java-设计模式(结构型)-【适配器模式】
1.适配器(Adapter Mode)
定义:将两个不兼容的类纠合在一起使用,属于结构型模式,需要有Adaptee(被适配者)和Adapter(适配器)两个身份
目的是消除由于接口不匹配所造成的类的兼容性问题。
我们经常碰到需要将两个没有关系的类组合在一起使用,第一种方法是,修改各自的接口,但是违背了开闭原则
第二种方法是,使用Adapter,在两种接口之间创建一个混合接口(混血儿)。
分类:类的适配器模式、对象的适配器模式、接口的适配器模式
三个角色:
- 目标角色(Traget:interface):期待得到的接口
- 源(Adapee)角色:现在需要适配的接口
- 适配器(Adapter:class)角色:必须是具体类
1.1 类的适配器模式:继承的方式适配
1.1.1 图解

1.1.2 三个角色
//待适配的源
public class Source {
//方法一:
public void method1()
{
System.out.println("source:method1方法");
}
}
//需要实现的接口
interface Targetable
{
void method1();
//方法二
void method2();
}
//以类继承的方式进行适配
class Adapter extends Source implements Targetable
{
//继承了方法一
//重写方法二:
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("Targetable:method2方法");
}
}
1.1.3 测试
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
//使用Target接口里定义的方法,不需要"Adapter ad"
Targetable ad=new Adapter();
System.out.println("adapter-----");
ad.method1();
ad.method2();
Targetable wp=new Wrapper(new Source());
System.out.println("wrapper-----");
wp.method1();
wp.method2();
}
}
1.1.4 运行结果
adapter----- source:method1方法 Targetable:method2方法 wrapper----- source:method1方法 Targetable:method2方法
1.2 对象适配器:组合的方式适配
1.2.1 图解

1.2.2 代码
public class Source {
public void method1()
{
System.out.println("source:method1方法");
}
}
interface Targetable
{
void method1();
void method2();
}
class Wrapper implements Targetable
{
//组合的方式适配
private Source s=null;
public Wrapper(Source s)
{
this.s=s;
}
@Override
public void method1() {
// TODO Auto-generated method stub
s.method1();
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("Targetable:method2方法");
}
}
1.3 两者方式的对比
- 类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式。
- 对象适配器:一个适配器可以把多种不同的源(以多态形式:将子类传入)适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。
- 因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓。
- 类适配器:由于适配器直接继承了Adaptee,使得适配器不能和Adaptee的子类一起工作,因为继承是静态的关系,
- 当适配器继承了Adaptee后,就不可能再去处理 Adaptee的子类了。
- 类适配器:适配器可以重定义Adaptee的部分行为,相当于子类覆盖父类的部分实现方法。
- 对象适配器:要重定义Adaptee的行为比较困难,这种情况下,可以通过定义Adaptee的子类来实现重定义,然后让适配器组合子类。
- 虽然重定义Adaptee的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源。
建议尽量使用对象适配器的实现方式,多用合成/聚合、少用继承。当然,具体问题具体分析,根据需要来选用实现方式,最适合的才是最好的。
1.4 接口适配器:对接口的部分方法用抽象类抽出来实现使用

1.4.1 代码
//接口:待适配中
interface Targetable
{
void method1();
void method2();
}
//抽象类:中间层,让子接口无需实现父接口的所有未实现方法,有选择的实现自己要实现的方法
abstract class Wrapper2 implements Targetable
{
public void method1(){}
public void method2(){}
}
//只实现方法1
class SourceSub1 extends Wrapper2
{
public void method1()
{
System.out.println("SourceSub1:method1");
}
}
//只实现方法2
class SourceSub2 extends Wrapper2
{
public void method2()
{
System.out.println("SourceSub2:method2");
}
}
1.4.2 测试
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
//使用Target接口里定义的方法,不需要"Adapter ad"
Targetable s1=new SourceSub1();
Targetable s2=new SourceSub2();
//S1:只实现方法1
s1.method1();
s1.method2();
//S2:只实现方法2
s2.method1();
s2.method2();
}
}
1.4.3 运行结果
SourceSub1:method1 SourceSub2:method2
1.5 适配器的优点
- 更好的复用性
系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
- 更好的扩展性
在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。

浙公网安备 33010602011771号