设计模式--结构型设计模式

结构型设计模式有外观模式,适配器模式,代理模式,装饰者模式,桥接模式,组合模式,享元模式。
外观模式
外观模式:为一组复杂的子系统接口提供一个更高级的统一接口,通过这个接口使得对子系统接口的访问更容易。
外观模式可以将浏览器不兼容的方法变得简单而又兼容各个浏览器,然而这只是外观模式应用的一部分,很多代码库中都是通过外观模式来封装多个功能,简化底层操作方法。

//简约版属性样式方法库
var A={
    //通过id获取元素
    g:function(id){
      return document.getElementById(id);
    },
    //设置元素css属性
    css:function(id,key,value){
        document.getElementById(id).style[key]=value;
    },
    //设置元素的属性
    attr:function(id,key,value){
        document.getElementById(id)[key]=value;
    }
}

通过这个代码库,我们操作元素的属性样式变得更简单
A.css(‘box’,’background’,’red’);

当一个复杂的系统提供一系列复杂的接口方法时,为系统的管理方便会造成接口方法的使用极其复杂。通过外观模式,对接口的二次封装隐藏其复杂性,并简化其使用时一种很不错的实践。
外观模式是对接口方法的外层包装,以供上层代码调用。因此有时外观模式封装的接口方法不需要接口的具体实现,只需要按照接口使用规则使用即可。这也是对系统与客户之间的一种松散耦合。是的系统与客户之间不会因结构的变化而相互影响。

适配器模式
适配器模式:将一个类(对象)的接口(方法或者属性)转化成另外一个接口,以满足用户需求,使类(对象)之间接口的不兼容问题通过适配器得以解决

function ajaxAdapter(){
 return [data.key1,data.key2,data.key3];
}
$.ajax({
    url:"xxx.php",
    success:function(data,status){
        if(data){
            doSomething(ajaxAdapter(data));
        }
    }
});

传统设计模式中,适配器模式往往是适配两个类接口不兼容的问题,然而在JavaScript中,适配器的应用范围更广,比如适配两个代码库,适配前后端数据等等。
JavaScript中的适配器的应用,更多应用在对象之间,为了使对象可用,通常我们会将对象拆分并重新包装,这样我们就要了解适配对象的内部结构,这也是与外观模式的区别所在,当然适配器模式同样解决了对象之间的耦合度,包装的适配器代码增加了一些资源开销,当然这是微乎其微的。

代理模式
代理模式:由于一个对象不能直接引用另一个对象,所以需要通过代理对象在这两个对象之间起到中介的作用。
var Count=(function(){
var img=new Image();
return function(param){
var str=’http://www.count.com/a.jpg‘;
for(var i in param){
str+=i+’=’+param[i];
}
img.src=str;
}
})();
Count({num:10});
代理模式可以解决系统之间的耦合度以及系统资源开销大的问题,通过代理对象可保护被代理对象,使被代理对象拓展不受外界的影响。也可以通过代理对象解决某一交互或者某一需求中造成的大量系统开销。
无论代理模式在处理系统,对象之间的耦合度问题还是在解决系统资源开销问题,他都将构建出一个复杂的代理对象,增加系统的复杂度,同时也增加了一定的系统开销,当然有时对于这种开销往往是可以接受的。

装饰者模式
装饰者模式:在不改变原对象的基础上,通过对其进行包装的拓展使其原有对象可以满足用户的更复杂需求。

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;
    }
}

在不了解原有功能的基础上对功能拓展模式,这是对原有功能的一种增强与拓展。当然同样对原有对象进行拓展的模式还有适配器模式,所不同的是适配器进行拓展很多时候是对对象内部结构的重组,因此了解其自身结构是必需的,而装饰者对对象的拓展是一种良性拓展,不用了解其具体实现,只是在外部进行了一次封装拓展,这又是对原有功能完整性的一种保护。

桥接模式
桥接模式:在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦。

//多维变量类
//运动单元
function Speed(x,y){
 this.x=x;this.y=y;
}
Speed.prototype.run=function(){
  console.log('运动起来');
}
//着色单元
functon Color(cl){
    this.color=cl;
}
Color.prototype.draw=function(){
    console.log('绘制色彩');
}
//变形单元
function Shape(sp){
  this.shape=sp;
}

于是我们想创建一个球类,并且它可以运动,可以着色。

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();
}

桥接模式最主要的特点即是将实现层与抽象层解耦分离,使两部分可以独立变化。由此可以看出桥接模式主要是对结构之间的结构。而前面学过的抽象工厂模式与创建者模式主要业务在于创建。通过桥接模式实现的解耦,使实现层与抽象层分开处理,避免需求的改变造成对象内部的修改,体现了面向对象对拓展的开发及对修改的关闭原则,这是很有用的。

组合模式
组合模式:部分-整体模式,将对象组合成树形结构以表示”部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

var Container=function(id,parent){
News.call(this);
this.id=id;
this.parent=parent;
this.init();
}
inheritPrototype(Container,News);
Container.prototype.init=function(){
 this.element=document.createElement('ul');\
 this.element.id=this.id;
 this.element.className="new"
};
Container.prototype.add=function(child){
    this.children.push(child);
    this.element.appendChild(child.getElement());
    return this;
}
Container.prototype.getElement=function(){
 return this.element;
}
Container.prototype.show=function(){
  this.parent.appendChild(this.element);
}

组合模式能够给我们提供一个清晰的组成结构。组合对象类通过继承同一个父类使其具有统一的方法,这样也方便了我们统一管理与使用,当然此时单体成员与组合体成员行为表现就比较一致了,这也就模糊了简单对象与组合对象的区别。有时这也是一种对数据的分级式处理。清晰而又方便我们对数据的管理与使用。
当然组合模式有时在实现需求上给我们带来更多的选择方式,虽然对于单体对象的实现简单而又单一,但是通过对其组合将会给我们带来更多的使用形式。

享元模式
享元模式:运用共享技术有效地支持大量的细粒度的对象,避免对象间拥有相同内容造成多余的开销

var Flyweight=function(){
    var created=[];
    function create(){
         var dom=document.createElement('div');
         document.getElementById('container').appendChild(dom);
         created.push(dom);
         return dom;
    }
    return {
         getDiv:function(){
            if(created.length<5){
                return create();
            }else{
              var div=created.shift();
              created.push(div);
              return div;
            }
        }
    }
}

享元模式的应用目的是为了提高程序的执行效率与系统的性能。因此在大型系统开发中应用是比较广泛的,百分之一的效率提成有时可以发生质的改变,它可以避免程序中的数据重复。有时系统内存在大量对象,会造成大量内存占用,所以应用享元模式来减少内存消耗是很有必要的。不过应用时一定要找准内部状态与外部状态,这样你才能更合理地提取分离。

所以结构型设计模式关注于如何将类或对象组合成更大,更复杂的结构,以简化设计。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值