什么是设计模式
设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。
为什么要使用设计模式
为了代码可重用性、让代码更容易被他人理解、保证代码的可靠性和稳定性。
- 单例模式
- 观察者模式
1.单例模式
通过单例模式可以保证系统中,应用该模式的类只有一个实例。
常用的有
- 数据库连接
- 日志记录
- 工具类
- 提示框
- 全局缓存
例
// 创建一个单例模式类class Singleton { constructor() { if(!Singleton.instance) { this.name = null Singleton.instance = this } return Singleton.instance } setName(name) { this.name = name } toString() { console.log(`This is Singleton toString, the name is ${ this.name}.`) } static getInstance() { if (!this.instance) { return this.instance = new Singleton() } return this.instance }}let sing1 = Singleton.getInstance()let sing2 = Singleton.getInstance()let sing3 = new Singleton()let sing4 = new Singleton()// sing1 === sing2 true// sing2 === sing3 true// sing3 === sing4 true复制代码
// 微信相关apiwx.showToast({ title:"测试1"})wx.showToast({ title:"测试2"})复制代码
// table 组件class Table { /** * Table 构造器 * @param selector table 容器选择器 * @param options 属性配置 */ constructor(selector, options) { this.options = options this.selector = selector this.init() if(!Table.instance) { Table.instance = {} } return Table.instance[selector] = this } init() { console.log(`Table init selector is ${ this.selector}.`) } static getInstance(selector) { if (!this.instance) { this.instance = {} } if(!this.instance[selector]) { return this.instance[selector] = new Table(selector, options) } return this.instance[selector] }}复制代码
2. 观察者模式模式
被观察者本身状态改变是主动发出通知
常用的有
vue
实现原理- 微信小程序
setData
function defineReactive(data, key, val) { observe(val); // 递归遍历所有子属性 var dep = new Dep(); // 监听值set/get操作 Object.defineProperty(data, key, { enumerable: true, configurable: true, get: function() { if (Dep.target) { // 判断是否需要添加订阅者 dep.addSub(Dep.target); // 在这里添加一个订阅者 } return val; }, set: function(newVal) { if (val === newVal) { return; } val = newVal; console.log('属性' + key + '已经被监听了,现在值为:“' + newVal.toString() + '”'); dep.notify(); // 如果数据变化,通知所有订阅者 } });}Dep.target = null;function observe(data) { if (!data || typeof data !== 'object') { return; } Object.keys(data).forEach(function(key) { defineReactive(data, key, data[key]); });};Dep.target = null;function Dep () { this.subs = [];}Dep.prototype = { addSub: function(sub) { this.subs.push(sub); }, notify: function() { this.subs.forEach(function(sub) { sub.update(); }); }};function Watcher(vm, exp, cb) { this.cb = cb; this.vm = vm; this.exp = exp; this.value = this.get(); // 将自己添加到订阅器的操作} Watcher.prototype = { update: function() { this.run(); }, run: function() { var value = this.vm.data[this.exp]; var oldVal = this.value; if (value !== oldVal) { this.value = value; this.cb.call(this.vm, value, oldVal); } }, get: function() { Dep.target = this; // 缓存自己 var value = this.vm.data[this.exp] // 强制执行监听器里的get函数 Dep.target = null; // 释放自己 return value; }};function VueDemo (data, exp) { this.data = data; observe(data); console.log("init data:", this.data[exp]); // 初始化模板数据的值 new Watcher(this, exp, function (value) { console.log("from Watcher:", value) }); return this;}复制代码
// example let data = { name: 'hello world'};var vueDemo = new VueDemo(data, 'name');复制代码
THE END!