设计模式结构型——适配器模式

📅 2026/8/22 12:06:17
设计模式结构型——适配器模式
目录什么是适配器模式适配器模式的实现适配器模式角色类适配器类图类适配器代码实现对象适配器类图对象适配器代码实现接口适配器类图接口适配器代码实现适配器模式的特点优点缺点注意事项使用场景和其他模式的对比什么是适配器模式适配器模式(Adapter)其别名为包装器模式(Wrapper)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起做法是将类自己的接口包裹在一个已存在的类中。在适配器模式中通过增加一个新的适配器类来解决接口不兼容的问题使得原本没有任何关系的类可以协同工作。根据适配器类与适配者类的关系不同适配器模式可分为对象适配器、类适配器、接口适配器三种。举例说明当你需要给手机充电但是墙上只有三叉口的插座这时候就需要用到三叉口插排插排上有二叉口这是就能给手机充电了插排就起到了一个适配器的作用。类适配器释义类适配器提供一个实现该接口的类并且扩展已有的类通过创建子类来实现适配。优点可以根据需求重写Adaptee类的方法使得Adapter的灵活性增强了。缺点有一定局限性。因为类适配器需要继承Target类而Java是单继承机制所以要求Adaptee类必须是接口。对象适配器释义对象适配器”通过组合除了满足“用户期待接口”还降低了代码间的不良耦合。在工作中推荐使用“对象适配”。优点同一个Adapter可以把Adaptee类和他的子类都适配到目标接口。缺点需要重新定义Adaptee行为时需要重新定义Adaptee的子类并将适配器组合适配。接口适配器释义接口适配器借助中间抽象类空实现目标接口所有方法子类选择性重写可以减少实现不必要方法。优点可以灵活方便的选择性重写接口方法。缺点由于是匿名内部类的形式所以不利于代码复用。适配器模式的实现适配器模式角色目标角色Target该角色定义把其他类转换为何种接口也就是我们的期望接口可以是一个抽象类或接口也可以是具体类。源角色Adaptee想把谁转换成目标角色是希望被适配的接口这个“谁”就是源角色它是已经存在的、运行良好的类或对象。适配器角色Adapter适配器模式的核心角色其他两个角色都是已经存在的角色而适配器角色是需要新建立的它的职责非常简单通过继承或是类关联的方式把源角色转换为目标角色将被适配者和目标抽象类组合到一起把源角色转换为目标角色。类适配器类图从上图可以看出Adaptee类并没有operation2()方法而客户端则期待这个方法。为使客户端能够使用Adaptee类需要提供一个包装(Wrapper)类Adapter。这个包装类包装了一个Adaptee的实例从而此包装类能够把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系这决定了适配器模式是对象的。类适配器代码实现/** * author Evan Walker 昂焱数据: https://www.ayshuju.com * version 1.0 * desc 类适配器 * date 2023/06/07 14:39:18 */ class Adaptee{//源角色 public void operation1(){ System.out.println(这是原来的类里面存在operation1); } } interface Target{//目标接口 void operation1(); void operation2(); } class Adapter extends Adaptee implements Target{//适配器类 Override public void operation2() { System.out.println(这是接口中的方法。); } } public class Test { public static void main(String[] args) { Target adapter new Adapter(); adapter.operation1(); adapter.operation2(); } }运行结果如下对象适配器类图从上图可以看出Adaptee类并没有operation2()方法而客户端则期待这个方法。为使客户端能够使用Adaptee类需要提供一个包装(Wrapper)类Adapter。这个包装类包装了一个Adaptee的实例从而此包装类能够把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系这决定了适配器模式是对象的。对象适配器代码实现/** * author Evan Walker 昂焱数据: https://www.ayshuju.com * version 1.0 * desc 对象适配器 * date 2023/06/07 14:39:18 */ /** * 目标接口 */ interface Target { void operation1(); void operation2(); } /** * 源角色 */ class Adaptee { public void operation1() { System.out.println(这是原来的类里面存在operation1); } } /** * 适配器角色 */ class Adapter implements Target{ private Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee adaptee; } /** * 源类Adaptee有方法operation1 * 因此适配器类直接委派即可 */ Override public void operation1() { this.adaptee.operation1(); } /** * 源类Adaptee没有方法operation2 * 因此由适配器类需要补充此方法 */ Override public void operation2() { System.out.println(这是接口中的方法。); } } public class Test { public static void main(String[] args) { Target adapter new Adapter(new Adaptee()); adapter.operation1(); adapter.operation2(); } }运行结果如下接口适配器类图接口适配(Default Adapter)模式为一个接口提供缺省实现这样子类型可以从这个缺省实现进行扩展而不必从原有接口进行扩展。接口适配器代码实现/** * author Evan Walker 昂焱数据: https://www.ayshuju.com * version 1.0 * desc * date 2023/06/08 16:27:14 */ /** * 目标接口 */ interface Target{ void operation1(); void operation2(); void operation3(); } /** * 定义一个抽象类来选择需要重写的类 */ abstract class abstractAdaptee implements Target{ Override public void operation1(){ System.out.println(默认实现operation1); } Override public abstract void operation2();//这个方法必须由子类来重写 Override public void operation3(){ System.out.println(默认实现operation3); } } /** * 定义一个类来继承abstractAdaptee类 * 通过接口和抽象类的结合我们在子类中可以选择性的去实现那些抽象方法 */ class Adapter extends abstractAdaptee{ Override public void operation2() { System.out.println(子类必须重写这个方法); } } public class Test { public static void main(String[] args) { Target adapter new Adapter(); adapter.operation1(); adapter.operation2(); adapter.operation3(); } }运行结果如下适配器模式的特点优点将目标类和适配者类解耦让任何两个没有关联的类一起运行。通过引入一个适配器类来重用现有的适配者类无须修改原有结构。提高了类的透明度和复用性。将具体的业务实现过程封装在适配者类中对于客户端类而言是透明的而且提高了适配者类的复用性同一个适配者类可以在多个不同的系统中复用。灵活性和扩展性都非常好可通过使用配置文件方便更换适配器也可不改原有代码新增的适配器类符合“开闭原则”。缺点过多地使用适配器会让系统非常零乱会让系统看起来很复杂不易维护因为需要从全局考虑不易整体进行把握。增加代码的阅读难度注意事项适配器模式最好在详细设计不要考虑它它不是为了解决还处在开发阶段的问题而是解决正在服役的项目问题。使用场景有动机地修改一个正常运行的系统的接口可以考虑使用适配器模式。多个组件功能类似但接口不统一且可能会经常切换时可使用适配器模式使得客户端可以以统一的接口使用它们。系统需要复用现有类而该类的接口不符合系统的需求导致无法直接去访问可使用适配器模式就能间接去访问这个类中的方法。和其他模式的对比适配器模式和装饰者模式装饰者模式是对以前的类进行进一步的封装与增强目的是一层一层的增加功能而适配器模式主要是为了协调多个调用者不同的调用方式而设计出来的。适配器模式和外观模式都是对现有类的封装外观模式定义了新的接口适配器则是复用已有的接口适配器是两个接口协调工作而外观模式则是为了别人使用的方便提供了一个比较易用的接口