写在前面
自己做项目的时候确实比较随心所欲:
1.很多应该封装为组件的部分不封装
2.很多频繁使用的功能不封装为工具类
3.很多常见的实体不封装为实体类
4.最好把增删改查和底部的数据库读取分成两个类
设计模式
单一职责原则(SRP)
一个对象或方法只做一件事情。减小粒度。
最少知识原则(LKP)
一个软件实体应当 尽可能少地与其他实体发生相互作用
开放-封闭原则(OCP)
软件实体(类、模块、函数)等应该是可以 扩展的,但是不可修改
1.单例模式
一个类只有一个实例,可以被全局访问,而且无法被重写。
重点在于构造函数立即执行,返回闭包函数,闭包函数返回实例。
function Son(name){
this.name=name;
}
Son.prototype.getName=function(){
console.log(this.name);
}
var Father=(function(){
//注意此处内容只在初始化时执行一次,此后继续调用Father不再执行
var instance=null;
console.log("test");
return function(...rest){
if(!instance){
instance=new Son(...rest);
}
return instance;
}
})()
Father("aaa").getName();
Father("bbb").getName();
2.适配器模式
解决两个已有接口之间不匹配的问题。
就像一个借口只接受数组参数,因此传参是要用适配器函数,将参数转为数组类型传入。
// 渲染数据,格式限制为数组了
function renderData(data) {
data.forEach(function(item) {
console.log(item);
});
}
// 对非数组的进行转换适配
function arrayAdapter(data) {
if (typeof data !== 'object') {
return [];
}
if (Object.prototype.toString.call(data) === '[object Array]') {
return data;
}
var temp = [];
for (var item in data) {
if (data.hasOwnProperty(item)) {
temp.push(data[item]);
}
}
return temp;
}
var data = {
0: 'A',
1: 'B',
2: 'C'
};
renderData(arrayAdapter(data)); // A B C
3.订阅-发布者模式(观察者模式)
也称作观察者模式,定义了对象间的一种一对多的依赖关系,当一个对象的状态发 生改变时,所有依赖于它的对象都将得到通知。
JS中的事件就是经典的发布-订阅模式的实现。
// 这个其实最好用立即执行的闭包来写,只返回包含函数的对象
function myEvent(){
var that = this;
that.cache = [];
that.on = function(event_name,fn){
that.cache[event_name] = that.cache[event_name] ? that.cache[event_name] : [];
that.cache[event_name].push(fn);
}
that.off = function(event_name,fn){
that.cache[event_name] = that.cache[event_name] ? that.cache[event_name] : [];
var index = that.cache[event_name].indexOf(fn);
console.log(index)
if(index >= 0){
that.cache[event_name].splice(index,1);
}
}
that.emit = function(event_name){
that.cache[event_name] = that.cache[event_name] ? that.cache[event_name] : [];
that.cache[event_name].forEach(function(fn){
fn();
});
}
}
var eve = new myEvent();
//console.log(eve)
function fn(){
console.log('click!')
}
eve.on('click',fn)
eve.emit('click')
eve.off('click',fn)
eve.emit('click')
4.代理模式
当客户不方便直接访问一个 对象或者不满足需要的时候,提供一个替身对象 来控制对这个对象的访问,客户实际上访问的是 替身对象。
实际应用:proxy。
5.工厂模式
工厂类只做实例化工作
let factory = function (role) {
if(this instanceof factory) {
var s = new this[role]();
return s;
} else {
return new factory(role);
}
}
factory.prototype = {
admin: function() {
this.name = '平台用户';
this.role = ['登录页', '主页']
},
common: function() {
this.name = '游客';
this.role = ['登录页']
},
test: function() {
this.name = '测试';
this.role = ['登录页', '主页', '测试页'];
this.test = '我还有一个测试属性哦'
}
}
let admin = new factory('admin');
let common = new factory('common');
let test = new factory('test');
6.享元模式
用共享技术支持大量的细粒度的对象
实际应用有:虚拟滚动,多子对象构造函数继承同一对象