常用设计模式

90 阅读2分钟

设计模式

定义

一种书写代码的方式,为了解决特定问题给出的简洁优化的解决方案

单例模式

  • 全局只有一个实例
  • 将构造函数赋值给instance,instance以闭包的形式保存在内存中
const singleTon = (function(){
    //可以是构造函数也可以是类
    function Person(name){
        this.name = name
        this.callback=cb
    }
    Person.prototype.sayHi = function(){
        console.log('hello world')
        this.callback()
    }
    let instance = null
    return function singleTon(name,cb){
        if(!instance) instance = new Person(name)
        // 处理函数
        instance.callback = cb||()=>{}
        return instance
    }
})()

观察者模式

  • 监控一个对象的状态,一旦状态发生变化,马上触发技能,
  • 需要两个构造函数来实现,一个是观察者,一个是被观察者
//观察者的构造函数
class Observer{
    constructor(name,fn=()=>{}){
        this.name = name
        this.fn = fn
    }
}

//创建两个观察者
const bzr = new Observer('班主任',(state)=>{console.log(`${state},我是班主任`)})
const bzr = new Observer('校长',(state)=>{console.log(`${state},我是校长`)})
//创建被观察者
1. 属性,自己的状态
2. 队列,记录都有谁观察者自己,数组[]
3. 方法,状态改变的时候可以触发技能
4. 方法,添加观察者
5. 方法,删除观察者
class Subject{
    constructor(state){
        // 记录自己的状态
        this.state = state
        // 数组用来保存观察者我的人
        this.observer = []
    }
    setState(val){
        this.state=val
        // 便利this,observers依次触发技能
        this.observers.forEach(item=>{
            // 告诉他我改变成了什么状态
            item.fn(this.state)
        })
    }
    addObserber(obs){
        const res = this.observers.find(item=>item===obs)
        if(!res){
            this.observer.push(obs)
        }
    }
    delObserver(obs){
        this.observers.filter(item=>item!==obs)
    }
}
const xiaoming  = new Subject('学习')
xiaoming.addObserver('班主任')
xiaoming.addObserver('校长')

发布订阅模式

  • 有一个对象,一直被监控
  • 当这个对象发生变化的时候,监控他的人,会通知所有与他关联的人
<!-- 去书店买书的例子
去书店,问,没有,留下一个联系方式给店员,
一旦有了书,就会接到电话
触发技能去买书
只需要一个构造函数
创建一个第三方店员的身份 -->
class Observer{
    consructor(){
        this.message = {}
    }
    on(type,fn){
        if(!this.message[type]){
            this.message[type] = []
        }
        this.message[type].push(fn)
    }
    off(type,fn){
        if(!fn){
            delete this.message[type]
            return
        }
        if(!this.message[type]){
            return
        }
        this.message[type]=this.message[type].forEach(item=>item!==fn)
    }
    triggger(type){
        if(!this.message[type]){
            return
        }
        this.message[type].forEach(item=>item())
    }
}
const person1 = new Observer()

策略模式

  • 一个问题匹配多个解决方案,不一定要用到哪个
  • 而且有可能还会继续增加多个方案
  • 例子: 购物车结算,我们有多种折扣计算方式
    • 满100减10
    • 满200减25
    • 8折
    • 7折
1. 把我们的多种方案,以闭包的形式保存起来
=> 对外留一个接口
=> 可以添加或减少
const calcPrice = (function(){
    const sale = {
        '100_10': function(price){return price-=10}
        '200_25': function(price){return price-=25}
        '80%': function(price){return price*=0.8}
    }
    function calcPrice(price,type){
        if(!sale[type]){
            return '没有这个折扣'
        }
        return sale[type](price)
    }
    calcPrice.add = function(type, fn){
        if(sale[type]){
            return '该折扣已经存在'
        }
        sale[type] = fn
    }
     calcPrice.del = function(type){
        delele sale[type]
    }
    return calcPrice
})()
const res = calcPrice(320,'100_10)
calcPrice.add('70%',function(price){return price*=0.7})