适配器模式/Adapter
意图/适用场景:
适配器模式用于对已有代码的重用。
如果客户端需要某一种接口(Target)的实现类,但系统中并没有一模一样的类。系统中已有的某种接口或者类(Adaptee)与所要求的接口(Target)有相同或相近的功能,只需要改变接口名或稍做一些修改就可以重用。
适配器模式正适合做这种重用。
适配器模式分为“类适配模式”和“对象适配模式”两种,下面分别描述。
类适配器模式/Class Adapter
UML:
参与者:
- 目标(Target)接口:客户端所需要的接口。
- 源(Adaptee)接口/类:已有的类,需要被适配。
- 适配器(Adapter)类:适配器模式的核心,用于把源接口转换为目标接口。
要点:
- 目标(Target)必须是一个接口,不能是类。这是因为Adapter需要继承Adaptee,而Java语言只支持单继承,所以Target只能是接口,Adapter实现它。
- Adapter与Adaptee之间是继承关系。
- UML示例中,三个角色都有一个相同名字的方法operation1(),而且这个方法的行为也正是客户端所需要的,这是最简单的情况,Adaptee的方法被重用。
- Adaptee中也可以不存在operation1()方法,即不存在能直接复用的方法。这种情况下,Adapter需要实现operation1()方法。
对象适配器模式/Object Adapter
UML:
参与者:
- 目标(Target)接口:客户端所需要的接口或者类。
- 源(Adaptee)接口/类:已有的接口/类,需要被适配。
- 适配器(Adapter)类:适配器模式的核心,用于把源接口转换为目标接口。
要点:
- Target可以是接口,也可以是类。因为Adapter不再继承Adaptee,Java只支持单继承。可以选择让Adapter继承Target。
- Adapter并不继承Adaptee,但Adapter对象中含有Adaptee对象的引用。即它们之间是聚合关系,Adaptee对象构成Adapter对象的一部分。
- Adapter通过对Adaptee对象的方法调用来实现Target所要求的接口功能。
示例代码:
[java]
// Source code from file:Adaptee.java
packagedesignPatterns.Adapter;
publicclass Adaptee {
publicvoid operation1() {
System.out.println("operation1() in Adaptee");
}
}
// Source code from file:ClassAdapter.java
packagedesignPatterns.Adapter;
publicclass ClassAdapter extends Adaptee implements Target {
publicvoid operation2() {
System.out.println("operation2() in ClassAdapter");
}
}
// Source code from file:ObjectAdapter.java
packagedesignPatterns.Adapter;
publicclass ObjectAdapter implements Target {
privateAdaptee adaptee = null;
publicObjectAdapter() {
adaptee =new Adaptee();
}
publicvoid operation1() {
System.out.println("operation1() in ClassAdapter");
adaptee.operation1();
}
publicvoid operation2() {
System.out.println("operation2() in ClassAdapter");
}
}
// Source code from file:Target.java
packagedesignPatterns.Adapter;
publicinterface Target {
publicvoid operation1();
publicvoid operation2();
}
// Source code from file:User.java
packagedesignPatterns.Adapter;
publicclass User {
publicstatic void main(String [] args) {
Target t =null;
// test for Class Adapter
t =new ClassAdapter();
t.operation1();
t.operation2();
// test for Object Adapter
t =new ObjectAdapter();
t.operation1();
t.operation2();
}
}
[/java]