这是我参与「第四届青训营」笔记创作活动的的第8天
设计模式的概念
设计模式就是前辈们代码设计的一个总结,也就是写代码的最佳实践,让代码有更好的可复用性、可读性、可维护性,设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。目前为止共有23种设计模式,但是有些设计模式不太常用。
7大设计原则
1.单一职责原则 SRP
我们设计的类尽量负责一项功能,如A类只负责功能A,B类只负责功能B,不要让A类既负责功能A,又负责功能B,这样会导致代码混乱,容易产生bug。
2.开放-封闭原则 OCP
是编程汇总最基础,最重要的设计原则,核心为对扩展开发,对修改关闭,简单来说,通过扩展软件的行为来实现变化,而不是通过修改来实现,尽量不修改代码,而是扩展代码。
3.里氏替换原则 LSP
程序中的子类应该可以替换父类出现的任何地方并保持预期不变。所以子类尽量不要改变父类方法的预期行为。
4.接口隔离原则 ISP
类不应该依赖他不需要的接口,接口尽量小颗粒划分。当类 A 只需要接口 B 中的部分方法时,因为实现接口需要实现其所有的方法,于是就造成了类 A 多出了部分不需要的代码。这时应该将 B 接口拆分,将类A需要和不需要的方法隔离开来。
5.依赖倒置原则 DIP
抽象不应该依赖细节,细节应该依赖于抽象。核心是面向接口编程,我们应该依赖于抽象接口,而不是具体的接口实现类或具体的对象。相对于细节的多变性,抽象的东西要稳定的多,以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。
6.最少知识原则(迪米特原则)LOD
一个类或对象应该对其它对象保持最少的了解。只与直接的朋友(耦合)通信。
7.组合/聚合复用原则 CRP
尽可能通过组合已有对象(借用他们的能力)来实现新的功能,而不是使用继承来获取这些能力。就是能用组合实现少用继承。
前端常用设计模式之一--发布订阅模式
在很多的库里都能见到这个设计模式的应用,在nodejs里对事件的监听基本都是用EventEmitter实现的,在这里实现一个简单的EventEmitter。
代码如下:
class EventEmitter {
constructor() {
this._events = {}
}
on(eventName, callback) {
if (!this._events) {
this._events = {}
}
if (this._events[eventName]) {
this._events[eventName].push(callback)
} else {
this._events[eventName] = [callback]
}
}
emit(eventName, ...args) {
this._events[eventName].forEach((fn) => {
fn(...args)
})
}
off(eventName, callback) {
if (this._events && this._events[eventName]) {
this._events[eventName] = this._events[eventName].filter(
(fn) => fn !== callback && fn.a !== callback
)
}
}
once(eventName, callback) {
const one = () => {
callback()
this.off(eventName, one)
}
one.a = callback
this.on(eventName, one)
}
}
复制代码
测试代码如下:
class Child extends EventEmitter {
constructor() {
super()
}
}
const child = new Child()
const happy = () => {
console.log('i love you')
}
const unhappy = () => {
console.log('你个老六')
}
child.on('给你糖', happy)
child.on('把你糖抢回来', unhappy)
const fn = () => {
console.log('逛街')
}
child.once('干什么', fn)
child.emit('给你糖')
console.log('________________________________')
child.emit('把你糖抢回来')
console.log('________________________________')
setTimeout(() => {
child.off('干什么', fn)
child.emit('干什么')
}, 1000)
复制代码
测试结果如下图: