照例搬上来 Head First Design Patterns 中的定义,适配器模式将类的接口转换为客户期望的另一个接口。 适配器允许继承不兼容的接口的类一起工作。
这个设计模式理解起来非常简单,就是把一个类的接口变换成客户端所能接受的另一种接口,使两种接口不匹配的类能一起工作。
代码如下:
public interface InterfaceVersion1 {
public void function();
}
public interface InterfaceVersion2 {
public void renamedFunction();
public void newFunction();
}
public class Adapter implements InterfaceVersion2 {
private InterfaceVersion1 adaptee;
public Adapter(InterfaceVersion1 adaptee){
this.adaptee=adaptee;
}
@Override
public void renamedFunction(){
adaptee.function(); //调用了原接口的方法
}
@Override
public void newFunction(){
//新添加的功能和方法
}
}
上面的类图和代码表现的都是对象适配器,还有一种适配器叫类适配器,类图是这样的
其中Adapter 类继承 Adaptee 类(被适配类),同时实现Target 接口(因为 Java 不支持多继承,所以只能通过接口的方法来实现多继承),在 Client 类中我们可以根据需要选择并创建任一种符合需求的子类,来实现具体功能。
说了这么多,来个代码理解一下(来自引用四)
// 已存在的、具有特殊功能、但不符合我们既有的标准接口的类
class Adaptee {
public void specificRequest() {
System.out.println("被适配类 具有特殊功能...");
}
}
// 目标接口,或称为标准接口
interface Target {
public void request();
}
// 具体目标类,只提供普通功能
class ConcreteTarget implements Target {
public void request() {
System.out.println("普通类 具有普通功能...");
}
}
// 适配器类,继承了被适配类,同时实现标准接口
class Adapter extends Adaptee implements Target{
public void request() {
super.specificRequest();
}
}
// 测试类
public class Client {
public static void main(String[] args) {
// 使用普通功能类
Target concreteTarget = new ConcreteTarget();//实例化一个普通类
concreteTarget.request();
// 使用特殊功能类,即适配类
Target adapter = new Adapter();
adapter.request();
}
}
有一种特殊的适配器,叫做外观模式(The FaCade Pattern) 这篇博文 对该模式有非常详细的介绍,下面是关于这两种模式的区别:
The Principle of Least Knowledge
为了降低类之间的耦合度,通常只调用 来自于对象本身的方法、需要作为方法参数的对象、所有该方法创建或实例化的对象、该对象的组成部分,千万不要调用那些返回调用其它方法结果的方法!
遵循这一原则的优点就是 减小了对象直接的依赖,减少了将来维护的成本;但缺点就是会产生很多 ‘‘wrapper’’ 类专门来防止其它部分的调用,这会导致复杂度增加。
下图体现了外观模式和最小知识原则的关系:
参考资料:
- Head First Design Patterns
- 老师上课的PPT
- lab作业
- https://blog.csdn.net/qq_36982160/article/details/79965027