本文最后更新于 2025-01-01T10:40:43+08:00
概念
适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
优点和缺点
类适配器
优点
- 可以覆盖自适应对象的行为,因为它使用继承
- 比对象适配器稍快,因为方法调用在编译时解析(静态绑定)
缺点
- 由于继承而与适应类紧密耦合
- 不能适应多个自适应对象(因为大多数语言不支持多重继承)
- 不太灵活,因为它依赖于编译时关系
类适配器通过绑定到特定的Adaptee类来使Adaptee适应Target,这意味着它不能适应类及其所有子类。这种类型的适配器允许适配器覆盖Adaptee的一些行为,因为适配器是Adaptee的子类。 此外,它只引入一个对象,而不需要额外的指针间接地使用Adaptee。
对象适配器
优点
- 更灵活,因为它不依赖于继承
- 可以通过包装不同的对象来使用多个自适应器
- 与被适应者松散耦合,使其在将来更容易修改或扩展
缺点
- 由于额外的间接级别(方法调用在运行时解析),动态绑定,比类适配器稍微慢一些
对象适配器允许单个适配器与多个Adaptee一起工作,包括Adaptee及其所有子类。这种类型的适配器可以同时向所有适配器添加功能。然而,它使得重写Adaptee的变得更加困难,因为它需要继承Adaptee的子类,并且让Adapter引用这个子类而不是Adaptee本身
什么时候使用适配器模式
- 想要复用现有的类,但它的接口与你需要的不匹配
- 创建一个可重用的类,它可以与不相关或不可预见的类(即不一定具有兼容接口的类)协作
- 需要使用几个现有的子类,但是通过将每个子类化来调整它们的接口是不切实际的。对象适配器可以调整其父类的接口
- 大多数使用第三方库的应用程序都使用适配器作为应用程序和第三方库之间的中间层,以将应用程序与库分离。如果必须使用另一个库,则只需要新库的适配器,而不必更改应用程序代码
适配器代码示例
类适配器(多在支持多重继承的语言里使用,例如C++)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| interface Target { void request(); }
class Adaptee { void specificRequest() { System.out.println("Specific request"); } }
class ClassAdapter extends Adaptee implements Target { @Override public void request() { specificRequest(); } }
public class Main { public static void main(String[] args) { Target target = new ClassAdapter(); target.request(); } }
|
对象适配器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| interface Target { void request(); }
class Adaptee { void specificRequest() { System.out.println("Specific request"); } }
class ObjectAdapter implements Target { private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee) { this.adaptee = adaptee; }
@Override public void request() { adaptee.specificRequest(); } }
public class Main { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); Target target = new ObjectAdapter(adaptee); target.request(); } }
|
设计模式之适配器模式
http://s1mplecode.com/design-pattern/adapter.html