适配器模式
我的理解:
- 就是原有的类(Adaptee),现在需要实现一个接口(Target)【他们的方法名称数量都有不同】。于是在不改动Adaptee情况下就要使用适配器模式了。
- 这个适配器类,就是对外展示的是接口Target定义的方法,对内【实现】就随便了(直接调用原类方法,增加,重用方法都行)。
- 其中对象适配模式,与中介,装饰模式有些类似,不过适配器在于接口转接。
2016年4月
定义:
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
类型:结构型模式
类图:
类适配器模式,既适配器同时继承原类与接口类。
对象适配器模式,既适配器包含原类的引用,并实现接口即可。
模式角色:
- 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
- 需要适配的类(Adaptee):需要适配的类或适配者类。
- 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。
实现种类:
1) 类适配器
当客户在接口中定义了他期望的行为时,我们就可以应用适配器模式,提供一个实现该接口的类,并且扩展已有的类,通过创建子类来实现适配。
2)对象适配器
对象适配器通过组合除了满足"用户期待的接口"还降低了代码间的不良耦合。
3)缺省适配器
缺省适配器模式是一种特殊的适配器模式,但这个适配器是由一个抽象类实现的,并且在抽象类中要实现目标接口中所规定的所有方法,但很多方法的实现都是空方法,而具体的子类都要继承此抽象类。
当客户在接口中定义了他期望的行为时,我们就可以应用适配器模式,提供一个实现该接口的类,并且扩展已有的类,通过创建子类来实现适配。
2)对象适配器
对象适配器通过组合除了满足"用户期待的接口"还降低了代码间的不良耦合。
3)缺省适配器
缺省适配器模式是一种特殊的适配器模式,但这个适配器是由一个抽象类实现的,并且在抽象类中要实现目标接口中所规定的所有方法,但很多方法的实现都是空方法,而具体的子类都要继承此抽象类。
PS:
- 过多的使用适配器,会让系统非常零乱,不易整体进行把握
- 如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
- 在任何时候,如果不准备实现一个接口的所有方法时,就可以使用“缺省适配模式”制造一个抽象类,给出所有方法的平庸的具体实现。这样,从这个抽象类再继承下去的子类就不必实现所有的方法了。
实例:
缺省适配器:
public interface AbstractService {
public void serviceOperation1();
public int serviceOperation2();
public String serviceOperation3();
}
public class ServiceAdapter implements AbstractService{
@Override
public void serviceOperation1() {
}
@Override
public int serviceOperation2() {
return 0;
}
@Override
public String serviceOperation3() {
return null;
}
}
接口AbstractService要求定义三个方法,分别是
serviceOperation1
()、
serviceOperation2()、serviceOperation3();而抽象适配器类ServiceAdapter则为这三种方法都提供了平庸的实现。因此,任何继承自抽象类ServiceAdapter的具体类都可以选择它所需要的方法实现,而不必理会其他的不需要的方法。
对象适配器:
public interface Target {
/**
* 这是源类Adaptee也有的方法
*/
public void sampleOperation1();
/**
* 这是源类Adapteee没有的方法
*/
public void sampleOperation2();
}
public class Adaptee {
public void sampleOperation1(){}
}
public class Adapter {
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
/**
* 源类Adaptee有方法sampleOperation1
* 因此适配器类直接委派即可
*/
public void sampleOperation1(){
this.adaptee.sampleOperation1();
}
/**
* 源类Adaptee没有方法sampleOperation2
* 因此由适配器类需要补充此方法
*/
public void sampleOperation2(){
//写相关的代码
}
}
类适配器:
public interface Target {
/**
* 这是源类Adaptee也有的方法
*/
public void sampleOperation1();
/**
* 这是源类Adapteee没有的方法
*/
public void sampleOperation2();
}
public class Adaptee {
public void sampleOperation1(){}
}
public class Adapter extends Adaptee implements Target {
/**
* 由于源类Adaptee没有方法sampleOperation2()
* 因此适配器补充上这个方法
*/
@Override
public void sampleOperation2() {
//写相关的代码
}
}