设计模式(不常用的几类)

设计模式

1. 创建型

1. 原型模式

  1. 概念
    • clone 自己,生成一个对象
  2. 应用(Object.create)
    //基于原型创建一个对象
    var prototype = {
      getName: function() {
        return this.first + ' ' + this.last
      },
      say: function() {
        console.log('hello')
      }
    }
    
    //基于原型创建
    var x = Object.create(prototype)
    x.first = 'A'
    x.last = 'B'
    console.log(y.getName())
    y.say()
    
  • JS 中的原型 prototype
    • 可以理解为 ES6 class 的一种底层原理
    • 而 class 是实现面向对象的基础,并不是服务于某个模式
    • ES6 全面普及后,可能会忽略 prototype

2. 结构型

2.1 桥接模式

  1. 概念

    • 用于把抽象化与实现化解耦,是的二者可以独立变化
  2. 演示

    class ColorShape {
      yellowCircle() {
        console.log('yellow circle')
      }
      redCircle() {
        console.log('red circle')
      }
      yellowTriangle() {
        console.log('yellow triangle')
      }
      redTriangle() {
        console.log('red triangle')
      }
    }
    
    let cs = new ColorShape()
    cs.redCircle()
    cs.redTriangle()
    cs.yellowCircle()
    cs.yellowTriangle()
    
  3. 设计原则

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

2.2 组合模式

  1. 概念
    生成树形结构,“整体-部分关系”。让整体和部分都具有一致的操作方式

  2. 代码演示

    //虚拟DOM(vNode)
    <div id="div1" class="container">
      <p>123</p>
      <p>456</p>
    </div>
    
    {
      tag:'div',
      attr:{
        id:'div1',
        className:'container'
      },
      children:[
        {
          tag:'p',
          attr:{},
          children:['123']
        },{
          tag:'p',
          attr:{},
          children:['456']
        }
      ]
    }
    
  3. 设计原则

    • 将整体和单个节点的操作抽象出来,符合开放封闭原则

2.3 享元模式

  1. 概念

    • 共享内存(主要考虑内存,而非效率)
    • 相同的数据,共享使用
  2. 代码演示

    <div id="div1">
      <a href="#">a1<a/>
      <a href="#">a2<a/>
      <a href="#">a3<a/>
      <a href="#">a4<a/>
      <a href="#">a5<a/>
    </div>
    <script>
    var div1 = document.getElementById('div1')
    div1.addEventListener('click',function(e){
      var target = e.target
      if(target.nodeName === 'A'){
        alert(alert.innerHTML)
      }
    })
    </script>
    
  3. 设计原则

  • 将相同的部分抽象出来,符合开放封闭原则

3. 行为型

3.1 策略模式

  1. 概念
  • 不同策略分开处理,避免出现大量 if…else
  1. 代码验证

    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()
    var u3 = new User('vip')
    u3.buy()
    
    //改进
    class OrdinaryUser {
      buy() {
        console.log('普通用户购买')
      }
    }
    class MemberUser {
      buy() {
        console.log('会员用户购买')
      }
    }
    class VipUser {
      buy() {
        console.log('VIP 用户购买')
      }
    }
    //测试
    var u1 = new OrdinaryUser()
    u1.buy()
    var u2 = new MemberUser()
    u2.buy()
    var u3 = new VipUser()
    u3.buy()
    
  2. 设计原则

  • 不同策略分开处理,符合开放封闭原则

3.2 模板方法模式

  1. 概念

  2. 代码验证

    class Action {
      handle() {
        handle1()
        handle2()
        handle3()
      }
      handle1() {
        console.log('1')
      }
      handle21() {
        console.log('2')
      }
      handle3() {
        console.log('3')
      }
    }
    
  3. 设计原则

3.3 职责链模式

  1. 概念
  • 异步操作可能分为多个职责角色来完成
  • 吧这些角色都分开,然后用一个链串起来
  • 将发起者和各个处理者进行隔离
  1. JS 中的链式操作
  • jQuery 的链式操作
  • Promise.then 的链式操作
  1. 代码验证

    //请假审批,需要组长、经理、总监分布审批
    class Action {
      constructor(name) {
        this.name = name
        this.nextActoin = 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()
    
  2. 设计原则

  • 发起者于各个处理者进行隔离
  • 符合开放封闭原则

3.4 命令模式

  1. 概念
  • 执行命令时,发布者和执行者分开
  1. 代码验证

    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()
    
  2. JS 中的应用

  • 网页富文本编辑器操作,浏览器封装命令对象
  1. 设计原则
  • 命令者与执行对象分开,解耦
  • 符合开放封闭原则

3.5 备忘录模式

  1. 概念
  • 随时记录一个对象的状态变化
  • 随时可以恢复之间的某个状态(如撤销)
  1. 代码验证

    //状态备忘
    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())
    console.log(careTaker.get(1))
    
  2. 设计原则

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

3.6 中介者模式

  1. 概念
  • 多个对象能够通过一个对象进行访问
  1. 代码验证

    class Mediator {
      constructor(a, b) {
        this.a = a
        this.b = b
      }
      setA() {
        let number = this.b.number
        this.a.setNumber(number * 100)
      }
    
      setB() {
        let number = this.a.number
        this.b.setNumber(number / 100)
      }
    }
    
    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()
        }
      }
    }
    
    //测试
    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)
    
  2. 设计原则

  • 符合开放封闭原则

3.7 访问者模式

  1. 概念
  • 将数据操作和数据结构分离

3.8 解释器模式

  1. 概念
  • 描述语言语法如何定义,如何解释和编译

猜你喜欢

转载自blog.csdn.net/Cipuzp/article/details/83864319
今日推荐