设计模式之适配器模式

适配器模式将某各类的接口转换成客户端期望的另一个接口表示,目的是为了消除由于接口不匹配所造成的类的兼容性问题。

适配器模式涉及的角色有:

1.目标角色(target)

这是期望得到的接口。

2.源角色(Adaptee)

现在需要适配的接口。

3.适配器角色(Adapter)

适配器类,这是适配器模式的核心,负责把源接口转换为目标接口。

 

具体来说,适配器模式分为三类,分别是类的适配器模式、对象的适配器模式和接口的适配器模式。

下面一一介绍

一.类的适配器模式

类的适配器模式把适配的类的API转换为目标类的API

UML图如下:

示例代码如下:

1 public interface Target {
2     public void method1();
3     public void method2();
4 }
1 public class Adaptee {
2 
3     public void method(){
4         System.out.println("source method.");
5     }
6 
7 }

下面是适配器模式的核心类Adapter:

 1 public class Adapter extends Adaptee implements Target {
 2 
 3     @Override
 4     public void method1() {
 5         //这样,待适配类的method()方法就适配成了目标类的method1()
 6         super.method();
 7     }
 8 
 9     @Override
10     public void method2() {
11         System.out.println("target method");
12     }
13 
14 }

下面是测试类:

1 public class AdapterTest {
2     public static void main(String[] args) {
3         Target adapter = new Adapter();
4         adapter.method1();
5         adapter.method2();
6     }
7 }

测试结果如下:

 

二.对象的适配器模式

与类的适配器模式相比,对象的适配器模式不是使用多继承或继承再实现的方式,而是使用直接关联,或者称为委托的方式。

UML图如下:

 

从UML图可以看出与类的适配器模式相比,对象的适配器模式是在Adapter类中添加了一个对Adaptee的引用。使用对象适配器模式,可以使得 Adapter 类(适配类)根据传入的 Adaptee 对象达到适配多个不同被适配类的功能。

示例代码如下:

1 public interface Target {
2     public void method1();
3     public void method2();
4 }
1 public class Adaptee {
2 
3     public void method(){
4         System.out.println("source method.");
5     }
6 
7 }

 

下面是对象的适配器模式的核心类Adapter:

 1 public class Adapter implements Target {
 2     private Adaptee adaptee;
 3 
 4     public Adapter(Adaptee adaptee) {
 5         this.adaptee = adaptee;
 6     }
 7 
 8     @Override
 9     public void method1() {
10         adaptee.method();
11     }
12 
13     @Override
14     public void method2() {
15         System.out.println("target method");
16     }
17 
18 }

 测试类如下:

1 public class AdapterTest {
2     public static void main(String[] args) {
3         Target adapter = new Adapter(new Adaptee());
4         adapter.method1();
5         adapter.method2();
6     }
7 }

 

运行结果如下:

可以看出,输入的结果与类的适配器模式相同,只是适配的方式不同而已。

三.接口的适配器模式

接口的适配器模式是这样的:有时我们写的一个接口中有多个抽象方法,当我们写该接口的实现类时必须实现该接口的所有方法,这显然比较浪费,因为并不是所有的方法都是我们需要的,有时可能我们只需要某一些。为了解决这个问题,我们借助于一个抽象类,该抽象类实现了接口,实现了所有的方法,而我们不与原始的接口打交道,只和该抽象类有联系。这就是接口的适配器模式。

代码入下:

1 public interface Source {
2     public void method1();
3     public void method2();
4 }
1 //定义抽象类并实现Source接口的所有方法
2 public abstract class Wrapper implements Source{
3     @Override
4     public void method1() {}
5 
6     @Override
7     public void method2() {}
8 }
1 public class SourceSub1 extends Wrapper {
2     @Override
3     public void method1() {
4         System.out.println("the Source interface's first Sub1!");
5     }
6 }
1 public class SourceSub2 extends Wrapper {
2     @Override
3     public void method2() {
4         System.out.println("the Source interface's first Sub2!");
5     }
6 }

 

下面给出测试类:

 1 public class SourceTest {
 2     public static void main(String[] args) {
 3         Source source1 = new SourceSub1();
 4         Source source2 = new SourceSub2();
 5 
 6         source1.method1();
 7         source1.method2();
 8 
 9         source2.method1();
10         source2.method2();
11     }
12 }

运行结果如下:

 

总结:

1.适配器模式的优点:

(1)更好的复用性

系统需要使用现有的类,而此类的接口不符合系统的需要,那么通过使用适配器模式可以使这些功能得到更好的复用。

(2)更好的扩展性

在实现适配器的功能时,可以调用自己开发的功能,从而扩展系统的功能。

2.适配器模式的缺点:

过多的使用适配器会让系统变得零乱,不易整体进行把握。例如,我们明明看到调用的是A的接口,然而内部却被适配成了B接口的调用,如果一个系统中出现太多这种情况,无异于一场灾难。因此,如果不是很有比较,不建议使用适配器模式,而是直接对系统进行重构。

 

posted @ 2016-09-28 11:08  GloryLee  阅读(508)  评论(0编辑  收藏  举报