js的设计模式

  起源:

 设计模式并非是软件开发中的专业术语。实际上‘模式’最早诞生于建筑学。20世纪30年代,哈佛大学建筑学博士和他的研究团队花了约20年的时间,

研究了为解决同一问题而设计出不同结构建筑,从中发现了那些高质量设计中的相似性,并且用‘模式’来指代相似性。

设计模式:在面向对象软件设计中针对特定问题的简洁而优雅的解决方案。

 单例模式:

  保证一个类只有一个实例,并提供一个访问它的全局访问点,如window对象。当我们单击登录按钮的时候,页面出现

一个登录浮窗,这个悬浮窗是唯一的,无论点击多少次登录按钮,这个浮窗都只会被创建一次,这个登录的浮窗就适合用单例模式创建。

  var CreateDiv=(function(){
                var instance;
                var CreateDiv=function(html){
                     console.log(instance)
                    if(instance){ //instance参数,如果没有则执行下面的,如果有则直接返回
                        return instance;
                    }
                    this.num=html;//this.num 为CreateDiv对象的一个属性   html为实例化的时候传进的参数
                    this.init();
                    console.log(this)
                    return instance = this;//返回CreateDiv对象
                }
                CreateDiv.prototype.init=function(){
                    var div=document.createElement('div');
                    div.innerHTML=this.num;//将num属性写在div里面
                    document.body.appendChild(div);
                }
                return CreateDiv;
            })();
            var a = new CreateDiv('a');
            var b = new CreateDiv('b');//因为只会被创建一次,所以实例化b的时候a已经实例化过了,所以CreateDiv对象是没有变化的
            a==b;//true
            a===b;//true

 

代理模式定义

    为一个对象提供一个代用品或占用符,以便控制对它的访问。很多明星都有自己的经纪人,比如开演唱会经纪人会代替明星细节和谈好薪酬之后

再跟明星签合同。即核心是当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象控制了这个对象的,替身对象对请求最初一些

处理之后再把请求转交给本体请求。

  var myImage=(function(){
                var imgNode=document.createElement('img');
                document.body.appendChild(imgNode);
                return {
                    setSrc:function(src){
                        imgNode.src=src;
                    }
                }
            })();
            var proxyImage=(function(){
                var img=new Image();
                img.onload=function(){
                    myImage.setSrc(this.src)//传入的图片路径
                };
                return{
                    setSrc:function(src){
                        myImage.setSrc('load.gif');
                        img.src=src;//把传入的图片路径传给真正的对象,显示在页面上
                    }
                }
            })()
            proxyImage.setSrc();

 

命令模式

  命令模式中的命令指的是一个执行某些特定事情的指令,有时候需要向某些特定事情的指令。常见的应用场景有时候需要向某些对象发送请求,

但是并不知道请求的接受者是谁,也不知道被请求的操作是什么。假如我们去快餐店,我们可以点餐取消餐,但是我们并不用关心厨师是谁,怎么做。

    var makeCommand=function(receiver,state){
                return function(argument){
                    receiver[state]();//调用方法
                }
            }
            var Ryn={  //对象上面的三个属性
                attack:function(){
                    console.log('攻击')
                },
                defense:function(){
                    console.log('防御');
                },
                crouch:function(){
                    console.log('蹲下');
                }
            }
            var command=makeCommand(Ryn,'attack');
            command();//攻击

 

发布订阅模式

  发布订阅模式又称观察者模式,它定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都将得到通知。现实生活中,

如我们去售楼中心,服务人员A接待了我们,然后再有客户找到A,这个时候暂时没房了,等到有房的时候不可能服务人员A挨个打电话通知,而是订阅A的

公共服务提醒。

      (function($){
                var o = $({});
                $.subscribe=function(){
                    o.on.apply(o,arguments);
                }
                $.unsubscribe=function(){
                    o.off.apply(o,arguments);
                }
                $.publish=function(){
                    o.trigger.apply(o,arguments);
                }
            })(jQuery)

 

 职责链模式

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这些关系连成一条链,并沿着这条链传递该请求,直到一个对象处理它为止。

现实生活中,如我们坐公交车人太多,我们把公交卡交给售票员,让前面的人不停的往前递,直到售票员刷卡结束。

    var fn1=function(data){
                if(data==1){
                    console.log('fn1->'+data);
                }else{
                    return 'next';
                }
            }
            var fn2=function(data){
                    console.log('fn2->'+data);
                    return 'next';
            }
            var fn3=function(data){
                    console.log('fn3->'+data);
                    console.log('done');
            }
            Function.prototype.after=function(fn){
                var self=this;
                return function(){
                    var ret=self.apply(this,arguments);// 当前函数本身
                    if(ret=='next'){
                        return fn.apply(this,arguments); //fn下一个要直执行的函数
                    }
                    return ret;
                }
            }
            var order=fn1.after(fn2).after(fn3);
            order(3);

 

posted @ 2017-12-03 23:03  伊优  阅读(1889)  评论(1编辑  收藏  举报