什么是adpter (wrapper)适配器
假设我们当前有一个从日本买回的笔记本电脑,但是我国的AC都是220V的电源,如果我们想要使用,还得买一个电源适配器把220V转换为100V的AC ,这个作为转换电源灯的适配器就是现在要说的适配器了.
适配器的种类
| 名称 | 具体|
类适配器 | 使用继承的适配器
对象适配器 | 使用委托的适配器
具体什么时候使用适配器 有点
- 在敏捷开发过程中,我们并非是从零开始编程,如果使用现有已经完善的功能类,开发新的功能类,在使用适配器的情况,如果出现bug我们可以立即在适配器类中寻找bug,不用顾及过去已经完善的类
- adpter 在不改变现有代码的情况下 使现有代码适配于新的接口,如果可能的话,在不知道现有类的功能,就可以编写新的类.
- 照顾版本升级与迭代 : 如果新的版本已经开发出来,但是不想丢下老的版本的,那么适配器是新老版本的中间件
- adpter 在使用的过程中与target 必须是一致的 ,如果不一致,将无法完成我们的功能.
- 简单的说当成现有程序达不到我们的要求的时候,我们通过wrapper进行包装,产生达到我们的需求的程序.
类适配器(以适配器显示打印两种字符 #为weak * strong)
UML图
- banner 为已经实现的功能类 220V电源
- print 接口 我们需要的功能类 12v直流电源
- printbanner 为适配器 转换器
code
- banner
public class Banner {
private String str;
public Banner(String str) {
this.str = str;
}
public void printStarWeak(){
System.out.println("**"+this.str+"** ");
}
public void printStarStrong(){
System.out.println("##"+this.str+"##");
}
}
public interface Print {
public abstract void printWeak();
public abstract void printStrong();
}
- printbanner
public class PrintBanner extends Banner implements Print{
public PrintBanner(String str) {
super(str);
}
@Override
public void printWeak() {
super.printStarWeak();
}
@Override
public void printStrong() {
super.printStarStrong();
}
}
表格加强说明关系
对象适配器(使用委托
- 说明: 使用委托:将某个方法中的实际处理交给其他实例的方法(在java中使用委托 可以使用静态委托 动态委托) 这里选择使用静态委托
依据要求: MainT类 Banner类 与前面的完全相同,改变的是printBanner类 在printbanner类中声明一个字段的,通过字段进行调用.
UML 使用委托
-
print: 对象适配器替换的为抽象类, 有因为java不能多重继承,所以采用委托的方式.
-
printbanner: 迭代器方式,提供委托的办法调用实际banner的已经实现的方法.
Code
public abstract class Print {
public abstract void printWeak();
public abstract void printStrong();
}
- printbanner
public class printBanner extends Print{
private Banner banner;
public printBanner(String str) {
this.banner = new Banner(str);
}
@Override
public void printWeak() {
banner.printStarWeak();
}
@Override
public void printStrong() {
banner.printStarStrong();
}
}
相关设计模式
- Bridge: adpter设计模式用于连接接口(api)不同的类, 而Bridge 用于链接类的功能层次结构与实现层次结构.
- Decorator: 用于填补不同的接口之间的缝隙, 而装饰者设计模式则是在不改变接口的前提下增加功能.
提高:
question: 请使用adpter模式编写一个将属性集合保存至文件中的FilePropertion类
FiloIo(Target) 中声明了将属性集合保存至文件的方法.并且假设FilePropertion类将实现这个FileIo接口 输入文件 file.txt 输出文件newfile.txt.
编写FilePropertion适配器,在我们只知道的FiloIo的情况下也可以对属性进行处理.
code
- 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);
}
- MainT
public class MainT {
public static void main(String[] args) {
FileIO f = new FileProperties();
try {
f.readFromFile("file.txt");
f.setValue("year", "2004");
f.setValue("month", "4");
f.setValue("day", "21");
f.writeToFile("newfile.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 答案
**/
public class FileProperties extends Properties implements FileIO {
@Override
public void readFromFile(String filename) throws IOException {
super.load(new FileInputStream(filename));
}
@Override
public void writeToFile(String filename) throws IOException {
super.store(new FileOutputStream(filename),"写出的配置文件");
}
@Override
public void setValue(String key, String value) {
super.setProperty(key,value);
}
@Override
public String getValue(String key) {
return getProperty(key, "");
}
}
- UML 图