• 设计模式 | 青训营笔记


    常见的设计模式

    这是我参与「第四届青训营」笔记创作活动的的第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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    三、原型模式

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

    四、代理模式

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

    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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    前面实现的方式,对状态的变更和消息的发布的业务耦合在一起,没有体现单一职责原则(一个方法只做一件事情),使用代理模式实现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}.`)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

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

    代理模式:

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

    组合模式:

    • 多个对象组合成为单个对象,也可单个对象单独使用
    • DOM结构,前端组件,文件目录
  • 相关阅读:
    Java中的网络编程------基于Socket的TCP编程和基于UDP的网络编程,netstat指令
    Request之登录系统跳转应用以及原理详解【JavaWeb】
    【C++】继承 ⑪ ( 多继承 | 多继承语法 | 多继承案例 )
    pat考完了
    Vsftpd文件传输服务(三种认证模式:匿名开放 、本地用户、虚拟用户)
    Maven下载+配置+idea配置
    java项目之线上教学平台(springboot框架)
    云计算-Linux文件类型介绍,归属关系,基本权限介绍
    MatlabR2019b安装教程
    2022NISCTF--web
  • 原文地址:https://blog.csdn.net/weixin_46248051/article/details/126092735