适配器模式

序言

老师上课讲了7种设计模式,分为三种类型:创建型模式,结构型模式,行为类模式。

结构型模式中主要讲了,适配器模式和装饰器模式。其中个人理解了装饰器模式,就是通过装饰对象来在原有对象的基础上增加一些新特性,上课举的咖啡的例子,在最基础的咖啡上加糖、加牛奶等等,这就是一个装饰的过程。但对适配器模式,并未理解,依旧云里雾里,课下学习,写博客记录。

适配器模式(Adapter Pattern)简述

先从字面意思来理解,适配器,生活中有电源适配器,也就是插头,其作用是将插座上220V的电压转化为一般为5V(万年5V1A)的电压,以供手机充电,解决了电压过大,无法充电的问题,其实现的是插座电源和手机充电电源之间两个不兼容的接口的问题。

形象地说,适配器是两个不兼容的接口之间的桥梁。

意图:将一个类的接口转换成客户端Client希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

解决的问题:主要解决改变环境后,原有的类不能在新环境下使用的情况,导致我们设计好的类被浪费,不能复用,重写耗费时间。

主要实现方式:继承。通过增加一个接口,将已存在的子类封装起来, client 面向接口编程,从而隐藏了具体子类。

UML类图关系:

image-20210707202243644

不兼容:target想要调用Request方法,而Adaptee并没有这个方法,只有SpecificRequest方法,要进行一个转换。

下面举一个例子来说,还是拿手机电源和插座电源来说:

先定义创建二者的接口:

1
2
3
public interface OutletPower{  //插座电源
public void charge(String appliance); //appliance 充电电器
}
1
2
3
public interface PhonePower{ //手机电源
public void phoneCharge();
}

然后创建两个类分别实现上面的接口:

1
2
3
4
5
6
public class OutletPowerImpl implements OutletPower{
@override
public void charge(String appliance){
System.out.println("插座电源220V:充电"+appliace);
}
}
1
2
3
4
5
6
public class PhonePowerImpl implements PhonePower{
@override
public void phoneCharge(){
System.out.println("手机充电电压5V:手机充电");
}
}

然后,现在我们就需要一个手机电源设配器,将电压由220V转换成5V,让其可以给手机充电。定义创建一个实现了phonePower接口的电源适配器类。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class PowerAdapter implements phonePower{
private OutletPower outletPower;
public PowerAdapter(){
OutletPowerImpl = new OutletPowerImpl();
}

@Override
public void phoneCharge(String appliance) {
if(appliace.equalsIgnoreCase("phone")){
OutletPowerImpl.charge(appliance);
}
}
}

然后实现电源转换:

这样一来,插座电源通过手机电源设配器能给手机充电。

总结

优点:

  1. 可以让任何两个没有关联的类一起运行。

  2. 提高了类的复用。

  3. 增加了类的透明度。

  4. 灵活性好。

缺点:

  1. 过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
  2. 由于 JAVA规定,一个子类 至多继承一个类,即只有一个父类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

参考资料:

【1】 https://www.runoob.com/design-pattern/adapter-pattern.html

【2】 https://www.jianshu.com/p/9d0575311214

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2019-2022 1nvisble
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信