适配器模式 Adapter:将一个类的接口转换为客户端希望的另外一个接口,使原本因为接口不匹配(或者不兼容)而无法在一起工作的两个类能够在一起工作。像是 Mac 的转换头、插座、数据线等,都是适配器模式的体现
适配器模式(Adapter)包含以下主要角色
优点:
缺点:
适配器模式分为类结构性模式和对象结构型模式两种,类结构型模式用的较少些,并且类之间的耦合度比对象结构型模式更高一些
类适配器模式——适配器继承自己实现的类(一般多重继承)
Adapter 与 Adaptee 是继承关系
Adapter 和 Adaptee 是委托关系
无论哪种适配器都是为了在不改变原有系统的基础上,提供新的接口服务
// 目标接口 public interface Target { void request(); } // 适配者类 public class Adaptee { public void specificRequest(){ System.out.println("适配者被调用"); } } // 类适配器 public Adapter extends Adaptee implements Target { @Override public void request(){ specificRequest(); } } // 客户端 public class ClassAdapterTest { public static void main(String[] args) { Target target = new ClassAdapter(); target.request(); } } // 运行结果如下: // 适配者被调用
// 目标接口 public interface Target { void request(); } // 适配者 public class Adaptee { void specificRequest() { System.out.println("适配者被调用了"); } } // 对象适配器 public class ObjectAdapter implements Target { private Adaptee adaptee; public ObjectAdapter(Adaptee adaptee) { this.adaptee = adaptee; } @Override public void request() { adaptee.specificRequest(); } } // 对象适配器测试 public class ObjectAdapterTest { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); ObjectAdapter objectAdapter = new ObjectAdapter(adaptee); objectAdapter.request(); } }
适配器模式(Adapter)可以扩展为双向适配器模式,可以把适配者接口转为目标接口,也可以把目标接口转为适配者接口,如下图所示
代码实现:
/** * 目标接口 */ public interface TwoWayTarget { void request(); } /** * 目标实现 */ public class TargetRealize implements TwoWayTarget { @Override public void request() { System.out.println("目标代码被调用"); } } /** * 适配者接口 */ public interface TwoWayAdaptee { void specificRequest(); } /** * 适配者实现 */ public class AdapteeRealize implements TwoWayAdaptee{ @Override public void specificRequest() { System.out.println("适配者代码被调用"); } } /** * 双向适配器 */ public class TwoWayAdapter implements TwoWayAdaptee, TwoWayTarget{ private TwoWayTarget target; private TwoWayAdaptee adaptee; public TwoWayAdapter(TwoWayAdaptee adaptee) { this.adaptee = adaptee; } public TwoWayAdapter(TwoWayTarget target) { this.target = target; } @Override public void specificRequest() { target.request(); } @Override public void request() { adaptee.specificRequest(); } } /** * 双向适配器客户端 */ public class TwoWayAdapterTest { public static void main(String[] args) { TwoWayAdaptee adaptee = new AdapteeRealize(); TwoWayTarget target = new TwoWayAdapter(adaptee); target.request(); System.out.println("~~~~~~~~~~~~~"); target = new TargetRealize(); adaptee = new TwoWayAdapter(target); adaptee.specificRequest(); } }