二、Adapter 模式 (加一个适配器,以便复用)
2.1 适配器模式通俗的解释
适配器模式的解释:在程序世界中,经常会有现现有的程序无法直接使用的情况,需要做适当的变换才可以使用。这种用于填补 “现有的程序” 和 “所需的程序” 之间差异的设计模式就称为 适配器模式
我的理解:适配器模式可以类比为 插头 与 插座 **的关系
2.2 适配器的模式的种类
- 类适配器模式(使用继承的适配器)
- 对象适配模式(使用委托的适配器)
2.3 实现适配器模式
2.3.1 使用继承的适配器
我们使用一个如下实例,输入一段 Hello 字符串,可以打印出 “Hello” 或 (Hello) 两种类型。分别代表强化字符串 和 弱化字符串
具体怎么使用适配器模式实现?
- 定义一个 Banner 类,包括用字符串括号括起来的 showWithParen() 和用 字符串 括起来的 showWithAster()。这代表我们*实际的情况
- 定义一个 Print 接口,里面分别包括了(加括号)的 printWeak() ,和(加 号)的 printStrong() 方法,我们假设这个接口是类似于*需求
- 需要一个适配器,通过 Banner 类实现 Print 接口的需求,扮演这个适配器角色的是 PrintBanner 类
实际情况 | 实现两种 Banner 的打印 | Banner (showWithParen、showWithAster) |
---|---|---|
需求(接口) | Print 接口 | Print接口(printWeak、printStrong) |
适配器 | printBanner | PrintBanner类 |
具体实现
Banner 类
/**
* 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 + "**");
}
}
Print 接口
// 需求接口
public interface Print {
public abstract void printWeak();
public abstract void printStrong();
}
PrintBanner 类 (核心) 子类继承父类,获得父类的方法
public class PrintBanner extends Banner implements Print{
public PrintBanner(String string) {
super(string);
}
// 括号
@Override
public void printWeak() {
showWithParen();
}
// *
@Override
public void printStrong() {
showWithAster();
}
}
Main 测试类
public class Main {
public static void main(String[] args) {
Print p = new PrintBanner("Hello");
p.printStrong();
p.printWeak();
}
}
在这里面呢,我们使用 Print 保存了 PrintBanner实例,并且隐藏了 Banner 类,showWithxxx() 方法,而且 Main 并不知道 printBanner 是如何实现的,这样就可以不用修改 Main 类了
2.3.2 使用委托的适配器
委托:将某个方法中的实际处理交给其他实例的方法
通过一种委托关系:当 PrintBanner 类的 printWeak() 被调用的时候,并不是 PrintBanner 类自己处理,而是交给了其它的实例(Banner 类的实例)的 showWithParen()
Print 类
public abstract class Print {
public abstract void printWeak();
public abstract void printStrong();
}
PrintBanner 类(printWeak 交给了 Banner 来处理)
public class PrintBanner extends Print {
private Banner banner;
public PrintBanner(String string) {
this.banner = new Banner(string);
}
@Override
public void printWeak() {
banner.showWithParen();
}
@Override
public void printStrong() {
banner.showWithAster();
}
}
2.4 为什么使用适配器模式
使用 Adapter 模式可以在完全不修改现有代码的前提下使现有代码适配新的接口 API。在 Adapter 模式中,并非一定需要现成的代码,只需要知道类的功能,就可以编写出新的类
2.5 适配器模式总结
- 使用 “继承”、“委托”实现适配器模式
- Adapter 用于填补具有不同接口(API)两个类之间的间隙