一、定义
将一个已有的接口转换成客户希望的另外一个接口。
我的理解:让一个实现了A接口的类,可以用到接收B接口的方法上,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
下面类图是对象适配与类的适配。对象的适配是构造函数接受对象,类的适配是适配器类直接实现想要的接口。
二、完全解耦
如果某个方法的参数是一个"类"的引用,而不是一个"接口"的引用的话,那么显而易见,我们传递的参数必须是这个类的对象或者是这个类的子类对象。比如下面的抽象类Teacher,在ClassRoom中接收的是一个Teacher类的引用,我们只能传递Teacher类的子类对象。这样做的一点不好之处在于,此方法限制了这个参数必须在Teacher类的继承体系当中的。
public abstract class Teacher {
public abstract void teach();
}
class ClassRoom {
public void beginClass(Teacher teacher) {
teacher.teach();
}
}
如果哪一天,我们请程序员叔叔也来现场演示一下代码,但是我们的程序员叔叔并不是教师。问题就出现了,程序员不能直接应用到ClassRoom的beginClass(Teacher teacher)方法上,因为UncleProgrammer类不是Teacher类的子类。但是如果Teacher是一个接口,那么情况就有所改变。
public interface Teacher {
void teach();
}
interface Coder{
/**
* 演示代码
*/
void showCode();
}
//程序员叔叔类,实现Coder接口
class UncleProgrammer implements Coder{
@Override
public void showCode() {
System.out.println("程序员叔叔演示代码");
}
}
/**
* 教师适配器
* 接收你所拥有的Coder接口实现类,产生你所需要的Teacher接口
*/
class TeacherAdapter implements Teacher{
private Coder coder;
public TeacherAdapter(Coder coder) {
this.coder = coder;
}
@Override
public void teach() {
coder.showCode();
}
}
//客户端使用环境
class ClassRoom {
public void beginClass(Teacher teacher) {
teacher.teach();
}
public static void main(String[] args) {
//有一间教室
ClassRoom classRoom = new ClassRoom();
//有个程序员叔叔
Coder uncle = new UncleProgrammer();
//创建教师适配器,接收你所拥有的接口实现类对象
TeacherAdapter adapter = new TeacherAdapter(uncle);
classRoom.beginClass(adapter);//运行结果:程序员叔叔演示代码
}
}
适配器能够让不同接口之间的方法可以相互使用。使用接口最大的好处在于“完全解耦”,不管是哪些接口,都能做出相关联的适配器,而如果是继承体系的话,就限制死了接收参数要在继承体系中。这也是面向接口编程最大的好处吧。
三、心法总结
适配器模式的终极目标:保留住现有的类,这就体现出适配器模式的代码复用性。
适配器的口诀:接收拥有的接口(实现类),产生需要的接口(实现类)。
适配器模式的优点:
1.提升代码的复用性,能够保留住现有的类,就是代码复用性最好的体现。在我这个例子中,复用了程序员叔叔类的代码。
2.让目标类与被适配的类完全的解耦。从类图也能看出来,目标类只与适配者有接触。
缺点:如果系统里面的适配器比较多,系统会显得很凌乱,不好维护
最经典的适配:Spirng中把Advice通知体系适配成Web体系中的拦截器体系中。
四、使用场景
1.系统需要使用现有的类,但是现有类的接口不符合系统的接口。
2.两个类所做的事情相似,但是有不同的接口。A实现类与B实现类干的活很像,但是方法接收B接口实现类,恰好A实现类干的就是B接口需要做的事情。那么做一个适配器,接收A接口的实现类,并且实现B接口。
3.旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候。
刻意练习
(1)适配器模式的定义
(2)适配器模式的类图
(3)优缺点
(4)使用场景
(5)实例代码
分割线--------------------------------------------------------------------------------------------
下一篇:装饰者设计模式5