一、类的适配器模式
1,UML图
目标(Target)角色:这就是所期待得到的接口。注意,由于这里讨论的是类适配器模式,因此目标不可以是类。
源(Adaptee)角色:现有需要适配的接口。
适配器(Adapter)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口中。显然,这一角色不可以是接口中,而必须是具体类。
2, 模式说明
适配器类是源的子类,因此可以在适配器类中置换掉(Override)源的一些方法;
只引进了一个适配器类,因此只有一个路线到达目标类,使问题得到简化。
3,模式示例代码
package com.maohao.struct.adapter;
public interface Target {
public void sampleOperation1();
public void sampleOperation2();
}
package com.maohao.struct.adapter;
public class Adaptee {
public void sampleOperation1(){
}
}
package com.maohao.struct.adapter;
public class Adapter extends Adaptee implements Target {
@Override
public void sampleOperation2() {
// TODO Auto-generated method stub
System.out.println("i am an adapter");
}
}
二、对象的适配器模式
1,UML图
目标(Target)角色:这就是所期待的接口,目标可以是具体的或抽象的类;
源(Adaptee)角色:现在需要适配的接口;
适配器(Adapter)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口,显然,这一角色必须是具体类。
2, 模式说明
适配器模式的用意是将接口中不同而功能相同或者相近的两个接口加以转换,这里面包括适配器角色
补充了一个源角色没有的方法,但是目标接口需要的方法。读者不要误以为适配器模式就是为补充源角色没有的方法而准备的。
对象的适配器模式效果:
(1)一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口;
(2)与类的适配器模式相比,要想置换源类的方法就不容易。如果一定要置换掉源类的一个或多个方法,就只好先做一个源类的子类,将源类的方法置换掉,然后再把源类的子类当做真正的源进行适配。
(3)虽然要想置换源类的方法不容易,但是要想增加一些新的方法则方便得很,而且新增加的方法可同时适用于所有源。
3,模式示例代码
package com.maohao.struct.adapter;
public class Adapter2 implements Target {
public Adaptee adaptee;
public Adapter2(Adaptee adaptee) {
super();
this.adaptee = adaptee;
}
@Override
public void sampleOperation2() {
// TODO Auto-generated method stub
System.out.println("i am a happy adapter");
}
@Override
public void sampleOperation1() {
// TODO Auto-generated method stub
adaptee.sampleOperation1();
}
}
4,模式说明
(1)系统需要使用现有的类,而此类的接口不符合系统的需要;
(2)想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。这些源不一定有很复杂的接口。
(3)(对对象的适配器模式而言)在设计里,需要改变多个已有的子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器类,而这个不太实际。
5,与其他模式比较
桥梁模式:在用意和应用上不同,桥梁模式的用意是把实现和它的接口分开,以便它们独立地变化。桥梁模式并不是用来把一个已有的对象接到不相匹配的接口上的。当一个客户端只知道一个特定的接口,但是又必须与具有不同接口的类打交道时,就应当使用适配器模式。
装饰模式:装饰类不能改它所装饰的Component对象的接口
6,模式应用
Iterator到Enumeration的适配、Enumeration到Iterator的适配、JDBC(每一个数据库引擎的JDBC驱动软件
都是一个介于JDBC接口和数据库引擎接口之间的适配器软件)