概念 :
适配器模式(Adapter Pattern)是一种结构型设计模式,用于将一个类的接口转换成客户端所期望的另一个接口。它允许不兼容的接口之间进行协同工作。
特点 :
- 通过适配器,可以使原本因为接口不匹配而无法合作的类能够一起工作。
- 适配器模式可以在不修改现有代码的情况下实现对目标对象方法和属性的访问。
- 可以使用多个适配器同时进行适配。
优点 :
- 提供了代码复用性,可以重用已有功能而无需修改源代码。
- 实现了解耦,使得客户端与目标对象之间松耦合。
- 增加了系统灵活性和可扩展性。
缺点 :
- 增加了系统复杂性,引入了额外的类和对象。
- 在某些情况下会导致系统过度设计。
适用场景 :
- 当一个对象的改变需要同时影响其他多个对象时。
- 当系统中存在一些对象之间的联动行为,但又希望它们之间解耦合时。
实现方式 :
类适配器
实现原理:
- 定义目标接口(Target),该接口是客户端所期望的接口。
- 创建一个适配者类(Adaptee),该类包含了需要被适配的方法。
- 创建一个适配器类(ClassAdapter),该类继承自适配者类并实现目标接口,通过继承关系同时具有了适配者和目标接口的特性。在适配器中调用适配者的方法来完成对目标接口方法的实现。
实现代码:
java
// 目标接口
interface Target {
void request();
}
// 适配者类
class Adaptee {
public void specificRequest() {
System.out.println("Adaptee specific request");
}
}
// 类适配器,通过继承实现
class ClassAdapter extends Adaptee implements Target {
@Override
public void request() {
specificRequest(); // 调用被适配者的方法
}
}
上述代码中,我们定义了一个目标接口 Target ,其中包含了客户端所期望调用的方法。然后创建一个具体的被适应对象 Adaptee ,它包含了需要被转换成目标对象调用形式但不兼容于 Target 接口规范定义 的方法。
接着,我们创建一个适配器类 ClassAdapter ,该类继承自被适应对象 Adaptee 并实现了目标接口 Target 。在适配器中,通过调用被适应对象的方法来完成对目标接口方法的实现。
使用类适配器方式可以使得客户端能够通过目标接口调用到被适应对象的方法,从而实现了两个不兼容接口之间的协同工作。
存在问题:
- 类适配器方式只能对单一的具体类进行适配,无法同时对多个具体类进行适配。
- 由于采用继承关系,当需要同时继承多个父类时会受到Java单继承限制。
尽管存在以上问题,使用类适配器方式可以较为简单地将一个已有的类转换成满足客户端需求的新类型。
对象适配器
实现原理:
- 定义目标接口(Target),该接口是客户端所期望的接口。
- 创建一个适配者类(Adaptee),该类包含了需要被适配的方法。
- 创建一个适配器类(ObjectAdapter),该类实现目标接口,并在内部持有一个适配者对象的引用。通过调用适配者对象的方法来完成对目标接口方法的实现。
实现代码:
java
// 目标接口
interface Target {
void request();
}
// 适配者类
class Adaptee {
public void specificRequest() {
System.out.println("Adaptee specific request");
}
}
// 对象适配器,通过组合实现
class ObjectAdapter implements Target {
private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest(); // 调用被适应对象的方法
}
}
上述代码中,我们定义了一个目标接口 Target ,其中包含了客户端所期望调用的方法。然后创建一个具体的被适应对象 Adaptee ,它包含了需要被转换成目标对象调用形式但不兼容于 Target 接口规范定义的方法。
接着,我们创建一个适配器类 ObjectAdapter ,该类实现了目标接口 Target 并在内部持有一个适应者对象 Adaptee 的引用。在适配器中,通过调用被适应对象的方法来完成对目标接口方法的实现。
使用对象适配器方式可以使得客户端能够通过目标接口调用到被适应对象的方法,从而实现了两个不兼容接口之间的协同工作。
存在问题:
- 对象适配器方式需要额外创建一个适配器类和持有被适应对象的引用,可能会增加代码复杂性。
- 当需要同时继承多个父类时会受到Java单继承限制。
使用对象适配器方式可以较为灵活地将一个已有的类转换成满足客户端需求的新类型,并且可以支持对多个具体类进行适配。
接口适配器
实现原理:
- 定义目标接口(Target),该接口是客户端所期望的接口。
- 创建一个抽象适配器类(Adapter),该类实现了目标接口,并提供了默认的空方法实现,以便让子类选择性地覆盖需要的方法。
- 创建具体的适配器子类,继承自抽象适配器类,并根据需要重写其中的方法。
java
// 目标接口
interface Target {
void method1();
void method2();
}
// 抽象适配器
abstract class Adapter implements Target {
public void method1() {} // 默认空方法实现
public void method2() {} // 默认空方法实现
}
// 具体适配器子类,根据需要选择性地覆盖父类方法
class ConcreteAdapter extends Adapter {
@Override
public void method1() {
System.out.println("ConcreteAdapter's method1");
}
}
上述代码中,我们定义了一个目标接口 Target ,其中包含了客户端所期望调用的多个方法。然后创建一个抽象适应器类 Adapter ,该类实现了目标接口并提供了默认的空方法实现。
最后,我们创建具体的适应器子类 ConcreteAdapter ,该类继承自抽象适配器类,并根据需要选择性地覆盖其中的方法。在这个例子中,我们只重写了 method1 方法。
使用接口适配器方式可以使得客户端能够选择性地实现目标接口中的方法,而不需要强制实现所有的方法。
存在问题:
- 接口适配器方式可能会导致类的层次结构变得复杂。
- 当需要同时继承多个父类时会受到Java单继承限制。
使用接口适配器方式可以提供更大的灵活性和可定制性,让客户端能够根据自身需求选择要实现的方法。