结构型设计模式对比 设计模式(十六)

结构型设计模式
结构型模式关注于总体最终的结构,经过继承和组合,构建出更加复杂的结构
进而提供更增强大的逻辑功能
七种结构型模式
  • 适配器模式(Adapter Pattern)
  • 组合模式(Composite Pattern)
  • 装饰器模式(Decorator Pattern)
  • 代理模式(Proxy Pattern) 
  • 桥接模式(Bridge Pattern)
  • 外观模式(Facade Pattern)
  • 享元模式(Flyweight Pattern)
全部的结构型设计模式在逻辑上都各自不一样程度的隐含了“间接”“代理”“委托”的含义 ,有的明显,有的含蓄 
image_5c09c064_5021
 
强表现
适配器、装饰器、代理、组合、桥接模式,这几种模式比较强烈的表现了“间接”“代理”“委托”的含义 
从图中能够清楚地看得出来,他们都有“代理”的含义
适配器模式,经过继承或者组合方式,“代理”了,被适配角色Adaptee
装饰器模式,经过组合的方式,"是你还有你",内部拥有Component,代理了被装饰的具体构建 ConcreteComponent
代理模式,经过组合的方式,内部拥有RealSubject,代理了真实主题角色
组合模式,经过组合的方式,内部包含叶子节点或者树枝节点,内部“代理”了 子对象
桥接模式,经过组合的方式,内部拥有Implementor,指向实现者
 
若是装饰器模式只有一个被装饰的类ConcreteComponent,也只有一个装饰器角色ConcreteDecorator
省略掉Decorator ,他跟代理模式的结构能够说是同样的
省略掉装饰器模式结构图中的ConcreteDecorator角色,组合模式和装饰器模式的结构就彻底同样了
若是只有一种类型的ConcreteImplementor,桥接模式又与对象适配器模式相同
 
虽说他们都有“代理”的含义,可是他们又有很大差异
适配器模式下,“代理”的对象是功能相近的替代方案,好比,插座适配器能够进行插头转换
使得本来不兼容,不可以一块儿工做的那些类可以一块儿工做
代理模式下,“代理”的真实主题的对象RealSubject,从而 对真实对象进行隐藏,封装
透明的对外界提供服务,控制外界对这个对象的访问
装饰器模式下,“代理”的是抽象的Component构建,可以代理全部的ConcreteComponent类型
装饰器和被装饰的构建都是Component,重点在于功能的扩展,添加额外的职责
组合模式下,“代理”的是抽象构建Component,代理的是子对象,用于描述“总体-部分”的概念
桥接模式,“代理”的是实现角色Implementor,代理的是具体的实现,用于将抽象与实现进行分离
分离后经过桥接模式进行链接
他们虽然都是“代理”,可是他们的侧重点不一样,被代理的事物的性质不一样
适配器模式在代理的过程当中,重点在于适配,不会增长额外的功能
代理模式侧重于控制,固然也一般用于增长功能
若是代理模式,代理的不是真实主题对象RealSubject,而是抽象构建Subject,显然,就演化成了装饰器模式
由于代理模式不光可以控制外界对真实对象的访问,他也可以提供额外的服务
装饰器模式则是重点在于功能的扩展,增肌额外的职责
而组合模式,重点在于造成“总体--部分”的结构,而且对外界客户端程序,提供一致的访问形式
 
弱表现
享元模式和外观模式也是必定程度的代理
享元模式,经过内部状态与外部状态的分离,经过享元池中的享元对象,代理了全部的具备内外状态完整的对象
对客户端来讲就是有如此多的对象, 只不过内存中却仅有少许的对象
 
外观模式在结构上彻底看不出来“代理”的含义,可是他在业务逻辑上充当的也偏偏是“接口人”“协调者”“控制台”的角色
因此也能够认为是“代理”了内部的子系统
 
代理模式与适配器模式
代理模式和适配器模式都须要借助于内部的“被代理”对象,或者“被适配者”对象进行工做
也就是说他们都将本身的工做委托出去
 
可是代理模式中, 代理者与被代理者他们拥有相同的接口,也就是拥有相同的对外呈现,重点在于对真实对象的隐藏,客户端请求的透传,而且能够额外的增长一些控制,管理
适配器模式中,目标对象和被适配者在接口上没有必然联系,好比目标是港版插座面板,被适配者是大陆插座面板,他们的共同点是提供电力,可是接口却彻底不一样
适配器的重点在于不能一块儿工做的类可以一块儿工做
 
代理模式与装饰器模式
代理模式提供与被代理的真实对象相同的访问接口,对真实对象进行必定的控制,也能够增长额外的服务,职责
装饰器模式也是代理了内部真实的对象,而且拥有相同的访问接口
 
