一、概述:
适配器模式,结构型模式之一。
(1)结构型模式:关注如何将现有类或对象组织在一起形成更强大的结构。结构型模式分为:类结构型模式和对象结构型模式。而适配器模式,既是类结构模式又是对象结构模式。
(2)适配器模式:将一个类的接口转换成客户希望的另一个接口,让那些接口不兼容的类可以一起工作。
二、结构与实现
- 结构
(1)Target(目标抽象类):目标抽象类定义客户所需的接口。
(2)Adapter(适配器类):它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配。在类适配器中,它通过实现Target接口并继承Adaptee来使两者产生联系,而在对象适配器中,它通过继承Target并关联一个Adaptee对象使两者产生联系。
(3)Adaptee(适配者类):被适配的角色,一般是一个具体类,包含了客户希望使用的业务方法。
- 实现
(1)类适配器:
实现目标抽象类,继承适配者类。覆写Target类中的request方法,将其转化为客户希望的方法,即调用父类(适配者类)的specificRequest()方法。
public class Adapter extends Adaptee implements Target{
public void request(){
super.specificRequest();
}
}
(2)对象适配器:
继承Target,关联适配者类(类似一个属性或者成员变量,只是这个变量是对象引用类型),重写request方法,方法内,适配者变量调用specificRequest()方法。
public class Adapter extends Target{
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee=adaptee;
}
public void request(){
adaptee.specificRequest();
}
}
- 注意
根据合成复用原则,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式,在实际开发中,对象适配器的使用频率更高。
三、应用实例
- 例题:
- 对应的类图:
- 代码实现:
(1)Target类(CarController):
public abstract class CarController {
public void move(){
System.out.println("玩具车移动ing...");
}
public abstract void shine();
public abstract void sound();
}
(2)Adapter类(Adapter):
public class Adapter extends CarController{
//关联两个具体的适配者
private ShineAdaptee shineAdaptee;
private SoundAdaptee soundAdaptee;
//当适配器初始化时,创建两个具体适配者
public Adapter() {
shineAdaptee=new ShineAdaptee();
soundAdaptee=new SoundAdaptee();
}
@Override
public void shine() {
shineAdaptee.policeShine();
}
@Override
public void sound() {
soundAdaptee.policeSound();;
}
}
(3)Adaptee类(ShineAdapter,SoundAdapter):
public class ShineAdaptee {
public void policeShine(){
System.out.println("警灯闪烁...");
}
}
public class SoundAdaptee {
public void policeSound(){
System.out.println("警笛音效...");
}
}
(4)Client(Client):
public class Client {
public static void main(String[] args) {
CarController car=(CarController)new Adapter();
car.move();
car.sound();
car.shine();
}
}
(5)运行测试:
四、扩展
- 缺省适配器模式(单接口适配器模式)
当不需要实现一个接口提供的所有方法时,可先设计一个抽象类实现该接口,并提供默认的实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适用于不想使用一个接口中的所有方法的情况。
public abstract class AbstarctService implements SeInterface{
//空方法进行实现
public void method1(){}
public void method2(){}
public void method3(){}
}
最后继承这个抽象类的子类就可以选择性地重写自己需要的方法。
2. 双向适配器
在适配器同时包含对目标类和适配者类的引用,适配者可以通过它调用目标类中的方法,目标类也可以通过它调用适配者类中的方法,那么这个适配器就是一个双向适配器。
public class Adapter implements Target,Adaptee{
private Adaptee ad;
private Target ta;
public Adapter(Adaptee ad){
this.ad=ad;
}
public Adapter(Target ta){
this.ta=ta;
}
public void request(){
ad.specificRequest();
}
public void SpecificRequest(){
ta.request();
}
}
五、总结
(1)适配器,结构型模式之一,既是类结构型模式又是对象结构型模式。
(2)类适配器:实现Target接口,继承Adaptee类,重写接口中的方法,方法内调用父类Adaptee的方法。
(3)对象适配器:继承Target并与Adaptee进行关联,使Target与Adaptee在适配器中产生关联。
适用情况:
(1)需要将现有接口转化为客户类所期望的接口,实现对现有类的复用。
(2)系统需要使用一些现有类,但这些类的接口不符合系统的需要。
(3)想创建一个可以重复使用的类,用于与一些彼此之间没有太大关联的类一起工作。