设计模式 | 青训营笔记

32 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天 maiami.jpg

一、单例模式

浏览器中常见的window对象,在整个浏览器渲染环境中,只保证只有一个实例,作为全局的共享对象

二、发布订阅者模式

订阅者向被订阅者注册回调函数,当被订阅者状态变更时,调用订阅者的回调函数,实现发布的效果

小案例: ① 订阅者调用订阅方法时传入订阅者对象: {被订阅者对象, 订阅者回调函数} => 即往被订阅者中的follower中Push入订阅者的对象; ② 当被订阅者状态变更时,执行所有的被订阅者follower中的订阅者注册的回调函数

type Notify = (user: User) => void

class User { name: string status: 'online' | 'offline' follower: {user: User, notify: Notify}[]

constructor (name: string) {
    this.name = name
    this.status = 'offline'
    this.follower = []
}

subscribe (user: User, notify: Notify) {
    user.follower.push({ user, notify })
}

online () {
    this.status = 'online'

    this.follower.forEach(({ notify }) => {
        notify(this)
    })
}

offline () {
    this.status = 'offline'

    this.follower.forEach(({ notify }) => {
        notify(this)
    })
}

`}

const lzx = new User('lzx') const xmd = new User('xmd') const cjt = new User('cjt')

lzx.subscribe(cjt, () => { console.log('LZX:') if (cjt.status == 'online') console.log('jt来了, 嘿嘿') if (cjt.status == 'offline') console.log('jt走了, 呜呜') }) xmd.subscribe(cjt, () => { console.log('XMD:') if (cjt.status == 'online') console.log('jt来了, 嘿嘿') if (cjt.status == 'offline') console.log('jt走了, 呜呜') })

cjt.online() console.log('-------') cjt.offline()`

三、原型模式

通过复制对象创造一个新的对象,在新对象上设置值

四、代理模式

能够在变成对象前后,进行一些其他的操作,实现一些解耦性的操作,上述案例使用如下代理:

const CreateProxyUser = (name: string) => { const user = new User(name)

const ProxyUser = new Proxy(user, {
    set: (target, prop: keyof User, value) => {
        target[prop] = value
        if (prop === 'status') {
            notifyStatusHandle(target, value)
        }
        return true
    }
})

const notifyStatusHandle = (user: User, status: String) => {
    if (status === 'online' || 'offline') {
        user.follower.forEach(({notify}) => {
            notify(user)
        })
    }
}

return ProxyUser

}

前面实现的方式,对状态的变更和消息的发布的业务耦合在一起,没有体现单一职责原则(一个方法只做一件事情),使用代理模式实现status变更时,再进行消息的发布调用,往后我们要做别的业务嵌入,也只需要在代理对象中加入我们的别的对象

五、迭代器模式

在类中,有一个内置属性[Symbol.iterator],其作为一个函数,返回值是一个包含next方法的对象,此操作可以给class加上迭代属性,从而在for…of循环中取值

每次调用next方法,都会返回当前成员的结构信息。具体来说就是包含了value和done两个属性的对象,其中value是当前成员的值,done表示遍历是否完成

`class MyItertor { name = 'LZX' pets = ['cat', 'dog', 'bird', 'fish'];

[Symbol.iterator]() {
    let node
    return {
        next: () => {
            while(node = this.pets.shift()) {
                return {value: node, done: false}
            }
            return {value: null, done: true}
        }
    }
}

}

const iterator = new MyItertor() for(let item of iterator) { console.log(${iterator.name} have a ${item}.) }`

六、前端框架中的设计模式

代理模式:

前端框架中对DOM操作的代理 DOM更新前后,onBeforeUpdate() + onAfterUpdate(),是用的代理模式 组合模式:

多个对象组合成为单个对象,也可单个对象单独使用 DOM结构,前端组件,文件目录