zoukankan      html  css  js  c++  java
  • 设计模式1—发布订阅者模式【行为型】

    设计模式的目的是为了改善代码

    一、概念:

      1、发布订阅者模式(也叫观察者模式),是一对多的关系。举个例子:比如开学了。

         老师【发布者】 向 学生【订阅者】 发个开学通知,学生收到通知就会各自行动起来。这就是一个发布订阅者模式。

         说明:在老师那里有登记的学生才会收到通知。即有订阅的对象才会收到通知。

    二、讲解:

      1、没用设计模式时,我们的代码可能经常是这样的。

            //发布者
            let teacher = {
                start(){
                    console.log('开学了')
                    console.log('张三,来报道')
                    console.log('李四,来报道')
                    console.log('王五,来报道')
                }
            }
    
            teacher.start()

      说明:一个函数被调用, 函数里面的代码开始执行。如果函数里面的代码执行的是不同功能,代码逻辑比较混乱。需求改动时,这块代码就会很难维护。

      2、上面代码改进下,函数里面的代码,分不同的功能放在对应的函数里面。这样功能 模块 就 比较清晰了。

            let teacher = {
                start(){
                    console.log('开学了')
                    notice_zs() // 执行函数可以看做通知对象。函数里面的程序,就是 通知 收到后,各自 执行的 行为了。
                    notice_ls()
                    notice_ww()
                }
            }
            // 通知 张三
            function notice_zs(){
                console.log('张三,来报道吧')  // 张三收到通知,执行的任务。
            }
            function notice_ls(){
                console.log('张三,来报道吧')
            }
            function notice_ww(){
                console.log('张三,来报道吧')
            }
            teacher.start()

      说明:这里代码的逻辑是清晰了。问题是 start 函数和 订阅者函数紧紧写在一起。未来需求变动,需要往里面再增加 订阅者就不方便。需要在两个地方同时写代码。

         两者 代码分隔太远,关注点 太分离。不易 阅读 和 修改。

      3、再次改进下,类似 addEventListener 绑定 事件【注意:观察者模式不是事件的绑定】。不管在哪里绑定事件函数。只要事件触发了,绑定的函数都会触发。

            //发布者
            let teacher = {
                customerList:[],
                dengji(fn){
                    this.customerList.push(fn)
                },
                start(){
                    console.log('开学了')
                    this.customerList.forEach(fn => {
                        fn()
                    })
                }
            }
            teacher.dengji(notice_zs)
            function notice_zs(){
                console.log('张三,来报道')
            }
    
            teacher.dengji(notice_ls)
            function notice_ls(){
                console.log('李四,来报道')
            }
    
            teacher.dengji(notice_ww)
            function notice_ww(){
                console.log('王五,来报道')
            }
    
            // 需求变动,增加功能。直接订阅方法就可以了
            teacher.dengji(function (){
                console.log('插班生,来报道');
            })
            
            teacher.start()

      说明:1、现在,后面有新的功能增加,订阅下这个方法就可以。start执行时,就会把订阅的方法全部执行。如果需要,可以再写一个取消订阅的方法。

         2、这种模式 解决了 耦合的 问题。各订阅者 和 发布者的代码都没有 耦合关系。可以在 项目中任何地方,订阅者之间没有任何关系。

      4、程序再次改进下。每个订阅者,可以根据需求进行订阅,符合订阅者要求的,才会通知(执行函数)他。

              //发布者,这里以招生老师来做 例子
            let teacher = {
                customerList:{},
                dengji(fn, type){
                    if(!this.customerList[type]){
                        this.customerList[type] = []
                    }
                    this.customerList.push(fn)
                },
                start(type){
                    console.log(type + '开学了')
                    if(!this.customerList[type]){
                        return
                    }
                    this.customerList[type].forEach(fn => {
                        fn()
                    })
                }
            }
            teacher.dengji(notice_zs, 'web') // 登记 的学生,是web班的。web 班 开学,通 web 班对应的学生。其他的 班的学生不通知
            function notice_zs(){
                console.log('张三,来报道')
            }
    
            teacher.dengji(notice_ls, 'java')
            function notice_ls(){
                console.log('李四,来报道')
            }
    
            teacher.dengji(notice_ww)
            function notice_ww(){
                console.log('王五,来报道')
            }
    
            // 需求变动,增加功能。直接订阅方法就可以了
            teacher.dengji(function (){
                console.log('插班生,来报道');
            })
            
            teacher.start('web')  // web 班开学了

      5、程序要更复杂一点,发布者 还可以 通知 不同内容(传参)给 订阅者。这里就不写代码,理解上面的 逻辑。自然就知道怎么处理了。

      总结:发布者 不用 管 订阅者 都有谁,只要 start 开始,订阅者都会执行。

      参考:https://www.bilibili.com/video/BV1Ap4y1y7gS?from=search&seid=1911502725376732686

  • 相关阅读:
    受脑认知和神经科学启发的人工智能
    1分钟爱上管理学
    刻意练习
    课题设计相关
    销售必备心灵鸡汤(转)
    从优秀到卓越
    小记
    何谓成熟?
    三体运动的程序模拟
    行星运动轨迹的程序实现
  • 原文地址:https://www.cnblogs.com/wfblog/p/14347464.html
Copyright © 2011-2022 走看看