适配器模式
适配器模式是个相当好理解的模式,可以参考生活中的电源适配器。
假设已有一个软件系统,我们希望它能和一个新的厂商类库搭配使用,但是这个新厂商所设计的接口和旧厂商的接口不同。
这时我们就可以写一个类,实现新厂商接口,但真正提供服务是被封装的旧厂商(反过来也可以,甚至是双向适配器)。外部客户只需要调用新厂商接口,而不需要直到内部是谁实现的。这个适配器相当于一个中间人,将客户锁发出的请求转成厂商类所能理解的请求。
假设我们缺少鸭子对象,需要使用火鸡对象来冒充鸭子。我们可以这样做:
1 | public interface Duck { |
1 | public interface Turkey { |
写个适配器:
1 | public class TurkeyAdapter implements Duck { |
1 | public class DuckTestDrive { |
这里鸭子是目标接口,火鸡就是被适配者。
客户使用适配器的过程如下:
- 客户通过目标接口调用适配器的方法对适配器发出请求。
- 适配器使用陪被适配者接口执行请求。
- 客户收到调用的结果,但并未察觉这一切是适配器在起转换作用。
同样的,我们也可以写一个适配器将鸭子转为火鸡。
定义适配器模式
适配器模式将一个类的接口,转换为客户期望的另一个接口。适配器让原本接口不兼容的类可以互相合作。
同样适配器可以将改变的部分封装起来,被适配者接口改变时,客户端代码也不需要修改。
对象适配器和类适配器
适配器主要有两类:对象适配器和类适配器。前面在鸭子的例子使用的是对象适配器。对象适配器使用的是组合,而类适配器使用的是继承(多继承)。
Java的枚举器
1 | public class EnumerationIterator implements Iterator { |
1 | public class EnumerationIteratorTestDrive { |
比较装饰器、适配器和外观:
装饰者:不改变接口,但加入责任
适配器:将一个接口转成另一个接口
外观:让接口更简单
外观模式
外观模式的意图是简化接口,而适配器的意图是将接口转换。使用外观模式,我们通过创建一个接口简化而统一的类,用来包装子系统中一个或多个复杂的类。
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
这也符合了OO的另一个设计原则:最少知识原则
最少知识原则:只和你的密友谈话。
这个原则希望我们在设计中,不要让太多的类耦合在一起,免得修改系统中的一部分,会信息到更多的部分。我们需要尽量使类对其他类对象的依赖尽可能的少。除了上面的外观模式,另一个指导原则就是:就任何对象而言,在该对象的方法内,我们只应该调用属于一下范围的方法:
- 该对象本身
- 被当做方法的参数而传递进来的对象
- 此方法所创建或实例化的任何对象
- 对象的任何组件(组合方式的成员变量)