JavaScript学习笔记javascriptWeb前端之路

javascript设计原则-单一职责

2016-12-21  本文已影响143人  smartphp

前面把javascript的设计模式基本过了一遍,可以说是感慨很多,许多的思想都是从未接触过的,学起来难度也不小,但是我觉得这个过程是很值得的。如果以前是在足球场上踢野球的话,现在总算找到一个像模像样的教练在指导了,不一定会成为一个世界级的球星,但是水平至少也会比以前提高很多。
接下来会看看一些设计原则,设计原则是比模式更高一级的方法,是纲领性的内容。

单一职责(single responsable princple)被定为为“引起变化的原因”。如果一个方法承担了过多的职责,那么在需求发生变化的过程中,需要改写这个方法的可能性就越大。
因此SRP原则体现为:一个对象(方法)只做一件事情。
参考《javascript设计模式与开发实践》第18章

设计模式中的SRP原则

代理模式
下面这个例子是要在文档中创建一个img标签,并且要插入图片
在加载图片的时候,由于网速的限制需要预先加载一张本地图片,稍后会加载网络图片。 在这个过程中创建img标签更换图片源没有关系的。所以最好是把这两个过程分为两个对象来处理。

//创建img标签的对象
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( 'file:// /C:/Users/svenzeng/Desktop/loading.gif' );
                img.src = src;
            }
        }
    })();
    //更改图片的路径,这个过程就和img标签的创建对象没有关系了。
    proxyImage.setSrc( 'http:// imgcache.qq.com/music/photo/000GGDys0yA0Nk.jpg' );

迭代器模式
看下面段代码

//这段代码往文档中添加div元素,但是有限制,这里就只能添加数组
//有两个职责一个是添加元素,一个是遍历数据,所有有必要分开
 var appendDiv=function(){
  for(var i=0;l=data.length;i<l;i++){
   var div=document.createElement('div');
   div.innerHTML=data[i];
   document.body.appendChild(div);
  }
 };
 
 appenDiv([1,2,3,4,5,6])

使用单一职责原则改变代码

var each = function( obj, callback ) {//遍历的方法
//对象和数组都可以输入,灵活性加大,并且还可以修改
        var value,
        i = 0,
        length = obj.length,
        isArray = isArraylike( obj ); // isArraylike 函数未实现,可以翻阅jQuery 源代码
        if ( isArray ) { // 迭代类数组
            for ( ; i < length; i++ ) {
                callback.call( obj[ i ], i, obj[ i ] );
            }
        } else {
            for ( i in obj ) { // 迭代object 对象
                value = callback.call( obj[ i ], i, obj[ i ] );
            }
        }
        return obj;
    };
 //根据输入数据的元素添加方法
    var appendDiv = function( data ){
        each( data, function( i, n ){ //使用each方法来执行遍历
        //在回调函数中根据遍历数据添加元素至文档中
            var div = document.createElement( 'div' );
            div.innerHTML = n;
            document.body.appendChild( div );
        });
    };

    appendDiv( [ 1, 2, 3, 4, 5, 6 ] );//数组数据
    appendDiv({a:1,b:2,c:3,d:4} ); //对象数据

单例模式

在前面已经有笔记了。实际是把实际操作和创建单例的方法分别封装在两个方法里。

var createLoginLayer = (function(){//创建元素的方法
        var div;
        return function(){
            if ( !div ){
                div = document.createElement( 'div' );
                div.innerHTML = '我是登录浮窗';
                div.style.display = 'none';
                document.body.appendChild( div );
            }
            return div; //单例的判断依据
        }
    })();
  
        //创建和检测单例的方法,参数为创建元素的方法
    var getSingle = function( fn ){ // 获取单例
        var result;
        return function(){
            return result || ( result = fn .apply(this, arguments ) ); 
                        //这个地方要注意apply和arguments的应用
        }
    };
    var createLoginLayer = function(){ // 创建登录浮窗
        var div = document.createElement( 'div' );
        div.innerHTML = '我是登录浮窗';
        document.body.appendChild( div );
        return div;
    };
    
    var createSingleLoginLayer = getSingle( createLoginLayer );
    var loginLayer1 = createSingleLoginLayer();
    var loginLayer2 = createSingleLoginLayer();
    alert ( loginLayer1 === loginLayer2 ); // 输出: true  //为同一对象
    
    ```
    
装饰者模式
前面的设计模式里也有介绍
装饰者模式可以动态为对象添加方法或指责。从而也使的对象的功能单一化。
下面两个函数调用的时候指向同一个对象。

Function.prototype.after = function( afterfn ){
var __self = this;
return function(){
var ret = __self.apply( this, arguments );
//执行原函数
afterfn.apply( this, arguments );//执行after函数
return ret;
}
};
var showLogin = function(){
console.log( '打开登录浮层' );
};
var log = function(){
console.log( '上报标签为: ' + this.getAttribute( 'tag' ) );

};
document.getElementById( 'button' ).onclick = showLogin.after( log );

// 打开登录浮层之后上报数据

   
#####单一职责原则减低了单个类或者对象的复杂度,按照指责把对象分解成更小的粒度。有助于代码的复用,修改和测试。但是代码复杂度是提高了。怎么平衡呢?这是个问题。
上一篇下一篇

猜你喜欢

热点阅读