或门面==网关?
11 回答
回顾 GoF 书中的 Facade 和 Martin Fowler 的 Gateway 的另一个答案中的链接,看来他们的重点是相反的方向。
Facade 为(一个或多个)外部客户提供了复杂内部结构的简单统一视图;
网关为应用程序的内部提供了一个简单统一的外部资源视图。
这种区别让我们专注于在设计中哪个更重要:
有了 Facade,外部系统就是我们的客户;如果它使外部接口更简单,最好增加面向内的复杂性。
有了网关,内部系统就是我们的客户;尽我们所能提供帮助,即使外部更复杂。
这两种模式在方式上非常相似它们都充当了某些东西的包装器。区别在于上下文:外观代表一组子系统,而网关可以代表任何功能。从这个角度来看,Facade对我来说是 Gateway 的具体案例(而不是相反)。
当我们认为使用子系统很复杂时,就会应用 Facade,或者如果我们想将多个子系统调用组合到一个 [方法] 执行中时,就会应用外观。然而,这并不一定意味着子系统不可访问,或者它们足够复杂。它只是意味着我们有子系统。
当我们想要包装一些东西并将它们以不同的方式公开时,就会应用网关。网关可能不是包装一个子系统,而只是一个相对复杂的功能。网关是一种通用模式,可以被认为是外观、代理和其他模式的基础。
如果仍需要示例进行说明:
Facade 可以通过查询支票账户子系统、信用账户子系统、储蓄子系统和后台子系统来计算客户的信用度(我想我在 GOF 书籍中看到过类似的例子)。
class MortgateFacade {
bool IsCreditWorth(string customerName) {
return !_checkingAccSystem.HasNegativeBalance(customerName) && !_creditAccSystem.HasNegativeCredit(customerName) && !_backOfficeSystem.IsInBlackList(customerName);
}
}
网关可以查询数据库表并通过ID返回客户。(是的,就是这么简单!)
class CustomersGateway {
Customer GetCustomer(int id) {
return _db.ExecuteOne("SELECT TOP 1 FROM CUSTOMERS WHERE CUSTOMER_ID="+id).AsCustomer();
}
}
[显然这是一个伪代码]
外观的意图由http://c2.com/cgi/wiki?FacadePattern给出
为子系统中的一组接口提供统一的接口。Facade 定义了一个更高级别的接口,使子系统更易于使用。这可用于将许多复杂的对象交互简化为单个界面。
这里的重点是设计一个隐藏复杂性的界面,我认为关键思想是在一个更有用的交互中隐藏多个细粒度的交互。因此,Facade 的重点是面向客户的。
网关模式不是原始 GOF 模式之一,我将其更多地视为企业集成模式,即比门面更高的层次。见福勒的定义
我认为网关主要是关于隐藏技术复杂性而不是接口复杂性——隐藏连接到大型机和外部系统的细节。事实上,我经常期望网关成为某种请求路由器,甚至可能根据请求细节选择不同的后端系统。所以我认为 Gateway 专注于它的门户。
显然,非正式的网关是门面,因为它隐藏了细节,但我认为当你实现 GOF 门面和 Fowler 网关时,你最终会做完全不同的事情。
这是福勒书中的直接引述:
虽然 Facade 简化了更复杂的 API,但它通常由服务的编写者完成以供一般使用。网关是由客户端为其特定用途编写的。此外,Facade 总是暗示与它所覆盖的接口不同的接口,而 Gateway 可以完全复制包装的外观,用于替换或测试目的。
【第十八章】
这可能会有所简化,但这是我的看法。
- 使用 Facade 模式时,您提供了其他人可以用来与您的应用程序对话的接口。示例:您已经实现了一些具有多个“模块”的应用程序,为了更轻松地访问“模块”,您创建了一个 Facade 以更轻松地与模块交互......单点联系。
- 使用网关模式时,您封装了一些您想要使用的外部部分。示例:您想使用日志记录但不想绑定到特定的日志记录框架,在这种情况下,您可以定义定义您要使用的功能的网关,并让网关处理与您想要的日志记录框架的交互利用。这使得将来更改日志框架变得容易。
我认为Gateway 是Facade 的一个特例——一个外部系统的外观。
简单地说,Facade 是一种设计模式,而 Gateway 是一种架构模式。
例如,应用程序网关是一种基础架构架构模式。该节点位于 DMZ 中,并将内部节点与只能连接到应用程序网关的外部客户端隔离开来。
当您考虑架构模式时,请考虑节点。当您考虑设计模式时,请考虑类/对象。
节点是以下的抽象:设备 - 硬件和系统软件 - 例如操作系统、平台/框架等。系统软件被“分配”给设备。节点“封装”了设备和系统软件,并与构成架构的其他节点相关。
网关是将服务器节点与客户端节点隔离的节点 - 客户端节点不能直接连接到服务器节点。网关接收连接,然后自己建立到目标节点的连接。
外观模式的主要价值是“简化”内部组件(在外观之后)的使用。可能是外观中的一个入口点或功能将使用内部组件的多个功能。如果网关带来了与它背后的 API 或组件的“简化”使用相同的价值,那么它可以被认为是一个门面。在其他情况下,网关可能只是架构的中间件、适配器、包装器或呼叫转发元素。或者一个网关可能身兼数职,比如简化几个流程、转发一些调用,同时还充当身份验证或授权中间件。因此,恕我直言网关是一种高度抽象的模式,可以包含一个或多个特定的结构模式,如外观、适配器、包装器、装饰器或中间件等。
Martin Fowler对网关的定义本质上是狭隘的(至少是这里的定义),并且更接近API 网关,其作用类似于格式装饰器。
就实现而言,网关可以做什么和不能做什么是没有限制的。它实际上是一个自己的应用程序,可以提供任何功能。
门面用于处理某些对象的图形,就像处理单个对象一样,网关用于连接两个不同的模块/系统。
要回答您的问题,我不会说 Facade==Gateway,而是说 Facade≈Gateway。我的意思是它们大致相等,基于上述不同意见,它们的不同之处尚不清楚。
您需要记住,设计模式和术语的关键组成部分之一是帮助更轻松地传达您的想法。话虽如此,如果您总是用外观说话,那么您将更有可能被理解,因为这是最常用的术语。
我倾向于将许多模式视为代理模式的特殊情况,而不必太担心它具体是哪一种。
IE:
Facade 是一堆复杂类的简单代理。
适配器是系统部分的代理,我们目前需要的接口不兼容
ETC...
从我在谷歌搜索“网关模式”中发现的内容来看,网关 == 代理:D