CH09-结构型-外观

模式动机

模式定义

外观模式(Facade Pattern),外部与子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。又称门面模式

模式结构

包含两种角色:

  • Facade:外观角色
  • SubSystem:子系统角色

类图

NAME

时序图

NAME

代码分析

模式分析

  • 根据单一职责原则,在软件中将一个系统划分为若干个子系统有利于降低整个系统的复杂性,一个最常见的目标是使子系统之间的通信和相互依赖关系达到最小,达到该目标的方式之一就是引入一个外观对象,来为子系统提供一个简单而单一的入口。
  • 外观模式也是迪米特法则的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度。
  • 该模式要求,一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂度分隔开,客户端则只需要与外观类交互,而不需要和子系统内部的诸多对象交互。
  • 该模式的目的在于降低系统的复杂度。
  • 该模式很大程度上提高了客户端使用上的便捷性,使得客户端无需关心子系统的内部细节。

优点

  • 对客户端屏蔽子系统组件,减少客户处理的对象数目,并使得子系统用起来更容易。
  • 实现客户端与子系统的松耦合,使子系统的组件变化不会影响到客户类,只需要调整外观类即可。
  • 降低大型系统中的编译依赖性,并简化了系统在不同平台之间的迁移过程,可以以一个更小粒度(子系统)修改、编译软件。
  • 只是提供了一个统一访问子系统的统一入口,并不影响用户直接使用子系统类。

缺点

  • 不能很好的限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
  • 在不引入抽象外观类的情况下,增加新的子系统可能要修改外观类或客户端的代码,违背了开闭原则。

适用场景

  • 当要为复杂子系统提供一个简单接口时可以考虑该模式。
  • 当客户与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。
  • 在层次化结构中,可以使用外观模式定义系统中的每一层接口,曾与曾之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。

模式扩展

  • 一个系统有多个外观类

    通常只有一个外观类,同时只有一个实例,即它是一个单例类。同时也可以定义多个外观类,分别于不同的特定子系统交互。

  • 不要通过外观类为子系统增加新的行为

  • 外观模式与迪米特法则

    外观类充当了客户与子系统之间的第三者,降低客户与系统的耦合度。

  • 引入抽象外观类

    该模式最大的缺点在于违背了开闭原则。当增减子系统时可以通过引入抽象外观类来解决该问题,客户端则针对抽象外观类编程。以增减具体外观类的方式来支持子系统的变更。