JS设计模式探索
[[toc]]
单例模式
var singleton = { name: 'hzf', age: 24, walk: function(){ console.log(this.age); }, eat: function(){ } }
|
- 不足之处:
- (1)没有什么封装性,所有的属性方法都是暴露的。
- (2)全局变量很容易造成命名空间污染。
- (3)对象一开始变创建,万一我们用不上就浪费了。
var person = function(){ const privateVariable = '私有的外面获取不到'; function showPrivate(){ console.log(privateVariable); } return { publicMethod: function(){ showPrivate(); }, publicVar: '共有的外面能直接获取' } } const single = person();
single.publicMethod(); console.log(single.publicVar);
|
发布订阅模式+观察者模式
如下图所示:
观察者模式
观察者和被观察者一般是直接联系
的,相互知道对方的存在。
观察者一般是同步的,被观察者一旦有变化,观察者会立即发生反应
Subject
- 被观察者,发布者;
Observer
- 观察者,订阅者;
class Subject { constructor() { this. observers = []; } add(observer) { this.observers.push(observer); } remove(observer) { let idx = this.observers.findIndex(item => item === observer); idx > -1 && this.observers.splice(idx, 1); } notify(boss) { for(let o of this.observers) { o.update(boss); } } }
class Observer { constructor(name) { this.name = name; } update(boss) { console.log(`${boss}通知我职位了,我是:${this.name}`); } }
let subject = new Subject();
let obs1 = new Observer('高级前端开发工程师'); let obs2 = new Observer('初级后端开发工程师');
subject.add(obs1); subject.add(obs2);
subject.notify('HR'); subject.notify('CTO');
|
发布订阅模式
发布者和订阅者是解耦的,他们是通过一个介质
(往往是消息队列)执行代码
发布订阅模式由于是消息队列代理的存在,往往是异步的
代码实现
let pubSub = { list: {}, subscribe: function(key, fn) { if (!this.list[key]) this.list[key] = []; this.list[key].push(fn); }, unsubscribe: function(key, fn) { let fnList = this.list[key]; if (!fnList) return false; if (!fn) { fnList && (fnList.length = 0); } else { const curFn = fnList.filter((item, index) => { return item !== fn }); this.list[key]=curFn } }, publish: function(key, ...args) { for (let fn of this.list[key]) fn.call(this, ...args); } } let sub1 = function (time) { console.log(`上班了:${time}`); } let sub2 = function (time) { console.log(`下班了:${time}`); }
pubSub.subscribe('onwork',sub1 ) pubSub.subscribe('onwork', sub2 )
pubSub.publish('onwork', '18:00:00');
pubSub.unsubscribe('onwork');
|
DOM 的事件监听是”发布订阅模式”
const hzf = document.getElementById('#hzf');
function notifyClick() { console.log('我被点击了'); }
hzf.addEventListener('click', notifyClick);
loginBtn.removeEventListener('click', notifyClick);
|
两种模式的关联和区别
发布订阅模式更灵活,是进阶版的观察者模式,指定
对应分发。
观察者模式维护单一
事件对应多个依赖该事件的对象关系;
发布订阅维护多个
事件(主题)及依赖各事件(主题)的对象之间的关系;
观察者模式是目标对象直接触发通知(全部通知),观察对象被迫接收通知。
发布订阅模式多了个中间层(事件中心),由其去管理通知广播(只通知订阅对应事件的对象);
观察者模式对象间依赖关系较强,发布订阅模式中对象之间实现真正的解耦。
参考文档
观察者模式 vs 发布订阅模式
观察者模式与发布订阅模式
观察者模式
原型模式
未完待续…….