首先了解设计模式的六大原则
Single Responsibility Principle 单一责任原则
确保职责功能的单一性
The Open Closed Principle 开放封闭原则
原有的功能不能被修改,在原有基础上了扩展的新的功能
The Liskov Substitution Principle 里氏替换原则
本质是多态和继承的应用
The Dependency Inversion Principle 依赖倒置原则
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象
The Interface Segregation Principle 接口分离原则
客户端不应该被强迫地依赖那些根本用不上的方法。
The Demietor Principle迪米特原则
一个对象应该对其他对象保持最少的了解
观察者模式:
应用:Promise、网页事件addEventListener、node自定义事件、vue数据绑定watch、vue和react生命周期的触发
和发布订阅不同,发布订阅是一个系统,观察者是两个系统的关联
// 主题
class Subject {
constructor(name) {
this.name = name;
this.observer = [];
this.state = "state init";
}
attatch = function (o) {
this.observer.push(o)
}
setState = function (n) {
this.state = n;
console.log(this.observer)
this.observer.forEach(item => item.update(this.state))
}
}
// 观察器
class Observer {
constructor(name, subject) {
this.name = name;
this.subject = subject;
this.subject.attatch(this);
}
update(value) {
console.log(this.name, "watch" , value)
}
}
let s = new Subject()
let o1 = new Observer('o1', s)
let o2 = new Observer('o2', s)
let o3 = new Observer('o3', s)
s.setState("324423")
单例模式
整个系统只存在一个实例应用,如登录权限,任务管理器,
// 使用自身的方法
class SingleMode {
state = 1;
constructor() {}
static getInstance() {
if(!SingleMode.instance__){
SingleMode.instance__ = new SingleMode()
}
return SingleMode.instance__;
}
}
// 闭包
const singleMode = (function() {
var state = 1;
var instance;
function getInstance() {
if(!instance){
instance = this
}
return instance;
}
getInstance.prototype = {}
return getInstance;
})()
// 单例代理
function Target() { this.state = 1 }
function ProxySingleModel () {
var instance;
return function () {
if(!instance) instance = new Target();
return instance;
}
}
console.log(new ProxSingleModle())
策略模式
本质在于方法作为参数传入,不同的策略解决问题,解决if、switch等条件语句的繁杂
// 分期付款
const payTypes = {
halfYear: function(totalMoney) {
const MonthRate = 0.33;
return {
onePay: total/ 6,
payTimes: 6,
rate: MonthRate * 6,
}
},
treeMonth: function(totalMoney) {
const MonthRate = 0.23;
return {
onePay: total/ 3,
payTimes: 3,
rate: MonthRate * 3,
}
},
}
class PayByStages {
constructor(totalMoney, stageType) {
this.totalMoney = totalMoney;
this.stateType = stageType;
}
getStageResult = function() {
return payType[stageType](totalMoney);
}
}
new PayByStages(123232, "halfYear")
中介模式
通过一个中介者对象,其他所有的相关对象都通过该中介者对象来通信,而不是相互引用,当其中的一个对象发生改变时,只需要通知中介者对象即可。通过中介者模式可以解除对象与对象之间的紧耦合关系。
var goods = { //手机库存
'red|32G': 3,
'red|64G': 1,
'blue|32G': 7,
'blue|32G': 6,
};
//中介者
var mediator = (function() {
var colorSelect = document.getElementById('colorSelect');
var memorySelect = document.getElementById('memorySelect');
var numSelect = document.getElementById('numSelect');
return {
changed: function(obj) {
switch(obj){
case colorSelect:
//TODO
break;
case memorySelect:
//TODO
break;
case numSelect:
//TODO
break;
}
}
}
})();
colorSelect.onchange = function() {
mediator.changed(this);
};
memorySelect.onchange = function() {
mediator.changed(this);
};
numSelect.onchange = function() {
mediator.changed(this);
};
装饰器模式
不改变原有对象的基础上,在运行期间给其添加方法属性
例如rc-form的实现rc-form-simple
工厂模式
应用于如JQ window.$挂载、vue异步组件的注册
class Product1{}
class Product2{}
class Factory {
createP1() { return new Product1() }
createP2() { return new Product2() }
}
let factory = new Factory();
let p1 = Factory.createP1();
let p2 = Factory.createP2();
适配器模式
将一个接口转化为另一个接口
class Plug {
getName() {
return 'iphone充电头';
}
}
class Target {
constructor() {
this.plug = new Plug();
}
getName() {
return this.plug.getName() + ' 适配器Type-c充电头';
}
}
let target = new Target();
target.getName(); // iphone充电头 适配器转Type-c充电头
代理模式
假设当A 在心情好的时候收到花,小明表白成功的几率有
60%,而当A 在心情差的时候收到花,小明表白的成功率无限趋近于0。
小明跟A 刚刚认识两天,还无法辨别A 什么时候心情好。如果不合时宜地把花送给A,花
被直接扔掉的可能性很大,这束花可是小明吃了7 天泡面换来的。
但是A 的朋友B 却很了解A,所以小明只管把花交给B,B 会监听A 的心情变化,然后选
择A 心情好的时候把花转交给A,代码如下:
let Flower = function() {}
let xiaoming = {
sendFlower: function(target) {
let flower = new Flower()
target.receiveFlower(flower)
}
}
let B = {
receiveFlower: function(flower) {
A.listenGoodMood(function() {
A.receiveFlower(flower)
})
}
}
let A = {
receiveFlower: function(flower) {
console.log('收到花'+ flower)
},
listenGoodMood: function(fn) {
setTimeout(function() {
fn()
}, 1000)
}
}
xiaoming.sendFlower(B)
职责链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止
// 请假审批,需要组长审批、经理审批、总监审批
class Action {
constructor(name) {
this.name = name
this.nextAction = null
}
setNextAction(action) {
this.nextAction = action
}
handle() {
console.log( `${this.name} 审批`)
if (this.nextAction != null) {
this.nextAction.handle()
}
}
}
let a1 = new Action("组长")
let a2 = new Action("经理")
let a3 = new Action("总监")
a1.setNextAction(a2)
a2.setNextAction(a3)
a1.handle()