• 设计模式之适配器模式


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

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

    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接口的调用,如果一个系统中出现太多这种情况,无异于一场灾难。因此,如果不是很有比较,不建议使用适配器模式,而是直接对系统进行重构。

  • 相关阅读:
    ip代理投票
    linq小笔记;
    c#类的执行顺序
    IEnumerable、GetEnumerator、IEnumerator的理解
    English随笔1
    AudioServicesPlaySystemSound音频服务—IOS开发
    iOS开发之压缩与解压文件
    xcode添加Cocos2d
    使用CoreTelephony获得SIM卡网络运营商名称
    iOS设备进行定位?
  • 原文地址:https://www.cnblogs.com/lixiuyu/p/5913885.html
Copyright © 2020-2023  润新知