结构型模式
1) 适配器模式 Adapter
定义:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一 起工作的那些类可以一起工作。
绘图:
场景/应用:
附注:
在《设计模式》中,对适配器模式讲了两种类型,类适配器模式和对象适配器模式,由于类适配器模式通过多重继承对一个接口与另一个接口进行匹配,而java等语言都不支持多重继承,也就是一个类只有一个父类,所以我们这里主要讲的是对象适配器。
在软件幵发中,也就是系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控 制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况,比如在需要对早期代码复用一些功能等应用上很有实际价值。
代码:见附录。(需要手工处理,进Eclipse编译最佳!)
2) 桥接模式 Bridge
定义:将抽象部分与它的实现部分分离,使它 们都可以独立地变化。
绘图:
场景/应用:
附注:
对象的继承关系是在编译时就定义好了,所以无法在运行时改变从父类继承 的实现。子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类 发生变化。当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他 更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。
在面向对象设计中,我们还有一个很重要的设计原则,那就是合成丨聚合复用原则。即优先使用对 象合成丨聚合,而不是类继承。
合成(Composition)和聚合(Aggregation)都是关联的特殊种类。聚合表示一种 弱的‘拥有’关系,体现的是A对象可以包含B对象,但B对象不是八对象的一部分:合成则是一种 强的‘拥有’关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。比方说,大 雁有两个翅膀,翅膀与大雁是部分和整体的关系,并且它们的生命周期是相同的,于是大雁和翅膀就是 合成关系。而大雁是群居动物,所以每只大雁都是属于一个雁群,一个雁群可以有多只大雁,所以大雁 和雁群是聚合关系。
合成&聚合复用原则的好处是,优先使用对象的合成7聚合将有助于你保持每个类被封装,并被集中 在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
什么叫抽象与它的实现分离,这并不是说,让抽象类与其派生类分离,因为 这没有任何意义。实现指的是抽象类和它的派生类用来实现自己的对象。就刚才的例子而言,就是让‘手机’既可以按照品牌来分类,也可以按照功能来分类。由于实现的方式有多种,桥接模式的核心意图就是把这些实现独立出来,让它们各自地变化。这 就使得每种实现的变化不会影响其他实现,从而达到应对变化的目的。
实现系 统可能有多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。
代码:见附录。(需要手工处理,进Eclipse编译最佳!)
3) 组合模式 Composition
定义:将对象组合成树形结构以表示‘部分- 整体’的层次结构。组合模式使得用户对单个对象和组合对象 的使用具有一致性。
绘图:
场景/应用:
附注:
这种方式叫做透明方式,也就是说在Composite中声明所有用来管理子对象的方法,其中 包括Add、Remove等。这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处 就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf类本身不具备Add、Remove方法的功能,所以实现它是没有意义的。”那么就需要安全方式,也就是在接口中不去声明方法, 那么子类Leaf就不需要去实现它,而是在Composite声明所有用来管理子类对象的方法,这样做就 不会出现刚才提到的问题,不过由于不够透明,所以树叶和树枝类将不具有相同的接口,客户端的调用 需要做相应的判断,带来了不便。
当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象 的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。组合模式让客户可以一致地使用组合结构和单个对象。
代码:见附录。(需要手工处理,进Eclipse编译最佳!)
4) 装饰模式 Decorator
定义:动态地给一个对象添加一些额外的职 责,就增加功能来说,装饰模式比生成子类更为灵活。。
绘图:
场景/应用:
附注:
装饰模式是利用来对对象进行包装的。这样每个装饰对象的实现就 和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中
如果只有一个 类而没有抽象的 类,那 么0扰0『拟0厂类可以是 的一个子类同样道理,如果只有一个 类,那么就没有必要建立一个单独的 类,而可以把 和 的责任合 并成一个类。
当系统需要新功能的时候,是向旧的类中添加新 的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,比如用西装或嘻哈服来装饰小菜, 但这种做法的问题在于,它们在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂 度,就像你起初的那个‘人’类,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执 行的特殊行为的需要。而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的 类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根 据需要有选择地、按顺序地使用装饰功能包装对象了【0?】。
装饰模式的装饰顺序很重要哦,比如加密数据和过滤词汇都卩了以是数据持久化前 的装饰功能,但若先加密了数据再用过滤功能就会出问题了,最理想的情况,是保证装饰类之间彼此独 立,这样它们就可以以任意的顺序进行组合了。
代码:见附录。(需要手工处理,进Eclipse编译最佳!)
5) 外观模式 Facade
定义:为子系统中的一组接口提供一个一致的界面,此模 式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
绘图:
场景/应用:
附注:
首先,在设计初期阶段,应该要有意识的将不同的两个层分离,比如经典 的三层架构,就需要考虑在数据访问层和业务逻辑层、业务逻辑层和表示层的层与层之间建立外观 这样可以为复杂的子系统提供一个简单的接口,使得耦合大大降低。其次,在开发阶段,子系 统往往因为不断的重构演化而变得越来越复杂,大多数的模式使用时也都会产生很多很小的类,这本是 好事,但也给外部调用它们的用户程序带来了使用上的困难,增加外观如可以提供一个简单的接 口,减少它们之间的依赖。第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩 展了,但因为它包含非常重要的功能,新的需求幵发必须要依赖于它。此时用外观模式?彻也是非常 合适的。你可以为新系统开发一个外观?彻类,来提供设计粗糙或高度复杂的遗留代码的比较清晰 简单的接口,让新系统与对象交互,与遗留代码交互所有复杂的工作。
代码:见附录。(需要手工处理,进Eclipse编译最佳!)
6) 享元模式 Flyweight
7) 代理模式 Proxy
posted on 2013-10-11 12:36 heartstage 阅读(187) 评论(0) 编辑 收藏 举报