9. 适配器模式(Adapter Pattern)

mac2026-05-19  5

文章目录

定义类型适用场景优点缺点扩展相关设计模式代码示例角色类适配器模式步骤UMLTest 对象适配器模式步骤UMLTest 生活场景步骤

定义

将一个类的接口(被适配者)转换成客户期望的另一个接口(目标)使原本接口不兼容的类可以一起工作

类型

结构型

适用场景

已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案

优点

能提高类的透明性和复用,现有的类复用但不需要改变(解决了现有类和目标类不匹配的问题)目标类和适配器类解耦,提高程序扩展性符合开闭原则(具体的实现都在适配器中,客户端知道的只有适配器类,如果需要扩展,只需要扩展适配器类,而原有的类是不需要变化的)

缺点

适配器模式编写过程需要全面考虑,可能会增加系统的复杂性增加系统代码可读难度如果过多的使用适配器模式,会让我们的系统变得凌乱,不易整理,比如我们调用一个接口。其实内部已经被是配成了另一个接口实现。

扩展

对象适配器模式 复合组合复用原则,并且使用委托机制类适配器模式 通过类继承来实现的

相关设计模式

适配器模式和外观模式

两者都是对现有的类或系统的封装, 外观模式 1.定义一个新的接口。 2.在现有的系统中提供一个更为方便的访问入口。 适配器模式 1.复用一个原有的接口。 2.使两个已有的接口协同工作。

代码示例

角色

被适配者Adaptee目标接口Target适配者Adapter

类适配器模式

步骤

创建被适配者 //被适配者 public class Adaptee { public void apapteeRequest(){ System.out.println("被适配者的方法"); } } 创建目标接口 //目标接口 public interface Target { void request(); }

创建具体的目标类

//具体目标类 public class ConcreteTarget implements Target { @Override public void request() { System.out.println("ConcreteTarget 目标方法"); } } 创建适配者,继承被适配者,实现目标接口方法 //通过Adapter把Adaptee.apapteeRequest()适配给了Target.request() public class Adapter extends Adaptee implements Target{ @Override public void request() { //...可添加各种逻辑代码 super.apapteeRequest(); } }

UML

通过类图我们可以看出,Adapter(适配者)继承了Adaptee(被适配者)同时实现了Target(目标接口)。这样Target其实是有两种实现的,一种是ConcreteTarget(具体目标实现),另一个种是通过Adapter适配成Adaptee.apapteeRequest()实现

Test

测试代码

public class Test { public static void main(String[] args) { Target target1 = new ConcreteTarget(); target1.request(); Target target2 = new Adapter(); target2.request(); } }

执行结果

ConcreteTarget 目标方法 被适配者的方法

对象适配器模式

对与从类适配器模式到对象适配器模式的演进,我们的被适配者Adaptee和目标Target是都不会发生改变的。我们只需要修改适配者Adapter即可

步骤

我们只会实现Target接口。通过组合的方式。把具体的requet()委托给Adaptee来实现。 public class Adapter implements Target { Adaptee adaptee = new Adaptee(); @Override public void request() { //....添加逻辑代码 adaptee.apapteeRequest(); } }

UML

Test

与类适配器模式相同 执行结果不变

ConcreteTarget 目标方法 被适配者的方法

生活场景

手机充电。民用电是220V的交流电,假设我们手机充电需要5V的直流电。并且手机会带电源适配器,它的作用就是把220V的交流电转化成5V的直流电。我们用对象适配器模拟这个生活场景。(在继承和组合的时候我们优先选择组合)

步骤

创建被适配者 220V交流电 public class AC220 { public int outputAC220V(){ int output= 220; System.out.println("输出民用交流电" + output + "V"); return output; } } 目标 输出5V的直流电 public interface DC5 { int outputDC5V(); } 适配者 电源适配器 public class PowerAdapter implements DC5{ //将220V的交流电组合进来 private AC220 ac220 = new AC220(); @Override public int outputDC5V() { //适配器输入电压 int adapterInput = ac220.outputAC220V(); //变压逻辑 int outPut = adapterInput/44; //电源适配器输出电压 System.out.println("电源适配器: 输入交流电:" + adapterInput + "V,输出直流电:"+ outPut + "V"); return adapterInput; } Test public class Test { public static void main(String[] args) { DC5 dc5 = new PowerAdapter(); int inputDc = dc5.outputDC5V(); } }

执行结果

输出民用交流电220V 电源适配器: 输入交流电:220V,输出直流电:5V
最新回复(0)