《JavaScript设计模式》读书笔记——Day2.1

接下来就是第三篇啦!!!更加的复杂了我感觉。。休息一下开始。

第三篇 结构型设计模式

//外观模式实现
    function addEvent( dom , type , fn ) {
        // 对于支持DOM2级事件处理程序addEvenListener方法的浏览器
        if ( dom.addEventListener) {
            dom.addEventListener( type , fn , false );
        } else if ( dom.attachEvent) {  // 对于支持attachEvent方法的浏览器
            dom.attachEvent('on' + type , fn);
        } else { // 对于这2种方法都不支持的浏览器
            dom [ 'on' + type ] = fn;
        }
    }
    var myInput = document.getElementById('myinput');
    addEvent( myInput , 'click' , function () {
        console.log ( '绑定我的第一个事件' );
    } );
    addEvent( myInput , 'click' , function () {
        console.log ( '绑定我的第二个事件' );
    } );

这样子这个函数就可以复用了,而且不会与后来其他的事件起冲突。

接下来是参数适配器:

/*
  * obj.name : name
  * obj.age : age
  * obj.title : title
  * obj.color : color
  * obj.size : size
  * obj.price : price
  */
  function doSomething( obj ) {
      var _adapter = {
          name   :   '罗浩浩',
          age    :    18,
          title  :   '设计模式',
          color  :   'red',
          size   :    100,
          price  :    30
      };
      for ( var i in _adapter) {
          _adapter[i] = obj[i] || _adapter[i];
      } 
  }

目的呢是调用的时候不知道参数传递的是否完整,所以用适配器来传入参数对象。

下面一个是数据适配,一般的数组我们会发现每个成员代表的意义不明确,我们就可以用下面这样的形式:

var obj = {
      name   :  '' ,
      type   :  '' ,
      title  :  '' ,
      time   :  ''
  };

  function arrToObjectAdapter( arr ) {
      return {
          name  :  arr[0],
          type  :  arr[1],
          title :  arr[2],
          data  :  arr[3]
      }
  }
  var arr = ['js','book','前端编程语言','8月1日'];
  var adapterData = arrToObjectAdapter( arr );
        console.log ( adapterData ); // name: "js" type: "book" title: "前端编程语言" time: "8月1日"

装饰者模式:

var decorator = function ( input , fn ) {
     // 获取事件源
     var input = document.getElementById(input);
     // 若事件源是已经绑定的事件
     if ( typeof input.onclick === 'function' ) {
         // 缓存事件原有的回调函数
         var oldClickFn = input.onclick;
         // 为事件源添加新的事件
         input.onclick = function () {
             // 事件源原有回调函数
             oldClickFn();
             // 执行事件源新增回调函数
             fn();
         }
     } else {
         // 事件源未绑定事件,直接为事件源添加新增回调函数
         input.onclick = fn;
     }
 };
 // 电话输入框功能装饰
 decorator( 'tel_input' , function () {
        document.getElementById( 'tel_demo_text' ).style.display = 'none' ;
 } )

着实是。。有点摸不着头脑,这里我要去问问啦~

下一个!我已经要死了。。桥接模式:

 var spans = document.getElementsByTagName('span');
    spans[0].onmouseover = function () {
        this.style.color = 'pink';
        this.style.bakcground = '#ccc';
    };
    spans[0].onmouseout = function () {
        this.style.color = '';
        this.style.bakcground = '';
    };

    spans[1].onmouseover = function () {
        this.getElementsByTagName('strong')[0].style.color = 'red';
        this.style.bakcground = '#pink';
    };
    spans[1].onmouseout = function () {
        this.getElementsByTagName('strong')[0].style.color = '';
        this.style.bakcground = '';
    };

html和css我局不写了。。偷个懒,主要是js。。。
这么写,好恶心啊,看着很不爽啊!那我么就用抽象化的思维,提取一下共同点。说白了,就是要有一个标签,然后要让他变色,那就再给他一个方法。那就是。。function(dom,color,bg)

 function changeColor ( dom , color , bg ) {
        dom.style.color = color;
        dom.style.background = bg;
    }
    var spans = document.getElementsByTagName('span');
    spans[0].onmouseover = function () {
        changeColor( this , 'pink' , '#ccc' )
    };

这一下就舒服多了嘛!!!

接下来是多元化对象!!!!疯了!!记不住那么多啊!

// 运动单元
    function Speed( x , y ) {
        this.x = x;
        this.y = y;
    }
    Speed.prototype.run = function () {
        console.log ( '动起来' );
    };
    // 着色单元
    function Color( cl ) {
        this.color = cl;
    }
    Color.prototype.draw = function () {
        console.log ( '绘制色彩' );
    };
    //说话单元
    function Speak( wd ) {
        this.word = wd;
    }
    Speak.prototype.say = function () {
        console.log ( '书写字体' );
    };

    // 创建一个球类,并且它可以运动,可以着色
    function Ball( x ,y, c ) {
        this.speed = new Speed ( x , y );
        this.color = new Color ( c );
    }
    Ball.prototype.init = function () {
        this.speed.run();
        this.color.draw();
    };

    // 创建一个人,它可以说话,可以运动
    function Human( x , y , f ) {
        this.speed = new Speed ( x , y );
        this.font = new Speak ( f );
    }
    Human.prototype.init = function () {
        this.speed.run();
        this.font.say();
    };

    var person = new Human ( 10 , 12 , 16 );  // 动起来
    person.init();  // 书写字体

这就是多元化对象。。其中当我们想做什么的时候,就实例化一个人物对象,这样他就有运动和说话的动作了。

桥接模式可以实现将元素的事件与业务逻辑之间解耦。也可以更加灵活的创建一个对象。他最大的特点就是将实现层(如元素绑定的事件)与抽象层(如修饰页面的UI逻辑)相分离,使得两边都可以有独立的变化。避免需求的改变而对对象内部的修改,体现了面向对象对括展的开放和对修改的关闭的原则。

受不鸟啦!!!明天再接着来!!

posted @ 2016-10-11 18:53  Hushaby丶  阅读(165)  评论(0编辑  收藏  举报