Adapter 模式
1.什么是 Adapter 模式
用来填补现有的程序和所需的程序之间差异的设计模式就是 Adapter 模式。
Adapter 模式有两种:
● 类适配器模式,即使用继承的适配器
● 对象适配器模式,即使用委托的适配器
2.使用继承的适配器示例程序
2.1 类适配器模式类图
2.2 Banner 类
提供 showWithParen 和 showWithAster 方法,可以被继承。但是 Main 方法并不知道 Banner 类和它的方法的存在。
public class Banner {
private String string;
public Banner(String string) {
this.string = string;
}
public void showWithParen() {
System.out.println("(" + string + ")");
}
public void showWithAster() {
System.out.println("*" + string + "*");
}
}
2.3 Print 接口
Print 是需求的接口,也就是 Main 方法里需要使用 pringWeak 和 printStrong 方法。
public interface Print {
public abstract void printWeak();
public abstract void printStrong();
}
2.4 PrintBanner 类(实现 Print ,继承 Banner )
继承 Banner 类,实现 Print 接口,起到适配器的作用,将 Banner 的细节隐藏起来,对外提供实现了的 Print 接口的方法。
public class PrintBanner extends Banner implements Print{
public PrintBanner(String string) {
super(string);
}
public void printWeak() {
showWithParen();
}
public void printStrong() {
showWithAster();
}
}
2.5 Main 类
调用 Print 接口的方法,但实际实现是 Banner 的方法提供实现。
public class Main {
public static void main(String[] args) {
Print p = new PrintBanner("Adapter");
p.printWeak();
p.printStrong();
}
}
// 程序执行结果:
// (Adapter)
// *Adapter*
3.使用委托的适配器示例程序
3.1 对象适配器模式类图
3.2 Banner 类
提供 showWithParen 和 showWithAster 方法,作为 PrintBanner 的成员变量。
public class Banner {
private String string;
public Banner(String string) {
this.string = string;
}
public void showWithParen() {
System.out.println("(" + string + ")");
}
public void showWithAster() {
System.out.println("*" + string + "*");
}
}
3.3 PrintBanner 类
成员变量是 Banner 的实例化对象,继承抽象类 Print ,起到适配器的作用。
public class PrintBanner extends Print {
private Banner banner;
public PrintBanner(String string) {
this.banner = new Banner(string);
}
public void printWeak() {
banner.showWithParen();
}
public void printStrong() {
banner.showWithAster();
}
}
3.4 Print 类
抽象类,提供 printWeak 和 printStrong 方法。
public abstract class Print {
public abstract void printWeak();
public abstract void printStrong();
}
3.5 Main 类
调用 Print 抽象类的方法,但实际实现是 Banner 对象的方法实现。
public class Main {
public static void main(String[] args) {
Print p = new PrintBanner("Adapter");
p.printWeak();
p.printStrong();
}
}
// 程序执行结果:
// (Adapter)
// *Adapter*
4.思考
4.1 隐藏被适配者
PrintBanner 作为一个适配器,可以隐藏掉真正实现方法的类或者对象以及它们的方法,这样不管具体实现是什么样的, Main 中的代码都不需要修改,只需要调用 PrintBanner 的方法即可。
4.2 两种模式的区别
类适配器模式中的适配器类继承被适配者(Banner)获取被适配者的方法,而对象适配器模式中的适配器类将被适配者(Banner)作为成员变量,通过实例化对象获取方法。
4.3 使用场景(有现有的经过充分测试的类)
Adapter 模式会对现有的类进行适配,生成新的类,我们使用的时候就直接使用这个新的类。一但出现了 Bug ,如果现有的类不存在问题,那么就可以直接去新的类中排查问题。
4.4 避免对测试过的代码进行修改
如果有已经经过测试的代码要拿来用,但是需要做一些修改的时候,最好不要在这个代码上进行修改,否则会改变原有代码,需要重新测试。使用适配器模式可以避免对这些代码进行修改,只需要知道现有的这些代码的功能,就可以编写新的类使这些代码适配新的接口。
4.5 版本兼容
当版本升级的时候,可以让新的功能扮演被适配者的角色,这样就可以让旧版本使用新的功能,实现版本的兼容。