门面模式与SRP

时间:2015-04-16 07:56:58

标签: oop design-patterns solid-principles single-responsibility-principle facade

在经典的Facade模式中,单个对象通常为更复杂的东西提供简化的界面。

正如四人帮所说的那样(尽管接近“官方”......):

  

Facade(185)为子系统中的一组接口提供统一接口。 Facade定义了一个更高级别的界面,使子系统更易于使用。

  

...一个外观只是抽象出子系统对象的接口,使它们更容易使用;它没有定义任何新功能,子系统类也不知道它。

或者,正如Unmesh将其放入https://stackoverflow.com/a/5242476

  

Facade可以保护用户免受系统复杂细节的影响,并为用户提供易于使用的简化视图。它还将使用系统的代码与子系统的细节分离,使以后更容易修改系统。

单一责任原则告诉我们

  

一个类或模块应该只有一个,而且只有一个要改变的原因。

Per Uncle Bob(http://en.m.wikipedia.org/wiki/Single_responsibility_principle

鉴于Facade在设计上可以保护用户免受众多“改变的原因”的影响,这两个想法如何协同工作? Facade是否有与其实现所依赖的子系统数量一样多的理由进行更改?

2 个答案:

答案 0 :(得分:4)

基本上,如果你的 Facade 类实现依赖性倒置原则(它取决于抽象,而不是具体的实现),你将不需要修改它在未来。

例外 - 如果存在错误或者您需要更改Facade的业务逻辑(例如,它封装的那些子系统之间的交互)。但这不是SRP违规行为。

顺便说一句,好像它在引文中含蓄地提到:

  

Facade(185)为子系统中的一组接口提供统一接口

答案 1 :(得分:1)

首先,

模式和原则 - 是两个截然不同的东西。模式是解决问题的有效方法,而原则只不过是一个指导原则。

因此,比较它们将毫无意义,特别是因为它们在大多数情况下相互完成。

至于SRP的定义,“改变的一个原因”可以很容易解释:

图像,如果您构建汽车的对象,包括引擎,类型和类似的东西。因此,该对象的构造如下所示:

car = new Car(new Engine(), new Type());

那么如果你想更换那辆车的发动机怎么办?然后你只需要替换Engine的实例。这是改变的一个原因,因为你不接触它的其他部分。

至于外墙,你提供的定义过于笼统。外观只是另一种包装可能在某些环境下不可用的内容的方式。他们只是确保您的东西适用于所有环境。例如,JavaScript中有一个非常着名的事件监听器示例:

function click(object, handler){
   if (object.addEventListener != undefined){
     // For major browsers
     object.addEventListener(....);
   } else if (object.attachEvent != undefined){
     // For IE < 7
     object.attachEvent(...)
   } else {
     object.click = handler;
   }
}