定义
将一个类的接口转换成客户希望的另一个类的接口使得原本由于接口不兼容而不能一起工作的类可以一起工作。
本质
转换匹配,复用功能。
登场角色
-
Target(对象)
该角色负责定义所需要的新的调用方法接口,即需要适配器模式适配后的新的接口的样子。
-
Client(请求者)
新接口的使用者,调用自己需求的新的Target接口。
-
Adaptee(被适配)
已经存在的部分,通常能满足功能需求,但是接口不满足需求,是将要被适配的部分。
-
Adapter(适配)
适配器模式的主人公,适配旧的方法,满足Target角色的需求,这也是适配器模式的目的。
适配器模式根据实现方式不同,可分为类适配器模式和对象适配器模式两种方式,在类适配器模式中,通过继承的方式实现,在对象适配器模式中,通过持有旧的被适配器的对象即“委托”的方式来实现。
示例代码(类适配器模式)
/**
* 需要被适配的类,持有旧的方法
*/
public class Banner {
private String message;
public Banner(String message){
this.message = message;
}
public void showWithParen(){
System.out.println("(" + message + ")");
}
public void showWithAster(){
System.out.println("*" + message + "*");
}
}
/**
* 需要适配后的新的调用方式
*/
public interface Print {
void printWeak();
void printStrong();
}
/**
* 适配器角色,适配旧方法的具体实现方式
*/
public class PrintBanner extends Banner implements Print{
public PrintBanner(String message) {
super(message);
}
@Override
public void printWeak() {
showWithParen();
}
@Override
public void printStrong() {
showWithAster();
}
}
/**
* 新接口的使用者
*/
public class Main {
public static void main(String args[]){
PrintBanner printBanner = new PrintBanner("这是类适配器模式");
printBanner.printWeak();
printBanner.printStrong();
}
}
运行结果
(这是类适配器模式)
*这是类适配器模式*
示例代码(对象适配器模式)
/**
* 新的接口调用方式
*/
public abstract class Print {
public abstract void printWeak();
public abstract void printStrong();
}
/*
适配旧方法的具体的实现方式
*/
public class PrintBanner extends Print{
private Banner banner;
PrintBanner(Banner banner){
this.banner = banner;
}
@Override
public void printWeak() {
banner.showWithParen();
}
@Override
public void printStrong() {
banner.showWithAster();
}
}
/**
* 新方法的使用者
*/
public class Main {
public static void main(String args[]){
PrintBanner printBanner = new PrintBanner(new Banner("这是对象适配器"));
printBanner.printWeak();
printBanner.printStrong();
}
}
运行结果
(这是对象适配器)
*这是对象适配器*
功能
进行转换匹配,目的是复用已有的功能,而不是来实现新的接口,也就是说客户端需要的功能是已经实现了的,需要适配器模式将不兼容的接口转换成客户端需要的样子。
优点
- 更好的复用性,如果功能已经存在,只是接口不兼容,那么只需要通过适配器模式就可以直接复用这些功能,而不用重新编写。
- 更好的扩展性,在复用就功能的实现,可以很方便的添加新的功能。
缺点
- 过多的使用适配器,会让系统凌乱,比如表面看到调用了A接口,实际上是调用了B 接口。