
Adapter模式——适配器
Adapter模式介绍
现实中的“适配器”(Adapter的中文),可以让直流12伏特的笔记本在100伏特的AC电源下工作:
在程序中,经常会存在一些程序无法直接使用,需要进行适当转换才能使用,这这哦末弥补“现有程序”和“所需程序”之间差异的设计模式就是 Adapter模式
Adapter模式也被称为 Wrapper模式,因此,Apapter模式也被称为“包装器”或“适配器”
示例程序(使用继承的适配器)
介绍:
你现在需要将一个100伏的电流转换为12伏的适配器
关系:
电源的比喻 | 示例程序 | |
---|---|---|
实际情况 | 交流100伏特 | Banner类(showWithParen、showWithAster) |
变换装置 | 适配器 | PrintBanner类 |
需求 | 直流12伏特 | Print接口(printWeak、printStrong) |
类图
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 + "*");
}
}
- 提供了两个方法,
(xxx)
表示弱电,*xxx*
表示强电
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();
}
}
PrintBanner
作为适配器,继承了Banner又实现了Print
Main类
public class Main {
public static void main(String[] args) {
Print p = new PrintBanner("Hello");
p.printWeak();
p.printStrong();
}
}
示例程序(使用委托的示例程序)
“委托”,就是“交给他人”,此示例程序旨在将无法处理的内容交给其他方法处理。
类图:
根据类图来看,委托的方式和继承的类图非常相似,Print
不再是接口而是一个类,并且直接继承,而 Banner
也不是作为PrintBanner 的父类,而是直接聚合了它
因此,只需要修改Print类和PrintBanner类
Print类
public abstract class Print {
public abstract void printWeak();
public abstract void printStrong();
}
PrintBanner类
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();
}
}
Adapter模式中的登场角色
- Target(对象)
- 该角色负责定义所需的方法。在示例程序中,
Print
扮演此角色。
- 该角色负责定义所需的方法。在示例程序中,
- Client(请求者)
- 该角色负责使用 Target 角色所定义的方法进行具体处理。在示例程序中,
Main
扮演。
- 该角色负责使用 Target 角色所定义的方法进行具体处理。在示例程序中,
- Adaptee(被适配)
- 该角色持有一个既定方法,方便
Apapter
调用。在示例程序中,由Banner
扮演
- 该角色持有一个既定方法,方便
- Apapter(适配)
- 主人公,使用
Adaptee
的方法满足Target
的需求。在示例程序中,PrintBanner
扮演。
- 主人公,使用
角色的类图:
继承下
:
委托下
:
拓展要点
什么时候使用Adapter模式
Adapter模式会对现有的类进行适配,因此一些工具类(如Logg4j)等,可以使用 Adapter模式,让现有的类扮演 Adapter,直接满足需要方法即可,这样可以大大减少开发时间,并且可以降低自定义开发的Bug率。
没有现成的代码
即时现有的类没有我需要的功能,也尽量不修改已测试好的代码,可以自己编写一个自定义的。
版本升级与兼容性
如软件总是会进行更新的,我们如果使用 Adapter 模式使新旧版本兼容,那么可以同时维护新旧版本的代码。
使用案例
你现在需要在 FileIO
接口的基础上使用适配器模式,作出一个 继承自 Properties
的 FileProperties
FileIO:
public interface FileIO {
public void readFromFile(String filename) throws IOException;
public void writeToFIle(String fileName) throws IOException;
public void setValue(String key, String value);
public String getValue(String key);
}
file.txt:
year=1999
Properties是JDK自带的 java.util.Properties
编写 FileProperties
public class FileProperties extends Properties implements FileIO {
@Override
public void readFromFile(String fileName) throws IOException {
load(new FileInputStream(fileName));
}
@Override
public void writeToFIle(String fileName) throws IOException {
store(new FileOutputStream(fileName), "written by FileProperties");
}
@Override
public void setValue(String key, String value) {
setProperty(key, value);
}
@Override
public String getValue(String key) {
return getProperty(key);
}
}
Main:
public class Main {
public static void main(String[] args) throws IOException {
FileIO f = new FileProperties();
f.readFromFile("file.txt");
f.setValue("year", String.valueOf(new DateTime().year()));
f.setValue("month", String.valueOf(new DateTime().month() + 1));
f.setValue("day", String.valueOf(new DateTime().dayOfMonth()));
f.writeToFIle("newFile.txt");
}
}
newFile.txt需要手动创建一下,最后如下:
#written by FileProperties
#Tue Jan 07 19:08:45 CST 2025
day=7
file=xxx.png
month=1
year=2025
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 zxb
评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果