真实世界的适配器:
程序世界的适配器:
类似于现实世界适配器的需求,程序世界也有这样的额需求.假设存在一个已经设计好的厂商类,要为其增加一个新的系统,但是接口却是这样的,两个接口无法匹配,无法工作.
可行的办法是设计一个适配器,将新增系统的接口转换为厂商类可以适配的接口.
适配器使用过程
- 客户通过目标接口调用适配器的方法对适配器发出请求
- 适配器使用被适配接口把请求转换成被适配者的一个或者多个调用接口
- 客户收到调用的结果,但未察觉这一切是适配器在起转换作用
- 客户和被适配器之间其实是解耦的,互不知晓(我们所说的,透明的)
定义适配器模式
适配器模式:将一个类的接口,转换成客户期望的另一个接口,从而实现兼容
他的通用代码如下(属于对象适配器):
package cn.sf.adapter;
public class Adaptee {
//Adptee:现在需要适配的已经存在的接口
public void specificRequest() {
System.out.println("调用接口,使用存在的厂商类");
}
}
public interface Target {
// target:定义client使用的与特定领域相关的接口
void Request();
}
package cn.sf.adapter;
public class Adapter implements Target {
Adaptee adaptee = new Adaptee();
public Adapter() {
// TODO Auto-generated constructor stub
}
public Adapter(Adaptee adaptee) {
super();
this.adaptee = adaptee;
}
@Override
public void Request() {
// TODO Auto-generated method stub
adapter.specificRequest();
}
}
package cn.sf.adapter;
public class Client {
public static void main(String[] args) {
// 调用适配器接口
Target adapter = new Adapter();
adapter.Request();
}
}
对象适配器
- 允许一个Adapter与多个adaptee同时工作,即adaptee本身以及他的所有的子类可以同时工作.adapter可以一次给所有的adaptee添加所有的功能
- 使用组合,不仅可以适配某个类,也可以适配该类的任何子类
类适配器:
- 用一个具体的Adapter类对adaptee和target进行匹配,adapter类多重继承adaptee和target类
- Adapter可重定义adaptee的部分行为,因为Adapter是adaptee的一个子类
通用代码:
public interface Target {
// target:定义client使用的与特定领域相关的接口
void Request();
}
package cn.sf.adapter;
public class Adaptee {
//Adptee:现在需要适配的已经存在的接口
public void specificRequest() {
System.out.println("调用接口,使用存在的厂商类");
}
}
package cn.sf.adapter;
public class Adapter extends Adaptee implements Target {
//Adapte:对Adaptee的接口与Target接口进行适配
@Override
public void Request() {
// TODO Auto-generated method stub
System.out.println("这是适配器接口");
super.specificRequest();
}
}
package cn.sf.adapter;
public class Client {
public static void main(String[] args) {
// 调用适配器接口
Target adapter = new Adapter();
adapter.Request();
}
}
类适配器与对象适配器讨论
- 类适配器使用继承的方式,对象适配器使用组合的方式
- 类适配器可以重定义adaptee的部分行为,而对象适配器仅仅是委托adaptee完成
- 类适配器仅能适配adaptee和target,无法适配adaptee的子类,而对象适配器可以
总结
意图:将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作.
使用场合:
- 使用一个已经存在的类,而他的接口不符合要求
- 创建一个可以复用的类,该类可以与其他不相关的类或不可预见(接口可能不一定兼容的)的类协同工作
- 使用一些已经存在的子类,但不可能通过子类匹配各自的接口.对象适配器可以适配他的父类接口
适配器分为类适配器和对象适配器
优点:方便设计者自定义接口,不用担心匹配问题
缺点:属于静态结构,由于只能单继承,所以不适用与多种不同的源适配到同一个目标