Skip to content

其他设计模式

优先级划分依据

  • 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、模板方法模式

deign

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、中间加入命令对象,作为中转站

deign

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、中介者模式

deign

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、解释器模式

  • 使用场景不多

Released under the MIT License.