134

我一直在阅读这两个定义,它们似乎完全相同。谁能指出他们的区别是什么?

谢谢

4

16 回答 16

169

Facade Pattern wiki 页面对此有一个简短的说明。

“当包装器必须尊重特定接口并且必须支持多态行为时,使用适配器。另一方面,当人们想要使用更简单或更简单的接口时,使用外观。”

我听到一个类比,您应该考虑一下您已设置为与所有不同的立体声系统一起使用的通用遥控器 - 您按下“on”,它会打开您的有线电视盒、接收器和电视。也许这是一个非常漂亮的家庭影院,它也可以调暗灯光并拉上阴影。那是一个门面——一个按钮/功能可以处理一组更复杂的步骤。

适配器模式只是链接了两个不兼容的接口。

编辑:适配器模式的快速类比(基于评论)可能类似于 DVI 到 VGA 适配器。现代视频卡通常是 DVI,但你有一个旧的 VGA 显示器。通过将适配器插入视频卡的预期 DVI 输入,并拥有自己的 VGA 输入,您将能够让旧显示器与新视频卡一起工作。

于 2010-06-02T20:31:11.120 回答
155

适配器 == 使方形钉适合圆孔。

Facade == 运行所有内部组件的单个控制面板。

于 2010-06-02T20:36:22.260 回答
23

正面:

关键要点:(来自Pankaj Kumar 的journaldev文章)

  1. 外观模式更像是客户端应用程序的助手
  2. 外观模式可以应用于任何开发点,通常是在接口数量增加和系统变得复杂时
  3. 子系统接口不知道 Facade,它们不应该有任何 Facade 接口的引用
  4. 外观模式应该应用于类似类型的接口,它的目的是提供一个接口而不是多个接口来完成类似的工作。

门面类图:

在此处输入图像描述

适配器:

  1. 它是一种结构模式
  2. 使用两个不兼容的接口很有用
  3. 使事情在设计后工作

Adapter的类图:

在此处输入图像描述

您可以在此 SE 帖子中找到有关适配器的更多详细信息:

桥接模式和适配器模式之间的区别

主要区别:

  1. Facade 定义了一个新的接口,而 Adapter 使用了一个旧的接口。适配器使两个现有接口协同工作,而不是定义一个全新的接口
  2. Adapter 和 Facade 都是包装器;但它们是不同类型的包装器。Facade 的目的是产生一个更简单的接口,而 Adapter 的目的是设计一个现有的接口

也可以查看sourcemaking文章以获得更好的理解。

于 2016-06-05T17:48:29.320 回答
21

老实说,许多模式可以以相同的方式以编程方式实现——区别在于意图。

适配器设计模式旨在将一个或多个类的接口“转换”为客户端期望使用的接口——适配器将对预期接口的调用转换为包装类使用的实际接口。

当需要更简单的接口时使用外观模式(同样,可以通过包装有问题的类以相同的方式实现。)当现有接口不兼容时,您不会说您正在使用外观,只是在您需要时使其更具可读性,减少设计不良等。

于 2010-06-02T20:39:45.603 回答
21

一个目的

门面简单

适配器互操作的。

于 2018-03-19T02:04:14.610 回答
17

外观设计用于在单个服务网关后面组织多个服务。适配器旨在提供一种使用已知接口访问未知接口的方法。

于 2010-06-02T20:30:51.987 回答
13

Facade 通常与 Adapter 进行对比。

正面 适配器
使用单一界面简化多个复杂组件 为接口提供不同的接口
适用于多个组件 适用于单个组件
控制面板就是一个例子 电源适配器就是一个例子
高级接口 低级接口
于 2018-01-27T13:16:37.670 回答
6

像往常一样,几种模式之间存在相似之处。但我会这样看:

  • 外观用于封装整个层,并提供一些“方便”访问它的方法
  • 使用适配器,您有两个组件应该已经可以一起工作,但不这样做,只是因为接口中有一些“不重要的”差异。
于 2010-06-02T20:34:25.820 回答
4

我将尝试用简单的语言来解释这一点,没有太多的形式。

