Appearance
其他设计模式
优先级划分依据
- 1、不常用
- 2、对应不到经典的应用场景
1、原型模式
- clone 自己,生成一个新对象
- java 默认有 clone 接口,不用自己实现
js
// 一个原型 对象
const prototype = {
getName: function() {
return this.first + ' ' + this.last
},
say: function() {
alert('hello')
}
}
// 基于原型创建 X
let x = Object.create(prototype)
x.first = 'A'
x.last = 'B'
alert(x.getName())
x.say()
// 基于原型创建 Y
let y = Object.create(prototype)
y.first = 'C'
y.last = 'D'
alert(y.getName())
y.say()2、桥接模式
- 1、用于把抽象化与实现化解耦
- 2、使得二者可以独立变化
2.1 设计模式验证
- 1、抽象和实现分离,解耦
- 2、符合开放封闭原则
3、组合模式
- 1、生成树形结构,表示“整体-部分”关系
- 2、让整体和部分都具有一致的操作方式
4、享元模式
- 1、共享内存(主要考虑内存,而非效率)
- 2、相同的数据,共享使用
5、策略模式
- 1、不同策略分开处理
- 2、避免出现大量 if ... else 或者 switch ... case
js
// 原始代码
class User {
constructor(type) {
this.type = type
}
buy() {
if (this.type === 'ordinary') {
console.log('普通用户购买')
} else if (this.type === 'member') {
console.log('会员用户购买')
} else if (this.type === 'vip') {
console.log('vip 用户购买')
}
}
}
// 测试代码
let u1 = new User('ordinary')
u1.buy()
let u2 = new User('member')
u2.buy()
let u3 = new User('vip')
u3.buy()js
// 策略模式优化代码
class OrdinaryUser {
buy() {
console.log('普通用户购买')
}
}
class MemberUser {
buy() {
console.log('会员用户购买')
}
}
class VipUser {
buy() {
console.log('vip 用户购买')
}
}
// 测试代码
let u1 = new OrdinaryUser('ordinary')
u1.buy()
let u2 = new MemberUser('member')
u2.buy()
let u3 = new VipUser('vip')
u3.buy()5.1 设计原则验证
- 1、不同策略,分开处理,而不是混合在一起
- 2、符合开放封闭原则
6、模板方法模式

7、职责链模式
- 1、一步操作可能分为多个职责角色来完成
- 2、把这些角色分开,然后用一个链串起来
- 3、将发起者的各个处理者进行隔离
- 4、联想到 JS、jQuery、Promise.then 的链式操作
js
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()7.1、设计原则验证
- 1、发起者与各个处理者进行隔离
- 2、符合开放封闭原则
8、命令模式
- 1、执行命令时,发布者和执行者分开
- 2、中间加入命令对象,作为中转站

js
// 接受者
class Receiver {
exec() {
console.log('执行')
}
}
// 命令者
class Command {
constructor(receiver) {
this.receiver = receiver
}
cmd() {
console.log('执行命令')
this.receiver.exec()
}
}
// 触发者
class Invoker {
constructor(command) {
this.command = command
}
invoke() {
console.log('开始')
this.command.cmd()
}
}
// 士兵
let soldier = new Receiver()
// 小号手
let trumpeter = new Command(soldier)
// 将军
let general = new Invoker(trumpeter)
general.invoke()8.1 应用场景
- 1、网页富文本编辑器操作,浏览器封装了一个命令对象
- 2、document.execCommand('bold')
- 3、document.execCommand('undo')
8.2 设计原则验证
- 1、命令对象与执行对象分开,解耦
- 2、符合开放封闭原则
9、备忘录模式
- 1、随时记录一个对象的状态变化
- 2、随时可以恢复之前的某个状态(如撤销功能)
js
// 备忘类
class Memento {
constructor(content) {
this.content = content
}
getContent() {
return this.content
}
}
// 备忘列表
class CareTaker {
constructor() {
this.list = []
}
add(memento) {
this.list.push(memento)
}
get(index) {
return this.list[index]
}
}
// 编辑器
class Editor {
constructor() {
this.content = null
}
setContent(content) {
this.content = content
}
getContent() {
return this.content
}
saveContentToMemento() {
return new Memento(this.content)
}
getContentFromMemento(memento) {
this.content = memento.getContent()
}
}
// 测试代码
let editor = new Editor()
let careTaker = new CareTaker()
editor.setContent('111')
editor.setContent('222')
careTaker.add(editor.saveContentToMemento()) // 将当前内容备份
editor.setContent('333')
careTaker.add(editor.saveContentToMemento()) // 将当前内容备份
editor.setContent('444')
console.log(editor.getContent())
editor.getContentFromMemento(careTaker.get(1)) // 撤销
console.log(editor.getContent())
editor.getContentFromMemento(careTaker.get(0)) // 撤销
console.log(editor.getContent())10、中介者模式

js
class A {
constructor() {
this.number = 0
}
setNumber(num, m) {
this.number = num
if (m) {
m.setB()
}
}
}
class B {
constructor() {
this.number = 0
}
setNumber(num, m) {
this.number = num
if (m) {
m.setA()
}
}
}
// 中介者
class Mediator {
constructor(a, b) {
this.a = a
this.b = b
}
setB() {
let number = this.a.number
this.b.setNumber(number * 100)
}
setA() {
let number = this.b.number
this.a.setNumber(number / 100)
}
}
// 测试
let a = new A()
let b = new B()
let m = new Mediator(a, b)
a.setNumber(100, m)
console.log(a.number, b.number)
b.setNumber(100, m)
console.log(a.number, b.number)11、访问者模式
- 将数据操作和数据结构进行分离
- 使用场景不多
12、解释器模式
- 使用场景不多