外观模式 vs. 单一职责原则

8
在经典的外观模式中,通常一个对象为更复杂的东西提供了一个简化的接口。
正如Gang-of-Four所说的那样(尽可能地接近“官方”):
外观(185)为子系统中一组接口提供了一个统一的接口。外观定义了一个更高级别的接口,使子系统更容易使用。
还有
...一个外观仅仅抽象出子系统对象的接口,使它们更易于使用;它不定义任何新功能,并且子系统类也不知道它。
或者,正如Unmesh在https://dev59.com/9m435IYBdhLWcg3wvys5#5242476中所说:
外观屏蔽了用户对系统复杂细节的认识,并为他们提供了一个简化的视图,易于使用。它还将使用系统的代码与子系统的详细信息解耦,使以后修改系统变得更容易。
单一职责原则建议我们:
一个类或模块应该有一个,而且只有一个,改变的原因。
根据Bob叔叔(http://en.m.wikipedia.org/wiki/Single_responsibility_principle)的说法,由于Facade的设计使用户屏蔽了多种“更改原因”,那么这两个想法如何共同工作呢? Facade是否有与其实现相关的子系统数量一样多的更改原因?

更改外观的原因有哪些? - PeeHaa
will clarify in the post - goofballLogic
2个回答

5

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

例外情况 - 如果存在错误或者需要更改Facade的业务逻辑(例如,封装在其中的子系统之间的交互),但这不违反SRP原则。

顺便说一下,在引用中似乎隐含地提到:

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


是的,那种解释有点合理,除了门面模式的任务之一是保护消费者免受底层系统变化的影响。如果这值得做,难道不意味着这些系统足够复杂,以至于它们的接口会随着版本变化而改变吗? - goofballLogic
我明白你的意思。是的,如果您必须更新特定子系统的接口,则意味着您已经违反了该接口的接口隔离原则。而且不要忘记开闭原则 - 最好扩展现有的接口/类,而不是更新其内部内容。 看起来在构建新类时,您必须了解所有SOLID原则 :) - Witcher

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;
   }
}

更新我的问题以反映“GoF”的正式外观定义。 - goofballLogic
1
你的示例门面并不完全符合门面模式的经典定义,至少在面向对象的圈子里是这样。 - goofballLogic
我所描述的定义来自Ross Harmes和Dustin Diaz的书《JavaScript设计模式》(第141页)。至于你反映的更改,我会为那些“门面”实现一个接口,因为现在实现将依赖于抽象而不是具体实现,这将解决你的问题。 - Yang
是的,他们已经将这种模式适应到了JavaScript世界。我认为他们的模式被很好地标记为“Facade”,因为它包装了对多个潜在底层子系统的访问。然而,它与传统的Facade模式非常不同,其中Facade对象将包含多个方法,例如此方法。值得注意的是,即使在他们微小的“Facade”中,也有至少三个潜在的更改原因,因为支持三种不同的标准。 - goofballLogic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接