《Head First设计模式》阅读笔记.第七章

来源:百度文库 编辑:神马文学网 时间:2024/05/01 01:43:21
2010-01-21

《Head First设计模式》阅读笔记.第七章

文章分类:Java编程 1.适配器(Adapter)模式部分

*OO适配器和真实世界的适配器扮演者同样的角色:将一个接口转换成另一个接口,以符合客户的期望。

*适配器(Adapter)类看起来很像命令(Command)模式中命令接口的实现类,只不过它不被作为参数传递。

Java代码
  1. ----DuckAdapter类----   
  2. public class DuckAdapter implements Turkey {   
  3.     private Duck duck;   
  4.        
  5.     public DuckAdapter(Duck duck) {   
  6.         this.duck = duck;   
  7.     }   
  8.        
  9.     public void goggle() {   
  10.         duck.quack();   
  11.     }   
  12.        
  13.     public void fly() {   
  14.         duck.fly();   
  15.     }   
  16. }   
  17. ------------  


适配器模式:将一个类的接口,转换成客户希望的另一个接口。适配器让原本接口不兼容的类合作无间。

*适配器模式可以让客户从实现的接口解耦。

*适配器(Adapter)模式充满着良好的OO设计原则:使用对象组合,以修改的接口包装被适配者;这种做法还有额外的优点,那就是被适配者的任何子类都可以搭配着适配器使用。

*适配器(Adapter)分为“对象(Object)”适配器和“类(Class)”适配器两种。

*在类适配器中,适配器继承了目标(Target)和被适配者(Adaptee);而对象适配器中,适配器利用组合的方式将请求传送给被适配者。

*类适配器是基于多重继承实现的,因为Java不支持多重继承,因此无法做到。

*由于类适配器使用了继承的方式,所以它的优点是不需要整个实现被适配者,必要的时候还可以覆盖被适配者的行为。

Java代码
  1. ----练习。解答----   
  2. public class ArrayListEnumeration implements Enumeration {   
  3.     private ArrayList list;   
  4.   
  5.     public ArrayListEnumeration(ArrayList al) {   
  6.         this.list = al;   
  7.     }   
  8.   
  9.     public boolean hasMoreElements() {   
  10.         return list.iterator().hasNext();   
  11.     }   
  12.   
  13.     public Object nextElement() {   
  14.         return list.iterator().next();   
  15.     }   
  16. }   
  17. ------------  


引用*装饰者(Decorator)模式与适配器(Adapter)模式的区别
(1)装饰者模式与“责任”相关,当涉及到装饰者时,就表示有一些新的行为或责任要加到设计中。
(2)适配器允许客户使用新的库和子集合,无须改变“任何”已存在的代码,由适配器负责转换即可。
(3)装饰者不会改变接口,而适配器会改变接口。
(4)装饰者的工作是扩展被包装对象的行为或责任,并不是“简单传递”就算了。
(5)装饰者(Decorator)模式与适配器(Adapter)模式的最大不同在于使用它们的意图(或目的)。

----连连看解答----
装饰者(Decorator)模式->不改变接口,但加入责任
适配器(Adapter)模式->将一个接口转换成另一个接口
外观(Facade)模式->让接口更简单
------------

2.外观(Facade)模式部分

*外观模式在简化接口的同时,依然将系统完整的功能暴露出来,一共需要的人使用。

*外观模式不仅简化了接口,也将客户从组件的子系统中解耦。

*适配器(Adapter)模式和外观(Facade)模式都可以包装多个类,前者的目的是将接口重新组织后提供新接口,后者的目的是简化接口。由于它们的差异很细微,所以两者常常同时出现。

外观模式:提供了一个统一的接口,用来访问子系统中的一群接口。外观模式定义了一个高层接口,让子系统更容易使用。

软件设计原则:要减少对象之间的交互,只留下几个“密友”。这个原则被成为“最少知识(Least Knowledge)原则”,它告诉我们只和自己的密友谈话。

*最少知识(Least Knowledge)原则告诉我们,不要让太多的类耦合在一起,免得修改系统的一部分,会影响到其它部分。如果许多类之间互相依赖,那么这个系统就是一个易碎的系统,需要花许多成本维护,也会因为太复杂而不容易被他人理解。

引用*通过只调用以下几种范围内的方法可以做到尽量遵循“最少知识原则”:
(1)该对象本身
(2)被当做方法的参数而传递进来的对象
(3)此方法所创建或实例化的任何对象
(4)对象的任何组件,比如类或对象本身的变量,或常量

*最少知识原则的不同名称:(Principal of) Least Knowledge,(The) Law of Demeter,迪米特法则,得墨忒耳法则

*使用最少知识原则的缺点是:更多的“包装类”被创造出来,以处理和其它组件的沟通。这可能导致复杂度和开发时间的增加,并减低运行时的性能。

引用----Sharpen Your Pencil----
第一个House类违反了“最少知识原则”,第二个House类则没有。
------------

3.适配器(Adapter)模式和外观(Facade)模式小结

*当需要使用一个现有的类,而其接口并不符合你的需要时,就使用适配器。

*当需要简化并统一一个很大的接口或者一群复杂的接口时,使用外观。

*适配器改变接口以符合客户的期望。

*外观将客户从一个复杂的子系统中解耦。

*实现一个适配器所要花费的工作量取决于目标接口的大小及复杂程度。

*实现一个外观,需要将子系统组合进外观中,然后将工作委托给子系统执行。

*适配器有两种形式:对象适配器和类适配器。类适配器需要用到多重继承。

*可以为一个子系统实现一个以上的外观。

*适配器(Adapter)将一个对象包装起来以改变其接口;装饰者(Decorator)将一个对象包装起来以增加新的行为和责任;而外观(Facade)将一群对象包装起来以简化其接口。

4.适配器(Adapter)模式实例
Java代码
  1. // 让所有List支持枚举   
  2. public class ListEnumeration implements Enumeration {   
  3.     private List list;   
  4.   
  5.     public ListEnumeration(List al) {   
  6.         this.list = al;   
  7.     }   
  8.   
  9.     public boolean hasMoreElements() {   
  10.         return list.iterator().hasNext();   
  11.     }   
  12.   
  13.     public Object nextElement() {   
  14.         return list.iterator().next();   
  15.     }   
  16. }  


5.外观(Facade)模式实例
Java代码
  1. // 车锁   
  2. public class CarLock {   
  3.     public void lock() {   
  4.         System.out.println("Car is locked.");   
  5.     }   
  6.   
  7.     public void unlock() {   
  8.         System.out.println("Car is unlock.");   
  9.     }   
  10. }   
  11.   
  12. // 发动机   
  13. public class Engine {   
  14.     public void start() {   
  15.         System.out.println("Engine is started.");   
  16.     }   
  17.   
  18.     public void stop() {   
  19.         System.out.println("Engine is stopped.");   
  20.     }   
  21. }   
  22.   
  23. // 汽车外观类   
  24. public class CarFacade {   
  25.     private CarLock lock;   
  26.   
  27.     private Engine engine;   
  28.   
  29.     public CarFacade(CarLock lock, Engine engine) {   
  30.         this.lock = lock;   
  31.         this.engine = engine;   
  32.     }   
  33.   
  34.     public void startCar() {   
  35.         this.lock.unlock();   
  36.         this.engine.start();   
  37.     }   
  38.   
  39.     public void stopCar() {   
  40.         this.engine.stop();   
  41.         this.lock.lock();   
  42.     }   
  43. }  


--END--