门面模式还是网关模式?
在《设计模式》一书中审查Facade和另一个答案中的Martin Fowler的Gateway链接时,它们的重点似乎朝着相反的方向。
Facade为一个或多个外部客户端提供了对复杂内部的简单统一视图;
Gateway为应用程序的内部提供了对外部资源的简单统一视图。
这种区别让我们关注设计中哪个更重要:
在Facade中,外部系统是我们的客户;如果使外部接口更简单,则可以将复杂性面向内部添加。
在Gateway中,内部系统是我们的客户;即使外部看起来更复杂,也要给予它所有的帮助。
这两个模式在某种程度上非常相似,它们都作为某些东西的封装器。不同之处在于上下文:Facade覆盖了一组子系统,而Gateway可以覆盖任何功能。从这个角度来看,对我来说,Facade是Gateway的具体情况(而不是相反)。
当我们认为使用子系统很复杂或者想要将几个子系统调用分组到一个[方法]执行中时,就会应用Facade。然而,这并不意味着子系统不可访问,或者它们足够复杂。这只是意味着我们有子系统。
当我们希望包装某些内容并以不同的方式公开它们时,就会应用Gateway。Gateway可能不仅包装子系统,还包装相对复杂的功能。Gateway是一种通用模式,可以被视为Facade、Proxy和其他模式的基础。
如果需要进一步解释,请看以下例子:
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();
}
}
[显然这是伪代码]
重点在于设计一个隐藏复杂性的接口,关键是将多个细粒度的交互隐藏在一个更可用的交互中。因此,Facade的焦点是面向客户端。为一个子系统中的一组接口提供一个统一的接口。Facade定义了一个更高级别的接口,使子系统更容易使用。这可以用来简化多个复杂对象交互为单个接口。
这可能有些简化,但以下是我的理解:
尽管外观模式简化了更复杂的API,通常是由服务的编写者用于一般用途。网关是由客户端为其特定用途编写的。此外,外观总是意味着与其所覆盖的内容有不同的接口,而网关可以完全复制包装的外观,用于替代或测试目的。
[第18章]
门面模式用于将一些对象图像视为单个对象进行处理,而网关模式用于连接两个不同的模块/系统。