想象一下,您有一些域类,并且您想从 UI 中与它们交互。外观可用于提供可从 UI 层调用的功能,以便 UI 层不知道外观以外的任何域类。这意味着不是调用域类中的函数,而是从外观调用单个函数,该函数将负责从其他类调用所需的函数。

另一方面,适配器可用于集成其他外部组件,这些组件可能具有您需要的相同功能,但它们的功能调用方式并不完全相同。假设您Car的域中有一个类,并且您与一个也定义了 Car 类的外部汽车提供商合作。在这个类中,您已经获得了函数car.getDoors(),但外部提供者具有等效的car.getNumDoors(). 您不想更改调用此函数的方式,因此您可以使用适配器类来包装外部 Car 类,以便getDoors()将对适配器的调用委托给getNumDoors()外部类。

于 2010-06-03T07:38:59.430 回答
3

适配器模式允许两个以前不兼容的接口相互工作。有 2 个独立的接口在使用。

Facade 模式采用一个已知的接口,即低级别/细粒度的,并用更高级别/粗粒度的接口包装它。有一个接口,已通过与另一个接口进行了简化。

于 2010-06-02T20:33:56.023 回答
3

适配器使两个接口一起工作。

Facade 将单个类暴露给更高、更有限的级别。例如,视图模型外观可能只公开较低级别类的某些只读属性。

于 2010-06-02T20:34:07.630 回答
2

适配器模式通过提供一个新接口来链接两个不兼容的接口。

外观模式用一个接口简化了一个复杂的子系统(具有多个组件)。

于 2019-08-12T21:43:51.490 回答
1

正面

抽象复杂性以提供更简单的接口。例如,计算机操作系统抽象了底层硬件的复杂性。或者,与低级语言 (C) 相比,高级编程语言 (Python/JavaScript) 抽象了复杂性。

适配器

它类似于硬件适配器。假设您要将 a 连接USB device到 a serial port,您将需要 a USB-serial port adapter

于 2018-08-08T08:50:37.850 回答
1

Facade模式的主要目标是使类或子系统更易于使用,而Adapter模式的主要目标是调整接口以满足客户的期望。

于 2020-06-15T07:25:29.743 回答
1

这两种模式之间的区别很明显,但不是在设计模式领域,而是在领域建模领域。在下文中,我将解释原因。

首先,我想重申其他人在这里所说的,然后我将添加注释:

Facade 是子系统(外部或遗留系统)的接口,可简化客户(我们)的访问。Facade 隐藏了另一个子系统的接口(聚合了一些调用,或者隐藏了一些我们不需要的 API),因此您的客户端只能通过这个 Facade 访问该子系统。

另一方面,适配器是另一个服务或对象的包装器。它使包装的对象符合客户期望的标准接口。假设“分类帐”对象上有一个方法,您需要对其进行调整(更改其参数,更改其名称等)。你可以用适配器包裹它。

现在,差异可能还不清楚。这就是我想提出这两种模式之间的关键区别的地方,不要让进一步混淆

Facade 不会更改其他子系统的域模型,而 Adapter 会。 这是关键的区别。时期。

这就是为什么在创建反腐败层时将这两者结合起来的原因。假设您有要使用的子系统,但您不希望其域模型混淆您的域模型。你会怎么办?您将创建一个反腐败层。如何?您首先创建一个外观,它简化了子系统接口的访问,然后为该接口中使用的域对象创建适配器(请记住外观仍然保存另一个子系统的域模型),因此它符合您的模型。

许多设计模式可用于域建模。对于 Facade 和 Adapter 设计模式也是如此。尽管这两种模式之间的区别在“设计模式”领域可能并不明显,但在“领域建模”领域更为明显。

于 2020-06-27T17:41:36.557 回答
0

我一直在阅读这两个定义,它们似乎完全相同。

真的吗 ?

我注意到术语适配器有时用于描述实际上是Stategy的东西,可能是因为这个词更具表现力。

例如,在Zend Framework中,所有的Adapter类实际上都是策略模式的实现,因为它们只将原生代码包装在类后面,具有多种行为。

适配器通常用于包装遗留或“旧式”代码。

于 2010-06-04T18:08:44.560 回答