一单例模式

1,原生js单例模式:
1)概念

    // 1,独立的对象,建2个一个xiaowang,一个xiaoli
    // 2,xiaoli跟xiaowang通过门铃进行通信
    // 3,先看一下xiaowang家有没有门铃 如果有门直接通过门铃通信didi,如果没有先建门
    // 4,两单例之间开始通信
    var xiaowang = (function (argument) {
        var door;
        var xiaowangHome = function (message) {
            this.doorbell = message;
        }
        var info = {
            sendMessage: function (message) {
                if (!door) {
                    door = new xiaowangHome(message)
                }
                return door
            }
        }
        return info
    })()
    var xiaoli = {
        callXiaowang: function (meg) {
            var _xw = xiaowang.sendMessage(meg);
            alert(_xw.doorbell);
            _xw=null;//等待垃圾回收
        }
    }

2)一般应用

    xiaoli.callXiaowang('dididi')
    // // 页面6个按钮
    // document.getElementById('#a').onclick=function(){
    //     //很多逻辑
        // var a=9;//改变量没法被其他变量获取
    // }
    // document.getElementById('#b').onclick=function(){
    //     //很多逻辑
    // }
    // document.getElementById('#c').onclick=function(){
    //     //很多逻辑
    // }
    // document.getElementById('#d').onclick=function(){
    //     //很多逻辑
    // }
    // document.getElementById('#e').onclick=function(){
    //     //很多逻辑
    // }
    // document.getElementById('#f').onclick=function(){
    //     //很多逻辑
    // }
    // 利用单例模式将逻辑划分到两个实例中,甚至更多
    var top={
        init :function(){
            this.render();
            this.bind()
        },
        a:4,
        render:function(){
            var me = this;
            me.btna=document.querySelector("#a");
        },
        bind:function(){
            var me=this;
            me.btn.onClick=function(){
                me.test();
            }
        },
        test:function(){
            a=5
        }
    }
    var bannner={
        init :function(){
            this.render();
            this.bind()
        },
        a:4,
        render:function(){
            var me = this;
            me.btna=document.querySelector("#a");
        },
        bind:function(){
            var me=this;
            me.btn.onClick=function(){
                me.test();
            }
        },
        test:function(){
            a=5;
            top.a=6;
        }
    }
    top.init()
    bannner.init()

2,vue单例模式:

class SingleObject {
    login() {
        console.log('login...')
    }
}
SingleObject.getInstance = (function () {
    let instance
    return function () {
        if (!instance) {
            instance = new SingleObject();
        }
        return instance
    }
})()
测试
let obj1 = SingleObject.getInstance()
obj1.login()
let obj2 = SingleObject.getInstance()
obj2.login()
console.log(obj1 === obj2) // true

let obj3 = new SingleObject()
obj3.login()
console.log('obj1 === obj3', obj1 === obj3) // false
结论

就好比在一个对象的属性上,定义一个方法。

二,命令模式

<script>
    // 命令模式作用:
    // 1,将函数的封装,请求,调用结合为一体。
    // 2,调用具体的函数解耦命令对象与接收对象
    // 3,提高程序模块化的灵活性
    // 注意事项:
    // 1,不需要借口一致,直接调用函数忌口,以免造成浪费。    
    var company ={
        artillery:function(num){
            alert(num+'炮'+'开始战斗')
        },
        infantry:function(num){
            alert(num+'人'+'开始战斗')
        },
        commander:function(order){
            this[order.type](order.num)
        }
    }
    //指挥
    company.commander({type:'infantry',num:50})
    company.commander({type:'artillery',num:100})
</script>

三,观察者模式,发布订阅模式区别。

1)观察者模式

<!-- <script>
    // 1,多个观察者直接订阅发布者的消息。在目标发出内容改变的事件后,直接接收事件并作出响应。
    // 2,观察者必须先订阅消息,否则就会接受不到消息
   var pubsub=(()=>{//观察者和订阅者都写在一个对象里面
       var topics={};
       function subscribe(topic,fn){
        if(!topics[topic]){
            topics[topic]=[] ;
        }
        topics[topic].push(fn); 
       }
       function publish(topic,...args){
           if(!topics[topic]){
               return
           }
           for(let fn of topics[topic]){
               fn(...args)
           }
       }
       return {subscribe,publish}
   })()
    pubsub.subscribe('test',function(a,b){  //订阅者A订阅了test事件
        console.log(a,b);    
        clearTimeout(timer)
    });
    var timer = setTimeout(()=>{
        pubsub.publish('test','123','HH');//123  HH(发布者B发布了test事件)
    },2000)
</script> -->
<script>
    class Watcher{//观察者订阅事件
        constructor(topic,fn){
            this.topics={};
            if(!this.topics[topic]){
                this.topics[topic]=[] ;
            }
            this.topics[topic].push(fn); 
        }
        publish(topic,...args){
           if(!this.topics[topic]){//避免遍历事件使用
              return
           }
           for(let fn of this.topics[topic]){
               fn(...args)
           }
        }
        test(){
           console.log(1111) 
        }
    }
    var oberser = new Watcher('test',function(a,b){  //订阅者A订阅了test事件
        console.log(a,b);    
    });
    oberser.publish('test','123','HH');
</script>

2)发布订阅模式
订阅者A和发布者B没有直接关系的,二者是通过dep订阅器进行交流的。

<script>
    // 1,订阅者A和发布者B没有直接关系的,二者是通过dep订阅器进行交流的
    class Dep{//订阅器收集依赖关系
        constructor(){
            this.subs=[]
        }
        addSub(sub){//添加观察者
            this.subs.push(sub)
        }
        notify(){//通知观察者
            this.subs.forEach(sub=>sub.updated())
        }
    }
    class Watcher{
        updated(){
            console.log('收到订阅器发来的消息')
        }
    }
    let dep = new Dep();
    let ob = new Watcher();
    //目标添加观察者了
    dep.addSub(ob);
    //目标发布消息调用观察者的更新方法了
    dep.notify();   //update
</script>

欢迎参与分享
公众号


用户bPbuFxB
51 声望4 粉丝