4.5-Facade-外观-结构型模式
用途
- 定义一个高层接口,为子系统的一组接口提供一个一致的界面,使得子系统更加易用
- Facade/fəˈsɑd/ 还可以降低子系统间的依赖关系

示例
有一个编译子系统,包含了若干个类来实现这一编译器,如 Scanner、Parse 等。
- 多数普通用户不关心语法分析等细节,只是希望实现一些代码。
- 因此子系统提供一个 Compiler 对象提供统一的高层接口,隐藏了内部实现
- 对于了解内部细节、有特殊需求的高级用户,可以绕过外观类 Complier 使用低层类实现功能
- 外观类不会隐藏内部实现

- 外观类不会隐藏内部实现
适用性
- 当你要为一个复杂子系统提供一个简单接口时。
- Facade 可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够
- 而那些需要更多的可定制性的用户可以越过 Facade 层。
- 客户程序与抽象类的实现部分之间存在着很大的依赖性。引入 Facade 将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
- 当你需要构建一个层次结构的子系统时,使用 Facade 模式定义子系统中每层的入口点。
- 如果子系统之间是相互依赖的,可以让它们仅通过 Facade 进行通信,从而简化了它们之间的依赖关系。
结构

- Facade:知道系统的内部结构,并将客户请求代理给适当的子系统对象
- Subsystemclasses:
- 实现子系统的功能,处理 Facade 分派的任务
- 没有 Facade 的任何信息
使用 Facade 的客户程序不需要直接访问子系统对象,而通过发送请求给 Facade 的方式与子系统通信。Facade 将这些消息转发给适当的子系统对象。
优缺点
优点:
- 对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。
- 它实现了子系统与客户之间的松耦合关系(子系统内部的功能组件往往是紧耦合的)
- Facade 模式有助于建立层次结构系统
- Facade 模式可以消除复杂的循环依赖关系
- Facade 模式同样也有利于降低编译依赖性,使得编译一个子系统一般不需要编译所有其他的子系统。
- 如果应用需要,它并不限制它们使用子系统类。因此你可以在系统易用性和通用性之间加以选择。
实现
- 进一步降低客户-子系统耦合度的方法:
- Facade 定义为抽象类而其具体子类对应不同的子系统实现可以进一步降低客户和子系统的耦合度
- 还可以用不同的子系统对象配置 Facade 对象
- 公共子系统类与私有子系统类:子系统和一个类都可用于功能的封装,相应地可以考虑提供公有和私有接口
- 子系统的公共接口包含所有的客户程序可以访问的类(包括 Facade),私有接口仅用于对子系统进行扩充
相关模式
Abstract Factory(3.1)模式可以与 Facade 模式一起使用以提供一个接口,这一接口可用来以一种子系统独立的方式创建子系统对象。 Abstract Factory 也可以代替 Facade 模式隐藏那些与平台相关的类。
Mediator(5.5)模式与 Facade 模式的相似之处是,它抽象了一些已有的类的功能。然而,Mediator 的目的是对同事之间的任意通信进行抽象,通常集中不属于任何单个对象的功能。Mediator 的同事对象知道中介者并与它通信,而不是直接与其他同类对象通信。相对而言,Facade 模式仅对子系统对象的接口进行抽象,从而使它们更容易使用;它并不定义新功能,子系统也不知道 Facade 的存在。
通常来讲,仅需要一个 Facade 对象,因此 Facade 对象通常属于 Singleton(3.5)模式。
facade 定义一个新的接口,而 Adapter 则复用一个原有的接口(适配器使两个已有的接口协同工作而非定义新的接口)

