设计模式
- 概念:
- 原则是“找出 程序中变化的地方,并将变化封装起来”,它的关键是意图,而不是结构
- 优点:有利于代码的复用和维护
- 常用的设计模式:单例模式、工厂模式、订阅/发布模式(观察者模式)、代理模式、组合模式、构造函数模式
- 单例模式:使用该模式定义的类只有一个实例
- 工厂模式:常用的实例化对象的模式,这种模式代替了new操作符。(在函数体内创建对象,添加属性方法,返回对象)
- 订阅发布模式:定义了一种一对多的关系,让多个观察者同时监听某一个对象,这个对象的状态发生改变时就会通知所有的观察者对象。
- 思路: 发布者负责发布消息、 订阅者负责接收接收消息,而最重要的是主题对象,他需要记录所有的订阅这特消息的人,然后负责吧发布的消息通知给哪些订阅了消息的人。
- 发布者发出通知 =>主题对象收到通知并推送给订阅者 => 订阅者执行相应的操作。
- 经典案例:事件监听,多个同类型事件时监听一个元素,元素对象即为发布者,每一个事件处理函数即为订阅者
- 代理模式:可以理解为在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截。也就是说提供一个替身对象 来控制对这个对象的访问,客户实际上访问的是 替身对象。替身对象对请求做出一些处理之后, 再把请求转交给本体对象
代码:
单例模式
假设要设置一个管理员,多次调用也仅设置一次,我们可以使用闭包缓存一个内部变量来实现这个单例
function SetManager(name) {
this.manager = name;
}
SetManager.prototype.getName = function() {
console.log(this.manager);
};
var SingletonSetManager = (function() {
var manager = null;
return function(name) {
if (!manager) {
manager = new SetManager(name);
}
return manager;
}
})();
var obj1 = SingletonSetManager('a').getName(); // a
var obj2 = SingletonSetManager('b').getName(); // a
console.log(obj1 === obj2);
工厂模式
function Animal(opts){
var obj = new Object();
obj.color = opts.color;
obj.name= opts.name;
obj.getInfo = function(){
return '名称:'+ onj.name+', 颜色:'+ obj.color;
}
return obj;
}
var cat = Animal({name: '波斯猫', color: '白色'});
cat.getInfo();
订阅发布模式
代理模式
保护代理主要实现了访问主体的限制行为,以过滤字符作为简单的例子
// 主体,发送消息
function sendMsg(msg) {
console.log(msg);
}
// 代理,对消息进行过滤
function proxySendMsg(msg) {
// 无消息则直接返回
if (typeof msg === 'undefined') {
console.log('deny');
return;
}
// 有消息则进行过滤
msg = ('' + msg).replace(/泥\s*煤/g, '');
sendMsg(msg);
}
sendMsg('泥煤呀泥 煤呀'); // 泥煤呀泥 煤呀
proxySendMsg('泥煤呀泥 煤'); // 呀
proxySendMsg(); // deny
它的意图很明显,在访问主体之前进行控制,没有消息的时候直接在代理中返回了,拒绝访问主体,这数据保护代理的形式
有消息的时候对敏感字符进行了处理