设计模式 | 青训营笔记

常见的设计模式

这是我参与「第四届青训营」笔记创作活动的的第6天!

一、单例模式

浏览器中常见的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结构,前端组件,文件目录
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值