外观模式和适配器模式有什么区别?
我一直在阅读这两个定义,它们看起来非常相似。
谁能指出他们有什么区别?
I've been reading both definitions and they seem quite the same.
Could anyone point out what are their differences?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
外观模式 wiki 页面对此有一个简短的说明。
我听到一个类比,你应该想到你已经设置为与所有不同的立体声系统一起使用的通用遥控器 - 你按下“on”,它就会打开你的有线电视盒、你的接收器,和你的电视。也许它是一个非常奇特的家庭影院,它也可以调暗灯光并绘制窗帘。这也是一个外观 - 一个按钮/功能,可以处理一组更复杂的步骤。
适配器模式只是连接两个不兼容的接口。
编辑: 适配器模式的快速类比(基于评论)可能类似于 DVI 到 VGA 适配器,现代显卡通常是 DVI,但您有一个旧的 VGA。借助可插入视频卡预期的 DVI 输入并具有自己的 VGA 输入的适配器,您将能够让旧显示器与新视频卡配合使用。
The Facade Pattern wiki page has a brief note about this.
I heard an analogy that you should think of your universal remote control that you've set up to work with all your different stereo systems - you press "on" and it turns on your cable box, your receiver, and your TV. Maybe it's a really fancy home theater and it dims the lights and draws the shades too. That's a Facade - one button/function that takes care of a more complicated set of steps.
The Adapter pattern just links two incompatible interfaces.
EDIT: A quick analogy for the Adapter pattern (based on the comments) might be something like a DVI-to-VGA adapter. Modern video cards are often DVI, but you've got an old VGA monitor. With an adapter that plugs into your video card's expected DVI input, and has its own VGA input, you'll be able to get your old monitor working with your new video card.
适配器 == 将方钉插入圆孔。
Facade == 一个运行所有内部组件的控制面板。
Adapter == making a square peg fit into a round hole.
Facade == a single control panel to run all the internal components.
外观的目的
是简单
适配器是互操作性。
The purpose of a
facade is simplicity
adapter is interoperability.
外观:
提供单个接口,而不是执行类似工作的多个接口
示例:API 网关
适配器:
可使用的结构模式 接口不兼容。它允许将现有类的接口用作另一个接口
示例:MouseAdapter
主要区别:
Facade 定义了新接口,而 Adapter 使用旧接口。适配器使两个现有接口协同工作
外观产生一个更简单的接口适配器更改现有接口
Facade:
Provides a single interface rather than multiple interfaces that does the similar kind of jobs
Example : API Gateway
Adapter:
A structural pattern to work with incompatible interfaces. It allows the interface of an existing class to be used as another interface
Example : MouseAdapter
Key differences:
Facade defines a new interface, whereas Adapter uses an old interface. Adapter makes two existing interfaces work together
Facade produce a simpler interface Adapter changes an existing interface
老实说,许多模式可以以相同的方式以编程方式实现——区别在于意图。
适配器设计模式旨在将一个或多个类的接口“转换”为客户端期望使用的接口——适配器将对预期接口的调用转换为包装类使用的实际接口。
当需要更简单的接口时,可以使用外观模式(并且可以通过包装有问题的类以相同的方式实现。)当现有接口不兼容时,您不会说您正在使用外观,而只是当您需要时使其更具可读性,减少设计不良等。
Honestly, many patterns could be implemented the same way programmatically -- the difference is in intent.
The Adapter design pattern is meant to 'translate' the interface of one or more classes into an interface that the client expects to use -- the adapter would translate the calls to the expected interface into the actual interface the wrapped classes use.
The Facade pattern is used when a simpler interface is wanted (and again, could be implemented the same way by wrapping the offending classes.) You wouldn't say you're using a facade when the existing interface is incompatible, just when you need to make it more readable, less poorly-designed, etc.
外观设计用于在单个服务网关后面组织多个服务。适配器旨在提供一种使用已知接口访问未知接口的方法。
A facade is designed to organize multiple services behind a single service gateway. An adapter is designed to provide a way to use a known interface to access an unknown one.
这两种模式之间的区别很明显,但不是在设计模式领域,而是在领域建模领域。下面,我将解释原因。
首先,我想重申其他人在这里所说的,然后我将添加注释:
外观是子系统(外部或遗留系统)的接口,它简化了客户端(我们)的访问。 Facade隐藏了其他子系统的接口(聚合一些调用,或者隐藏一些我们不需要的API),因此您的客户端只能通过这个Facade访问该子系统。
另一方面,适配器是另一个服务或对象的包装器。它使包装的对象符合客户端期望的标准接口。假设“Ledger”对象上有一个方法,您需要对其进行调整(更改其参数、更改其名称等)。您可以用适配器将其包裹起来。
现在,差异可能仍然不清楚。这就是我想提出这两种模式之间的关键区别的地方,以免进一步混淆:
Facade 不会更改其他子系统的域模型,而 Adapter 会更改。 < strong>这是关键的区别。
这就是为什么在创建反腐败层时将这两者结合起来的原因。假设您有一个想要使用的子系统,但您不希望它的域模型混淆您的域模型。你会怎么办?您将创建一个反腐败层。如何?您首先创建一个 Facade,它可以简化对子系统接口的访问,然后创建该接口中使用的域对象的适配器(请记住,Facade 仍然保存其他子系统的域模型),因此它符合您的模型。
许多设计模式都可以用于领域建模。对于外观和适配器设计模式来说也是如此。尽管这两种模式之间的区别在“设计模式”领域可能并不明显,但在“领域建模”领域则更加明显。
The difference between these two patterns is clear, but not in the realm of Design Patterns, but Domain Modeling. In the following, I'll explain why.
First, I want to reiterate others have said here, and then I'll add the note:
A Facade is an interface to a subsystem (an external or a legacy system) that simplifies the access for the client (us). Facade hides the interface of the other subsystem (aggregate some calls, or hide some APIs that we don't need), thus your client only accesses that subsystem through this Facade.
On the other hand, an Adapter is a wrapper around another service or object. It makes the wrapped object conform to a standard interface that the client expects. Let's say there is a method on the "Ledger" object, which you need to make a tweak (change its parameters, change its name, etc.). You can wrap it with an adapter.
Now, still the difference might not be clear. That's where I want to bring up the key difference between these two patterns leaving no room for further confusion:
Facade doesn't changes the domain model of the other subsystem, while Adapter does. This is the key difference. Period.
That's why you combine these two when you create an Anticorruption Layer. Let's say you have subsystem which you want to use, but you don't want its domain model to muddle your domain model. What would you do? You'd create an Anticorruption Layer. How? You first create a Facade, that simplifies accessing the interface for the subsystem, and then adapters for the domain objects used in that interface (remember the facade still holds the domain model for the other subsystem), so it conforms to your model.
Many design patterns can be used in domain modeling. This is true for Facade and Adapter design patterns, as well. Although the difference between these two patterns might not be clear in "design pattern" realm, it's more clear in "domain modeling" realm.
像往常一样,几种模式之间存在相似之处。但我会这样看待它:
As usual, there exist similarities between several patterns. But I would see it like this:
适配器模式允许两个以前不兼容的接口相互协作。有 2 个独立的接口在使用。
外观模式采用已知的低级别/细粒度接口,并用更高级别/粗粒度接口包装它。有一个单一的接口,通过与另一个接口的包装来简化。
Adapter pattern allows two,previously incompatible, interfaces to work with each other. Has 2 separate interfaces in play.
The Facade pattern takes a known interface, that is low level/fine grained, and wraps it with a higher level/course grained interface. Has a single interface, that has been simplified by wrapping with another.
我将尝试用简单的语言来解释这一点,不要太正式。
想象一下,您有一些域类,并且您希望通过 UI 与它们进行交互。外观可用于提供可从 UI 层调用的函数,以便 UI 层不知道外观之外的任何域类。这意味着您不再调用域类中的函数,而是从外观调用单个函数,该函数将负责从其他类调用所需的函数。
另一方面,适配器可用于集成其他外部组件,这些组件可能具有您所需的相同功能,但它们的功能调用方式并不完全相同。假设您的域中有一个
Car
类,并且您与一个也定义了 Car 类的外部汽车提供商合作。在此类中,您拥有函数car.getDoors()
,但外部提供程序具有等效的car.getNumDoors()
。您不想更改调用此函数的方式,因此可以使用适配器类来包装外部 Car 类,以便将对适配器的getDoors()
的调用委托给getNumDoors()。
I'll try to explain this in plain words, without much formality.
Imagine you've got some domain classes and from the UI you want to interact with them. A facade can be used to provide functions that can be called from the UI layer so that the UI layer doesn't know about any domain classes other than the facade. That means instead of calling the functions in the domain classes you call a single function from the facade, which will be responsible of calling the needed functions from the other classes.
An adapter, on the other hand, can be used to integrate other external components that might have the same functionality you need but their functions are not called quite the same way. Say you've got a
Car
class in your domain and you work with an external car provider that has a Car class defined as well. In this class, you've got the functioncar.getDoors()
but the external provider has the equivalentcar.getNumDoors()
. You don't want to change the way you call this function, so you can use an adapter class to wrap the external Car class so that a call togetDoors()
of the adapter is delegated togetNumDoors()
of the external class.适配器使两个接口一起工作。
Facade 将单个类暴露到更高、更有限的级别。例如,视图模型外观可能仅公开较低级别类的某些只读属性。
Adapter makes two interfaces work together.
Facade exposes a single class to a higher, and more limited level. For example, a view model facade may only expose certain read only properties of a lower level class.
适配器模式通过提供新的接口来链接两个不兼容的接口。
外观模式通过单个接口简化了复杂的子系统(具有多个组件)。
Adapter pattern links two incompatible interfaces by providing a new interface.
Facade pattern simplifies a complex subsystem(having multiple components) with a single interface.
外观
抽象复杂性以提供更简单的界面。例如,计算机操作系统抽象了底层硬件的复杂性。或者,与低级语言(C)相比,高级编程语言(Python/JavaScript)抽象了复杂性。
适配器
它类似于硬件适配器。假设您要将
USB 设备
连接到串行端口
,您将需要一个USB 串行端口适配器
。Facade
Abstracts complexity to provide a simpler interface. Say for example, an computer OS abstracts the complexity of underlying hardware. Or a high-level programing languages(Python/JavaScript) abstracts complexity when compared to a low-level language(C).
Adapter
It's analogues to a hardware adapters. Say you want to connect a
USB device
to aserial port
, you will need aUSB-serial port adapter
.Facade 模式的主要目标是使类或子系统更易于使用,而 Adapter 模式的主要目标是将接口调整为客户端期望的内容。
The main goal of the Facade pattern is to make the class or subsystem easier to use, while the main goal of the Adapter pattern is to adjust the interface to what the client expects.
真的 ?
我注意到术语适配器有时被用来描述事实上的策略,也许是因为这个词更具表现力。
例如,在 Zend Framework 中,所有 Adapter 类实际上都是 Strategy 模式的实现,因为它们仅将本机代码包装在类后面,有几种行为。
适配器通常用于包装遗留或“旧式”代码。
Really ?
I have noticed that the term Adapter is sometimes used to describe what is in fact a Stategy, maybe because the word is more expressive.
For example, in Zend Framework, all the Adapter classes are in fact implementations of the Strategy pattern, because they only wrap native code behind classes, to have several behaviours.
Adapters are often used to wrap legacy or "old-style" code.