设计模式:适配器

一共有23种经典的设计模式,在原始书《 Design Patterns: Elements of Reusable Object-Oriented Software有介绍。 这些模式提供了针对特定问题的解决方案,这些问题通常在软件开发中反复出现。

在本文中,我将描述适配器模式的方式。 以及应如何以及何时应用。

适配器模式:基本概念

适配器 允许两个不兼容的接口一起工作。 这是适配器的实际定义。 接口可能不兼容,但内部功能应适合需要。 适配器设计模式通过将一个类的接口转换为客户端期望的接口,可以使不兼容的类一起工作。 —维基百科

将类的接口转换为客户端期望的另一个接口。 Adapter使类可以协同工作,否则由于接口不兼容而无法实现。 —设计模式:可重用的面向对象软件的元素

这种模式的主要特点是与其他类或具有不同接口的几个类相比,重用一个具有不同接口的类,以便它们可以一起工作。

此模式有两个版本:

  • object adapter通过在运行时委派给adaptee对象来实现target接口。
  • class adapter通过在编译时从adaptee类继承来实现target接口。

由于多重继承不受包括Java在内的许多语言的支持,并且与许多问题相关联,因此我们没有显示使用类适配器模式的实现。

总而言之,对象适配器(AKA适配器)包含它包装的类的实例。 此模式的UML图如下:

Adaptor类包含Adaptee类。 这意味着Adaptee类将由Adaptor

适配器模式:何时使用

  1. 有一个类,其接口与您需要的接口不匹配。
  2. 有几个子类,但是通过对每个子类进行子类化来调整其接口是不切实际的。

适配器模式具有几个优点,总结如下:

  • 该代码更具可恢复性和灵活性
  • 清理代码,因为客户端/上下文在每个具体类中均不使用不同的接口,并且可以使用多态性在不同的适配器之间进行交换。

适配器模式-示例1:使用JavaScript / TypeScript的新Android到达城市示例

现在,我将向您展示如何使用JavaScript / TypeScript实现此模式。 请记住,Javascript既缺少接口又没有抽象类。 因此,了解此模式的最佳方法是使用示例和TypeScript。 在我们的案例中,我提出了一个问题,其中存在一个名为Warrior的抽象类,该抽象类定义了Warrior。 战士具有一套与问题不相关的属性和一种称为attack的方法。 有一种类型的分类,例如SaiyanNamekian ,它定义了attack方法的具体实现,但是一个新类到达了称为Android的系统,该类不满足Warrior的界面,但是内部以不同的方式实现了该方法。 下面的UML图显示了我刚刚描述的场景。

解决方案是使用包含在包含Android对象的类( AndroidAdapter )中的适配器模式,并使用它来使其与战士的界面兼容。 即,使用适配器模式的新UML图如下所示:

与模型和接口关联的代码如下:

如您所见, Android类尚未实现warrior的界面。 因此, AndroidAdapter类负责解决此问题。

最后,要使用这三个类的客户端/上下文应将AndroidAdapter类与SaiyanNamekian一起使用,如在下一个代码中看到的:

适配器模式-示例2:几个种族希望使用JavaScript / TypeScript一起工作(Genki-dama)

使用适配器模式解决的另一个有趣的问题是,当有多个具有不同接口的类但它们可以一起工作时。 在以下UML的图中,您可以看到这种情况:

在这种情况下,种族之间具有不同的通讯接口。 具体来说,每个种族都有一种或几种分享力量的方法。 例如,人类共享了myPowerPart1myPowerPart2拥有了getPower ,甚至更复杂的是赛亚人,它有两种方法来共享其权力( myPowerPart1myPowerPart2 )。

您可以在以下UML的图中看到,使用适配器模式可以实现多个种族一起工作的解决方案。

每个类都使用一个新的适配器类,该适配器类包含原始对象和实现该接口的方法。 此示例的代码非常简单。

以及它们各自的适配器如下:

最后,所有物体都为消灭邪恶和实现强大力量贡献力量。

我创建了两个npm脚本,这些脚本在应用适配器模式后运行此处显示的两个示例。

npm run example1
npm run example2

结论

当存在可以一起使用但它们的接口不兼容的类时,适配器模式可以避免项目中重复的代码。 在这篇文章中,您已经可以使用JavaScript / TypeScript语言实现简单的实现。

最重要的事情不是实现您所展示的模式,而是为了能够认识到该特定模式可以解决的问题,以及您何时可以实现或不实现所述模式。 这是至关重要的,因为实现会根据您使用的编程语言而有所不同。

更多更多更多…

  • 设计模式:Gamma,Helm,Johnson和Vlissides的可重用的面向对象软件的元素,Addison Wesley,1995年。
  • 适配器模式-维基百科。
  • https://www.dofactory.com/javascript/adapter-design-pattern
  • https://github.com/sohamkamani/javascript-design-patterns-for-humans#-adapter