适配器模式
通常情况下,客户端可以通过目标类的接口访问它所提供的服务。有时现有的类可以满足客户类的功能需求,但是它所提供的接口不一定是客户类所期望的,这可能是因为现有类中的方法名与目标类中定义的方法名不一致等原因所导致的。这种情况下,现有的接口需要转化为客户类期望的接口,这样就保证了对现有类的重用。适配器模式可以完成这样的转化。
适配器模式:将一个接口转换成用户希望的另一个接口。适配器模式使接口不兼容的那些类可以一起工作,别名为包装器(Wrapper)。适配器模式既可作为类结构型模式,也可作为对象结构型模式。
UML
- Target:抽象目标,定义客户要用的的特定领域的接口。
- Adaptee:适配者,需要适配的接口
- ClassAdapter:适配器。把源接口转换成目标接口,分为类适配器和对象适配器
- Client:客户,针对目标类进行程序设计,调用再部门类中定义的业务方法。
示例代码
interface Target{
public void request();
}
// 适配者
class Adaptee{
public void specificRequest(){
System.out.println("this is adaptee's specificRequest.");
}
}
// 类适配器
class ClassAdapter extends Adaptee implements Target{
public void reqeust(){
System.out.println("this is ClassAdapter's reqeust.");
super.specificRequest();
}
}
// 对象适配器
class ObjectAdapter implements Target{
private Adaptee adaptee = new Adaptee();
public void reqeust(){
System.out.println("this is ObjectAdapter's reqeust.");
adaptee.specificRequest();
}
}
class Client{
private Target target;
public void setTarget(Target t){
this.target = t;
}
public void opertion(){
target.request();
// 其他业务逻辑
}
}
class Test{
public static void main(String args[]){
Client c = new Client();
// 测试类适配器
c.setTarget(new ClassAdapter());
c.opertion();
// 测试对象适配器
c.setTarget(new ObjectAdapter());
c.opertion();
}
}
说明
在类适配器模式中,适配器类实现了目标抽象类接口并继承了适配者类,并在目标抽象类的实现方法中调用所继承的适配者类的方法;在对象适配器中,适配器类继承了目标抽象类并定义了一个适配者类的对象实例,在所继承的目标抽象类方法中调用适配者类的相应业务方法。
优点
将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无需修改原有代码。增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。
缺点
类适配器模式的适配器类在很多编程语言中不能同时适配多个适配者类,对象适配器模式很难置换适配者类的方法。
使用场景
,而且提高了适配者的复用性。
缺点
类适配器模式的适配器类在很多编程语言中不能同时适配多个适配者类,对象适配器模式很难置换适配者类的方法。
使用场景
系统需要使用现有的类,而这些类的接口不符合系统的需要。想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的类,包括一些可能在将来引进的类一起工作。