找回密码
 立即注册
首页 业界区 安全 13.结构型 - 适配器模式 (Adapter Pattern)

13.结构型 - 适配器模式 (Adapter Pattern)

郦惠 昨天 22:45
适配器模式 (Adapter Pattern)

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁
意图: 将一个类的接口转换成客户希望的另外一个接口; 适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作;
主要解决: 主要解决在软件系统中, 常常要将一些"现存的对象"放到新的环境中, 而新环境要求的接口是现对象不能满足的;
代码实例

例: 一个生活中的例子, 家里有一台空调,  现有一个三口的插座, 空调使用三口插座, 完美匹配;
倘若再买一台TV电视, 使用二口插座, 如何解决这个问题?
UML类图

1.png

1.三线 设备及实现
  1. //三口插头
  2. public interface TriplePin {
  3.     //参数分别为火线live, 零线null, 地线earth
  4.     public void electrify(int l, int n, int e);
  5. }
  6. // 空调
  7. public class AirConditioning implements TriplePin {
  8.    @Override
  9.    public void electrify(int l, int n, int e) {
  10.       System.out.println("火线接通: " + l);
  11.       System.out.println("零线接通: " + n);
  12.           System.out.println("地线接通: " + e);
  13.    }
  14. }
复制代码
2.二线 设备及实现
  1. //二口插头
  2. public interface DualPin {
  3.     public void electrify(int l, int n);//这里没有地线
  4. }
  5. // 电视
  6. public class TV implements DualPin {
  7.    @Override
  8.    public void electrify(int l, int n) {
  9.       System.out.println("火线接通: " + l);
  10.       System.out.println("零线接通: " + n);
  11.    }
  12. }
复制代码
3.使用者
  1. // 我是一个固执的电源, 只给三线设备的供电
  2. public class Power {
  3.    @Override
  4.    public void ConnectElectricity(TriplePin pin) {
  5.       int l = 1, n = 0, e = -1;
  6.           pin.electrify( l,  n,  e);
  7.    }
  8. }
复制代码
4.适配实现

有两种实现方式

  • 类适配器: 继承实现
  • 对象适配器: 组合实现
推荐使用组合的方式优于继承方式
4.1.对象适配器(组合实现)
  1. public class TriplePinAdapter implements TriplePin {
  2.    private DualPin dualPinDevice;
  3.    //创建适配器的时候, 需要把双插设备接入进来
  4.    public TriplePinAdapter(DualPin dualPinDevice) {
  5.       this.dualPinDevice = dualPinDevice;
  6.    }
  7.    //适配器实现 目标接口(三线)
  8.    @Override
  9.    public void electrify(int l, int n, int e) {
  10.       //实际上调用了被适配设备的双插通电, 地线e被丢弃了;
  11.       dualPinDevice.electrify(l, n);
  12.    }
  13. }
复制代码
4.2.对象适配器(继承的方式)
  1. //继承二线设备, 实现三线设备接口
  2. public class TriplePinAdapter extends TV implements TriplePin{
  3.    @Override
  4.    public void electrify(int l, int n, int e) {
  5.       super.electrify(l, n);
  6.    }
  7. }
复制代码
5.测试
  1. public static void main(String[] args) {
  2.          Power power = new Power();//固执的电源
  3.          power.ConnectElectricity(new AirConditioning() );//给空调使用, 完美匹配;
  4.          // 新买一台电视, 它是二线设备, 也想用, 怎么办?
  5.          DualPin tv = new TV();
  6.          // 通过适配器, 组合二口设备
  7.          TriplePin triplePin = new TriplePinAdapter(tv)
  8.          // 不完美使用
  9.          power.ConnectElectricity(triplePin );
  10. }
复制代码
适配器模式 (Adapter Pattern) 总结

关键角色


  • 目标角色(被适配)
  • 适配角色(通过组合改变目标, 被不兼容的使用者使用)
  • 使用者(固定, 或者旧系统代码)
适配器模式的优缺点

适配器模式的优点

  • 将目标类和适配者类解耦, 通过引入一个适配器类来重用现有的适配者类, 无序修改原有结构
  • 增加了类的透明性和复用性, 将具体业务实现过程封装在适配者类中, 对于客户端类而言是透明的, 而且提高了适配者的复用性, 同一个适配者类可以在多个不同的系统中复用.
  • 灵活性和扩展性都非常好, 通过使用配置文件可以很方便的更换适配器, 也可以在不修改原有代码的基础上增加新的适配器类, 符合开闭原则.
适配器模式的缺点

  • 类适配器的缺点

    • 对于Java等不支持多重继承的语言, 一次最多只能适配一个适配者类, 不能同时适配多个适配者
    • 适配者类不能为被 final 修饰

  • 对象适配器的缺点

    • 与类适配器模式相比较, 在该模式下要在适配器中置换适配者类的某些方法比较麻烦.

适配器模式适用的场景


  • 统一多个类的接口设计时
    某个功能的实现依赖多个外部系统(或者说类)。通过适配器模式, 将它们的接口适配为统一的接口定义

  • 需要依赖外部系统时
    当我们把项目中依赖的一个外部系统替换为另一个外部系统的时候, 利用适配器模式, 可以减少对代码的改动

  • 原有接口无法修改时或者原有接口功能太老旧但又需要兼容;
    JDK1.0 Enumeration 到 Iterator 的替换, 适用适配器模式保留 Enumeration 类, 并将其实现替换为直接调用 Itertor.

  • 适配不同数据格式时;
    Slf4j 日志框架, 定义打印日志的统一接口, 提供针对不同日志框架的适配器

代理、桥接、装饰器、适配器 4 种设计模式的区别

代理、桥接、装饰器、适配器,这 4 种模式是比较常用的结构型设计模式。它们的代码结构非常相似. 但其各自的用意却不同

  • 适配器模式的主要目的是:将一个类的接口转换为客户希望的另一个接口.适配器模式让那些不兼容的类可以一起工作
  • 和 代理模式 的区别:适配器模式主要改变所考虑对象的接口, 而代理模式 主要目的是控制访问,不改变所代理类的接口
  • 和 装饰器模式 的区别:装饰者模式在不改变原始类接口的情况下,对原始类功能进行增强,并且支持多个装饰器的嵌套使用。
  • 和 桥接模式 的区别:桥接模式的目的是将接口部分和实现部分分离,从而让它们可以较为容易、也相对独立地加以改变。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册