适配器模式

结构型模式概述

结构型模式的定义:结构型模式(Structural Pattern)关注如何将现有类或对象组织在一起形成更加强大的结构。不同的结构型模式从不同的角度组合类或对象,它们在尽可能满足各种面向对象设计原则的同时为类或对象的组合提供一系列巧妙的解决方案。

结构型模式可以分为以下类别:

  • 类结构型模式:关心类的组合,由多个类组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系。
  • 对象结构型模式:关心类与对象的组合,通过关联关系,在一个类中定义另一个类的实例对象,然后通过该对象调用相应的方法。

大部分结构型模式是对象结构型模式。

适配器模式概述

引入:电源适配器

220V的电压显然无法直接为笔记本电脑提供工作环境电压,需要使用电源适配器进行变压。

现实生活:

  • 不兼容:生活用电220V <–> 笔记电脑20V
  • 引入 AC Adapter(交流电适配器)

软件开发:

  • 存在不兼容的结构,例如方法名不一致。
  • 引入适配器模式

适配器模式的定义:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。别名为包装器(Wrapper)模式。定义中所提及的接口是指广义的接口,它可以表示一个方法或者方法的集合。

适配器模式的结构与实现

适配器模式包括类适配器对象适配器。在对象适配器模式中,适配器与适配器直接是关联关系;在类适配器模式中,适配器与适配器之间是继承或实现关系。

适配器模式中的角色

  • Target(目标抽象类):目标抽象类定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类。
  • Adapter(适配器类):它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配。适配器Adapter是适配器模式的核心,在类适配器中,它通过继承Target并关联一个Adaptee对象使二者产生联系。
  • Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下甚至没有适配者类的源代码。

典型的类适配器代码:

public class Adapter extends Adaptee implements Target {
public void request() {
super.specificRequest();
}
}

典型的对象适配器代码:

public class Adapter extends Target {
//维持一个对适配者对象的引用
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee=adaptee;
}
public void request() {
adaptee.specificRequest(); //转发调用
}
}

缺省适配器模式

缺省适配器模式的定义:当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适用于不想使用一个接口中的所有方法的情况,又称为单接口适配器模式。

适配器模式的优缺点与适用环境

模式优点

  • 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。
  • 增加了类的透明性和复用性,提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用。
  • 灵活性和扩展性非常好。
  • 类适配器模式:置换一些适配者的方法很方便。
  • 对象适配器模式:可以把多个不同的适配者适配到同一个目标,还可以适配一个适配者的子类。

模式缺点

  • 类适配器模式:(1) 一次最多只能适配一个适配者类,不能同时适配多个适配者;(2) 适配者类不能为最终类;(3) 目标抽象类只能为接口,不能为类。
  • 对象适配器模式:在适配器中置换适配者类的某些方法比较麻烦。

适配器模式可以将一个类的接口和另一个类的接口匹配起来,使用的前提是不能活不想修改原来的适配者接口和抽象目标类接口。例如购买了一些第三方类库或者控件,但是没有源代码,此时使用适配器模式可以统一对象访问接口。

适配器模式更多的是强调对代码的组织,而不是功能的实现。在实际开发中,对象适配器的使用频率更高。

发表回复

Breeze Wang

A student majoring in Software Engineering at Central South University has an understanding of software development techniques, software architecture, and is able to use Godot to develop game projects. I am currently in the Game Development Laboratory at Central South University. I have experience participating in Global Game Jam. Loving game development.