可是代理模式重点在于增长对真实对象的控制,隐藏真实对象,通常会在代理类内部建立一个真实的对象
也就是说这种 代理关系在编译时期已经静态肯定了
代理类接受处理来自客户端的请求,在内部转发到真实主题对象上
好比
//代理模式
public class Proxy implements Subject{
private Subject realSubject;
public Proxy(){
//关系在编译时肯定
realSubject = new RealSubject();
}
public void doSth(){
….
realSubject.doSth();
….
}
}
装饰器模式在于功能的动态增长,因此对象通常做为参数进行传递,好比:
      InputStream inputStream = new BufferedInputStream(new FileInputStream("........"));
这是一种在 运行期间动态增长功能方式
 
适配器与外观模式
适配器模式将一种接口转换为另一种接口,使得本来不能一块儿工做的类能够协做
外观模式是将子系统的的多个接口的访问转换为另外一种接口,使得本来复杂难用,耦合程度高的多个类有一个一致简单的接口
他们都变成了另一种形式的接口
全部的请求也都是委托他人进行处理,适配器模式委托给被适配角色,外观模式委托给子系统
 
适配器模式是为了可以一块儿工做,他们本来是并不兼容的
外观模式是为了可以更好地更简单的工做,他们本来是能够一块儿工做的
 
桥接模式与适配器模式
适配器模式的主要目的是让由于接口不兼容而不能互相工做的类可以一块儿工做
换句话说就是 他们自己不一样,我用“纽带” Adapter将他们链接起来

桥接模式则是将本来或许紧密结合在一块儿的抽象与实现,进行分离
使她们可以各自独立的发展,是把链接在一块儿的两个事物,拆分开来
而后用“纽带”“桥梁”(也就是对象的引用)将他们链接起来

适配器模式就比如 张三和王五不认识,李四介绍他们认识
桥梁模式比如张三和王五整天黏在一块儿活干得很差太乱套,李四说之后我做为接口人,你俩各干各的吧
虽然看起来都是两我的干活,中间一个联系人,可是含义倒是彻底不一样

桥接模式与装饰器模式
装饰器模式中,使用组合而不是继承来对类的功能进行扩展
避免了类的个数的爆炸增加, 与桥梁模式的结果不约而同
他们 都解决了类爆炸增加的问题,都避免了过多的不必的子类

装饰器模式侧重于功能的动态增长,将额外的功能提取到子类中
经过不一样的排列组合,造成一个递归的调用方式,以动态的增长各部分的功能

桥梁模式是将本来系统中的实现细节抽取出来,好比原来抽象概念与实例化所有都是一个类层次结构中
把全部的实现细节,好比示例中的平台相关实现,抽取出来,进行分离达到抽象与实现分离的目的

因此虽然他们均可以解决子类爆炸式增加、不易扩展的问题
可是他们的 出发点彻底不一样
一个关注于功能的动态扩展组合
一个关注于抽象与实现的分离,得到更多的灵活性
 
 
总结
全部的结构型模式的都离不开“分离,解耦”的概念
而“分离,解耦”以后,又经过某种形式创建联系,好比“组合”
抽象与实现进行分离,分离就意味着独立,独立就意味着能够单独发展,桥接模式
对于分离的事物经过委托的形式托付工做,就能够在中间提供更多的服务,代理模式
而分离的两个事物也能够经过必定形式的结合、转换进而一块儿协同工做,适配器模式
将一个对象的多个功能点进行分离,从而可以动态的组合以造成更强大的功能,装饰器模式
将事物自身内部核心状态与外部状态进行分离,进而减小核心状态的存储运行消耗,享元模式
将客户端与子系统的耦合交互进行分离,抽象出来一个新的接入点,外观Facade,下降耦合,外观模式
分离开的多种事物,若是他们有“总体--部分”的关系,能够将它们组合在一块儿,造成更复杂的总体结构,组合模式
(ps:上面的分离指分开的,不耦合在一块儿,不是特指本来是一个总体,被分红两部分)
 
以上各个部分的差别对比点主要根据设计模式的最初意图、动机,设计模式本就是设计原则的实现化角色
对于任何的结构,你均可以按照你本身的想法去使用、拓展,固然,前提是更合适或者更优秀
不然您那是瞎用
好比代理模式与装饰器模式本就很相似,若是你将代理模式的真实对象也是做为参数进行传递
也是用来动态的增长职责,那么就成了装饰器模式,因此再回头,你说你的是代理模式仍是装饰器模式?
这么看这个名字代理仍是装饰器又有什么大的区别的呢?都只是用来叙述而已
可是若是你这么作还非要说是代理模式,有一个很大的问题就是和同事、领导沟通起来就特别费劲了,说不定还会吵起来...
因此,除非你有更好更合适的选择,或者改变
不然,必定要尽可能按照模式本来的意图和动机去使用某种模式
 
相关文章
相关标签/搜索