7-适配器模式

适配器模式

结构型模式

关注如何将现有类或对象组织在一起形成更加强大的结构

结构型模式分类
类结构型模式
  • 关心类的组合,由多个类组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系

对象结构型模式
  • 关心类与对象的组合,通过关联关系,在一个类中定义另一个类的实例对象,然后通过该对象调用相应的方法

适配器模式的定义

image-20221128203447563

对象结构型模式 / 类结构型模式

  • 别名为包装器(Wrapper)模式
  • 定义中所提及的接口是指广义的接口,它可以表示一个方法或者方法的集合

适配器模式结构(类适配器)

image-20221128203615150

适配器模式结构(对象适配器)

image-20221128203750857
适配器模式包含以下3个角色:
  • Target(目标抽象类)

  • Adapter(适配器类)

  • Adaptee(适配者类)

典型的类适配器代码
1
2
3
4
5
public class Adapter extends Adaptee implements Target {
public void request() {
super.specificRequest();//通过super转发调用
}
}
典型的对象适配器代码
1
2
3
4
5
6
7
8
9
10
11
public class Adapter extends Target {
private Adaptee adaptee; //维持一个对适配者对象的引用

public Adapter(Adaptee adaptee) {//不仅可以适配类,也可以适配类的子类(里氏替换原则)
this.adaptee=adaptee;
}

public void request() {
adaptee.specificRequest(); //通过类名转发调用
}
}
实例类图:
image-20221130190502427

上图为对象适配器。

move()直接在CarController中实现

phonate()、twinkle()做成抽象方法

(1) CarController:汽车控制类,充当目标抽象类

(2) PoliceSound:警笛类,充当适配者

(3) PoliceLamp:警灯类,充当适配者

(4) PoliceCarAdapter:警车适配器,充当适配器

(5) Client:客户端测试类

配置文件操作

  1. 将具体适配器类的类名存储在配置文件中

  2. 扩展方便

1
2
3
4
<?xml version="1.0"?>
<config>
<className>designpatterns.adapter.PoliceCarAdapter</className>
</config>

当需要增加救护车时,只需要增加新的警笛类、警灯类以及对应的救护车适配器类,然后改变相应的配置文件中适配器的名称即可完成扩展,符合开闭原则

缺省适配器模式

定义

image-20221130191924902
结构
image-20221130191958152

缺省适配器类为抽象类,但其中实现的方法都是具体的方法(空实现),具体的实际方法由缺省适配器类的子类实现。

缺省适配器类的典型代码片段
1
2
3
4
5
public abstract class AbstractServiceClass implements ServiceInterface {
public void serviceMethod1() { } //空方法
public void serviceMethod2() { } //空方法
public void serviceMethod3() { } //空方法
}

双向适配器

结构
image-20221130192249819

在request方法中调用adaptee.specificRequest();(目标类是:ConcreteTarget类)

同样在specificRequest方法中可以调用target.request();(目标类是:ConcreteAdaptee类)

双向适配器典型代码片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Adapter implements Target,Adaptee {
private Target target;
private Adaptee adaptee;

public Adapter(Target target) {
this.target = target;
}

public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}

public void request() {
adaptee.specificRequest();
}

public void specificRequest() {
target.request();
}
}

模式优点

  • 目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构

  • 增加了类的透明性和复用性,提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用

  • 灵活性和扩展性非常好

  • 类适配器模式:置换一些适配者的方法很方便

    • 类适配器继承适配者类
  • 对象适配器模式:可以把多个不同的适配者适配到同一个目标,还可以适配一个适配者的子类

模式缺点

类适配器模式:
  • 一次最多只能适配一个适配者类,不能同时适配多个适配者

  • 适配者类不能为最终类

  • 目标抽象类只能为接口,不能为类

对象适配器模式:
  • 在适配器中置换适配者类的某些方法比较麻烦

模式适用环境

  • 系统需要使用一些现有的类(适配者),而这些类的接口不符合系统的需要,甚至没有这些类的源代码

  • 创建一个可以重复使用的类(目标类/适配者),用于和一些彼此之间没有太大关联的类,包括一些可能在将来引进的类一起工作

    • 解决原本类之间不能连同工作的问题

课后思考

  1. 在对象适配器中,一个适配器能否适配多个适配者?

  2. 如果能,应该如何实现?

  3. 如果不能,请说明原因?

  4. 如果是类适配器呢?

  • 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 © 2023-2024 Guijie Wang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信