设计模式学习 - 适配器模式

适配器模式简介

定义

适配器模式又称之包装模式,将一个类的接口转换成用户所希望的接口,可以使原本两个不相互兼容的类在一起工作。
可以通俗理解为,适配器模式就是把目标理想变成现实的。

UML类结构图

适配器模式分为类适配器模式和对象适配器模式,两者的UML类图有点细微的区别。

类适配器模式
这里写图片描述

对象适配模式
这里写图片描述

从上图可以看出,类适配模式与对象适配器区别主要体现在Adapter与Adaptee的关系不同。

  • 类适配器模式:是通过继承关系把Adaptee与Adapter连接到一起。
  • 对象适配器模式:是以委托代理的方式连接到一起,用户通过对象传递的方式进行关联。

角色介绍:

  • Target:目标角色,用户理想中的接口,这里目标接口是YaoMing
  • Adaptee:被适配的类,实现情况下的接口,这里被适配的类是JiaoLian
  • Adapter:适配转换器,是理想目标实现的方式,是一个具体类,是整个适配器模式的核心。

下面通过简单的例子,再结合UML图就能够很好的理解适配器模式是什么样子。

适配器模式的简单实现

据说,姚明刚刚去NBA打球时,有记者采访姚明说:“在CBA和NBA最大的区别是什么?”,姚明的答案是“在NBA我需要翻译,而在CBA我不需要”,可见姚明刚开始是不懂外语的,在比赛中,怎样听懂明白教练的战术安排,此时就需要找到一个中间人进行翻译,把教练的话翻译成中文,姚明就可以听懂了。

  • 姚明希望听到的是中文,就是Target目标接口
  • 实际上教练讲的是英文,就是被适配Adaotee类。
  • 中间人翻译,把英文翻译成中文的过程,就是Adapter类

代码实现

1、创建用户希望的目标YaoMing接口,姚明希望能听到中文。

/**
 * 
 * @author 13480
 * 目标类(用户所期待的样子),
 * 姚明希望听到是中文话。
 */
public interface YaoMing {

    String getChinese();

}

2、创建一个需被适配的类Adaptee。

/**
 * 
 * @author 13480
 * Adaptee类,需要被适配的类
 * 需要教练本身讲的是英文,姚明听不懂,这时教练说的话就要被翻译成中文,姚明才能听懂,这就是被适配的类
 */
public class JiaoLian {

    //教练战术安排,要求姚明加强防守
    public String english(){
        return "Yao Ming strengthens defense";
    }
}

3、创建中间翻译人Adapter,这里分成类适配器模式和对象适配器模式进行对比

(1)类适配器模式的Adapter

public class TranslatorAdapter extends JiaoLian implements YaoMing{

    @Override
    public String getChinese() {
        String english = english();
        System.out.println("JiaoLian:"+english);
        //中间省略……翻译过程 english --> chinese
        String chinese="姚明加强防守";
        return chinese;
    }

}

(2)对象适配器模式的Adapter

public class TranslatorAdapter2  implements YaoMing{

    private JiaoLian mJiaoLian;

    public void setJiaoLian(JiaoLian mJiaoLian) {
        this.mJiaoLian = mJiaoLian;
    }

    @Override
    public String getChinese() {
        String english = mJiaoLian.english();
        System.out.println("JiaoLian:"+english);
        //中间省略……翻译过程 english --> chinese
        String chinese="姚明加强防守";
        return chinese;
    }

}

4、用户端使用

public class AdapterTest {

    public static void main(String[] args) {
        //类适配器模式使用
        TranslatorAdapter translatorAdapter = new TranslatorAdapter();
        System.out.println("翻译的结果:"+translatorAdapter.getChinese());

        //对象适配器模式使用
        JiaoLian jiaoLian = new JiaoLian();
        TranslatorAdapter2 translatorAdapter2 = new TranslatorAdapter2();
        translatorAdapter2.setJiaoLian(jiaoLian);
        System.out.println("翻译的结果:"+translatorAdapter2.getChinese());
    }

}

输出结果:

JiaoLian:Yao Ming strengthens defense
翻译的结果:姚明加强防守

从实现中可以看出,对象适配器是对象传递来实现关联的,因此可以适配多个对象,而类适配器则是通过继承来关联的,由于java中只能单继承,所以无法做到动态修改,只能适配一个类;除此之外,适配器类由于继承于被适配器类,会把被适配类的属性方法暴露出来,会造成潜在使用安全问题。因此开发中更多的是选择对象适配器方式实现,更灵活又安全。

使用场景

  • 往往在项目后期维护中,旧接口不太符合新需求的要求,而又不想创建新对象来实现,想复用旧接口,此时可以用适配器模式进行包装。
  • 需要一个统一的输出接口,而用户端输入又是一个未知的类型。在Android最典型的就是ListView的适配器,适配器暴露getView接口,来满足用户各种各样的样式布局。

猜你喜欢

转载自blog.csdn.net/hzw2017/article/details/80789127