美文网首页
其他设计模式

其他设计模式

作者: EmilWong | 来源:发表于2019-06-21 15:30 被阅读0次

    一、原型模式

    概念:clone自己,生成一个新对象;Java默认有clone接口,不用自己实现
    UML类图
    JS中的应用

    // `Object.create` 用到了原型模式的思想(虽然不是Java中的clone)
    // 基于一个原型创建一个对象
    var prototype = {
      getName: function () {
        return this.first + '  ' + this.last
      },
      say: function () {
        console.log('hello')
      }
    }
    // 基于原型创建X
    var x = Object.create(prototype)
    x.first = 'A'
    x.last = 'B'
    console.log(x.getName())
    x.say()
    

    二、桥接模式

    概念:用于把抽象画与实现化解耦,使得二者可以独立变化
    UML类图


    image.png

    实现:

    class Color {
      constructor(name) {
        this.name = name
      }
    }
    class Shape {
      constructor(name, color){
        this.name = name
        this.color = color
      }
      draw() {
        console.log(`${this.color.name} ${this.name}`)
      }
     }
    // 测试代码
    let red = new Color('red')
    let yellow = new Color('yellow')
    let circle = new Shape('circle', red)
    circle.draw()
    let triangle = new Shape('triangle', yellow)
    triangle.draw()
    

    设计原则验证

    • 抽象和实现分离,解耦
    • 符合开放封闭原则

    三、组合模式

    概念:生成树形结构,表示"整体-部分"关系
    JS应用:虚拟DOM中的VNode是这种形式,但数据类型简单

    四、享元模式

    • 共享内存(主要考虑没内存,而非效率)
    • 相同的数据,共享使用
    • (Js中未找到经典应用场景)

    五、策略模式

    概念:

    • 不同策略分开处理
    • 避免出现大量if...else 或者 switch case

    演示

    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 用户购买')
        }
      }
    }
    // 测试代码
    var u1 = new User('ordinary')
    u1.buy()
    var u2 = new User('member')
    u2.buy()
    
    // 策略模式改写
    class OrdinaryUser{
      buy () {
        console.log('普通用户购买')
      }
    }
    class MemberUser {
      buy() {
        console.log('会员用户购买')
      }
    }
    class VipUser{
      buy(){
        console.log('vip用户购买')
      }
    }
    var u1 = new OrdinaryUser()
    u1.buy()
    

    六、模板方法模式

    class Action {
    handle() {
    handle1()
    handle2()
    handle3()
    }
    handle1(){
    console.log('1')
    }
    handle2(){
    console.log('2')
    }
    handle3(){
    console.log('3')
    }
    }

    七、职责链模式

    概念:

    • 一步操作可能分为多个职责角色来完成
    • 把这些角色都分开,然后用一个链串起来

    代码演示:

    // 请假需要蹭蹭审批
    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()
    

    JS中的应用

    • 职责链模式和业务结合较多,JS中能联想到链式操作
    • jQuery的链式操作,Promise.then的链式操作

    八、命令模式

    概念:

    • 执行命令时,发布者和执行者分开

    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() 
    

    JS中的应用

    • 网页富文本编辑器操作,浏览器封装了一个命令对象
    • document.execCommand('bold')
    • document.execCommand('undo')

    九、备忘录模式

    概念:

    • 随时记录一个对象的状态变化
    • 随时可以恢复之前的某个状态(如撤销功能)
    • 未找到JS中经典应用,除了一些工具(如编辑器)

    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()) // 444
    editor.getContentFromMemento(careTaker.get(1))  // 撤销
    console.log(editor.getContent()) // 333
    

    设计原则验证

    • 状态对象与使用者分开,解耦
    • 符合开放封闭原则

    十、中介者模式

    概念:对象和对象之间的访问都通过一个中介者

    十一、访问者模式

    概念:

    • 将数据操作和数据结构进行分离,使用场景不多

    十二、解释器模式

    概念:

    • 描述语言语法如何定义,如何解释和编译
    • 用于专业场景

    十三、关于面试

    • 观察者模式
    • 单例模式

    相关文章

      网友评论

          本文标题:其他设计模式

          本文链接:https://www.haomeiwen.com/subject/sorrxctx.html