glmapper

菜鸟成长系列-适配器模式

字数统计: 1.4k阅读时长: 4 min
2020/01/28 Share

本文为阅读 《JAVA与模式》的个人笔记,文中相关概念及背景描述参考书本。如有不当,请联系指正。

定义:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配为无法在一起工作的两个类能够在一起工作 -《JAVA与模式》

适配、包装、转换几个字眼从汉字的字面意思来说是不同的,不同在于这几个词所对应的行为不同;但是他们所期望的目的是差不多一致的,就是将不可用变成可用。所以常说的适配器模式、转换器模式以及包装模式指的都是一个模式。

适配器模式的两种形式

在 java 语言体系中,根据适配类型的不同。适配器模式可以分为:类的适配器模式对象的适配器模式

类的适配器模式

顾名思义,类的适配器模式是把被适配的类的 API 转换成为目标类的 API。

这里涉及到三个角色:

  • 目标角色:客户端期待的接口
1
2
3
4
5
6
7
8
9
10
11
public interface Target {
/**
* 源类没有的方法
*/
void sampleOperation1();

/**
* 源类没有的方法
*/
void sampleOperation2();
}
  • 源角色:现有需要被适配的接口
1
2
3
4
5
public class Adaptee {
void sampleOperation1(){
// todo your biz
}
}
  • 适配器角色:把源接口转换成目标接口的适配器类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Adapter extends Adaptee implements Target {

@Override
public void sampleOperation1() {
// todo your biz
}
/**
* 由于源类没有 sampleOperation2 方法,因此适配器类中补充上这个方法
*/
@Override
public void sampleOperation2() {
// todo your biz
}
}

Target 接口申明了两个方法:sampleOperation1 和 sampleOperation2 ,而源角色 Adaptee 是一个具体的类,它只有一个 sampleOperation1 方法,但是没有 sampleOperation2 这个方法。适配器角色 Adapter 扩展了 Adaptee ,同时又实现了目标接口,由于 Adaptee 没有 sampleOperation2 方法,而目标接口又要求这个方法,因此适配器角色 Adapter 实现了这个方法。

适配器模式所达到的效果是:使用一个具体类把源(Adaptee)适配到目标(Target)中,这样一来,如果源以及源的子类都使用此类适配,就行不通了。由于适配器类是源的子类,因此可以在适配器类中置换掉源的一些方法;另外,由于只引进了一个适配器类,因此只有一个路线达到目标类,使问题得到简化。

对象的适配器模式

与类的适配器模式一样,对象的适配器模式把被适配的类的 API 转换成为目标类的 API ,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到 Adaptee 类,而是使用委派关系连接到 Adaptee 类。这里我们只需要对前面的 Adapter 做简单的修改即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ObjAdapter implements Target {

private final Adaptee adaptee;

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

@Override
public void sampleOperation1() {
adaptee.sampleOperation1();
}

@Override
public void sampleOperation2() {
// todo your biz
}
}

实际上这里所说的委派就是组合。

适配器模式的用意在于将接口不同而功能相同或者相近的两个接口加以转换,这里面包括适配器角色补充了一个源角色没有的方法。需要注意的是,不要误以为适配器模式就是为了补充源角色没有的方法而准备的。

在什么情况下需要使用适配器模式

书中提到的有三种场景,但是在实际的工程中,场景要远远多于书中所说的。

  • 1、系统需要使用现有的类,而此类的接口不符合系统的需要
  • 2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有很复杂的接口
  • 3、在设计里,需要改变多个已有的子类的接口,如果使用类的适配器模式,就需要针对每一个子类做一个适配器,而这不太实际。

与一些模式的区别

与桥接器模式的区别

桥接器模式的用意是要把实现和它的接口分开,以便于它们可以独立的变化。桥接器模式并不是用来把一个已有的对象接到不匹配的接口上的,当一个客户端只知道一个特定的接口,但是又必须与具有不同接口的类打交道时,就应当使用适配器模式。

与装饰模式的区别

一个装饰类也是位于客户端和另一个 Component 对象之间的,在它接到客户端的调用后把调用传给一个或者几个 Component 对象。一个纯粹的装饰类必须与 Component 对象在接口上的完全相同,并增强后者的功能。


与适配器类不同的是,装饰类不能改变它所装饰的 Component 对象的接口。

装饰模式可以这样理解,《开局一把枪,装备全靠打:皮肤、装备加持就是角色的装饰》

小结

本篇是在阅读 《JAVA与模式》一书所做的笔记记录,以备后续方便查阅。

原文作者:GuoLei Song

原文链接:http://www.glmapper.com/2020/01/28/java-design-model-adapter/

发表日期:January 28th 2020, 3:32:14 pm

更新日期:January 28th 2020, 5:13:18 pm

版权声明:转载请注明出处

CATALOG
  1. 1. 适配器模式的两种形式
    1. 1.1. 类的适配器模式
    2. 1.2. 对象的适配器模式
  2. 2. 在什么情况下需要使用适配器模式
  3. 3. 与一些模式的区别
    1. 3.1. 与桥接器模式的区别
    2. 3.2. 与装饰模式的区别
  4. 4. 小结