2022-05-23 设计模式

设计模式 5 大原则

1,单一职责原则
一个类只封装一定的功能
过于复杂的代码块想办法拆分成单独的方法

2,开闭原则
对修改关闭,对扩展开放
增加或者变更需求时,不应该修改核心代码,应该再之前的基础上新增功能

3,里氏替换原则
父类能用的地方,子类都能用,即可以用任何子类替换父类

4,接口隔离原则
接口之间功能不要重复
接口更纯粹干净

5,依赖倒置原则
使用方应该依赖抽象,比如接口,抽象类,配置等,而不是其实现,因为实现会频繁变更

设计模式分类

1,创建型

1,单例模式
一个类只有一个全局实例,并提供一个获取它的全局入口。

class LoginForm {
  constructor() {
  }
}
//用闭包存一个永久的单例
LoginForm.getInstance = (function () {
  let instance = null
  return = function () {
    if (!instence) {
      instance = new LoginForm()
    }
    return instance
  }
})()

2,工厂模式
如果不想让某个子系统与较大的哪个对象之间形成强耦合。而是想在运行时可以从许多系统进行挑选或者切换的话。工厂模式可以进行解耦。

class product1 {
  run () { }
}

class product2 {
  run () { }
}

class Fatory {
}

Fatory.create(productName) {
  if (productName === '1') {
    return new product1()
  }
  else {
    return new product2()
  }
}

let p = Fatory.create('1')
p.run()

2,结构型

1,适配器模式
适配器用于解决两个接口不兼容的情况,通过适配器可以在不改变原有接口源码的情况下,让两个不兼容的接口通信

//客户端接收一个对象,必须有run方法
class client {
  constructor(app) {
    this.app = app
  }

  run () {
    this.app.run()
  }
}

//appForien没有run方法,无法与client兼容
class appForien {
  constructor(name) {
    this.name
  }
  business () {
    return this.name
  }
}

//创建Forien适配器
class forienAdapter {
  constructor(app) {
    this.app = app
  }

  run () {
    const result = this.app.business()
    return result
  }
}

//使用
const app = new appForien()
const fa=new forienAdapter(app)
const c = new client(fa)
c.run()

应用场景:vue中的computed就是适配器,将原先各种数据组装成客户端能用的新数据

2,装饰器模式
动态的给对象或者函数添加某些功能

class cellPhone {
  create () {
  }
}

class Decorator {
  constructor(cellPhone, funcBefore, funcAfter) {
    this.cellPhone = cellPhone
  }

  create () {
    funcBefore()
    this.cellPhone.create()
    funcAfter()
  }
}

//使用
const d = new Decorator(new cellPhone(), () => {
  //前置功能
}
  , () => {
    //后置功能
  })
d.create()

3,代理模式
客户端不直接与接口进行通信,而是加一个代理层进行通讯

class client {
  constructor() {
    this.msg = ''
  }
  getMsg () {
    return this.msg
  }

  setMsg (msg) {
    this.msg = msg
  }
}

class msgProxy {
  constructor(client, encodeMsg) {
    this.client = client
    this.encodeMsg = encodeMsg
  }
  getMsg () {
    return this.encodeMsg(this.client.getMsg())
  }

  setMsg (msg) {
    const msgStr = this.encodeMsg(msg)
    this.client.setMsg(msgStr)
  }
}

//使用
const c = new client()
const p = new msgProxy(c, (str) => {
  return str + '111'
})
p.setMsg('aaa')
console.log(p.getMsg())

4,组合模式

3,行为型

1,观察者模式
定义了一种一对多的模式。有多个观察者监听一个主题,只要主题发送通知,所有观察者都会进行响应。
这其中的关键是主题要收集到所有的观察者。然后有一个通知方法,循环遍历通知每一个观察者。对于观察者而言,他们有一个依赖的
主题,并且有一个同名的响应方法。

//一个主题,用于收集依赖,发布通知
class Subject {
  constructor() {
    this.state = 0
    this.observers = []
  }

  getState () {
    return this.state
  }

  setState (state) {
    this.state = state
    this.notifyAllObservers()
  }

  notifyAllObservers () {
    this.observers.forEach(ob => {
      ob.update()
    })
  }

  attach (observer) {
    this.observers.push(observer)
  }
}

//观察者,用于跟踪主题,响应通知
class Observer{
  constructor(name,subject){
    this.name = name
    this.subject = subject
    this.subject.attach(this)
  }

  update(){
    //do something
  }
}

2,迭代器模式
提供一种方法顺序执行一个聚合对象中各个元素,而又不暴露该对象得内部表示

class Iterator {
  constructor(container) {
    this.list = container.list
    this.index = 0
  }

  next () {
    if (this.hasNext()) {
      //do something
      return this.list[this.index++]
    }
    return null
  }

  hasNext () {
    return this.index >= this.list.length
  }
}

class Container{
  constructor(list){
    this.list = list
  }

  getIterator(){
    return new Iterator(this)
  }
}

//使用
const con = new container([1,2,3,4,5])
let iterator = con.getIterator()

while(iterator.hasNext()){
  iterator.next()
}

3,策略模式
将不同的可能用到的方法封装在一起,并且他们可以互相替换

//应用场景:表单验证
//策略对象
class strategies {
  static isRequire (value, errorMsg) {
    if (!value) {
      console.log(errorMsg)
    }
  }

  static minLength (value, errorMsg, length) {
    if (value.length < length) {
      console.log(errorMsg)
    }
  }
}

//验证类
class Validator {
  constructor(form) {
    this.form = form
  }
  valid (rules) {
    rules.forEach(rule => {
      rule.stratege(form[rule.name], rule.errorMsg,rule.args)
    });
  }
}

//使用,配置策略
const rules = [
  { name: id, stratege: strategies.isRequire, errorMsg: '必填' },
  { name: address, stratege: strategies.minLength, errorMsg: '过长', args: 10 },
]

const formValidator = new Validator({
  id:'123',
  address:'tom jack no 100'
}).valid(rules)

4,模板方法模式
将一个过程或者一个流程算法的公共部分提取出来,可变部分的逻辑给子类去实现和变动,整个大步骤不变

class flow{
  constructor(step1,step2){
    this.step1=step1
    this.step2=step2
  }

  run(){
    this.start()
    this.step1()
    this.step2()
    this.end()
  }

  start(){
    console.log('start')
  }

  end(){
    console.log('end')
  }
}

5,命令模式
将执行逻辑和执行对象之间解耦,使得执行逻辑可以更容易扩展

//接收器
class Receiver {
  run () {
    console.log('run start')
  }
}

//命令类型
class Command {
  constructor(Receiver) {
    this.Receiver = Receiver
  }

  execute () {
    this.Receiver.run()
  }
}

//命令触发器
class Invoker {
  constructor(Command) {
    this.Command = Command
  }

  invoke () {
    this.Command.execute()
  }
}

//使用,客户下订单发货
const base = new Receiver() //仓库
const order = new Command(base) //订单
const client = new Invoker(order) //客户
//客户下订单
client.invoke()


6,中介模式
将多个对象的直接交互,变成由一个中介对象来间接交互,可以将交互对象之间解耦

class A {
  constructor() {
    this.val = ''
  }
  setB (m, val) {
    m.setB(val)
  }
}

class B {
  constructor() {
    this.val = ''
  }
  setA (m, val) {
    m.setA(val)
  }
}

//中介者
class Mediator {
  constructor(a, b) {
    this.a = a
    this.b = b
  }
  setA (val) {
    A.val = val
  }
  setB (val) {
    A.val = val
  }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容