Facade(外观模式)
意图
为子系统中的一组接口提供一个一致的界面,_Facade_模式定义了一个高层接口,这个接口使得这一子系统更加易用。
动机
将一个系统划分成为若干个子系统有利于降低系统的复杂性。一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小。达到该目标的途径之一就是引入一个外观对象,它为子系统中较为一般的设施提供了一个单一而简单的界面。
比如,我们现在有一个Scheudle Server(调度服务器),它为客户提供了开机,读取初始化配置文件,加载驱动,释放资源,关闭文件,关闭电源等等API,而客户每次使用它,从开机到开始使用的每一步都需要自己配置,当然这些接口非常重要,但是我们就是想简单的使用,不需要自定义配置,因此,我们需要一套简单的接口,该接口会为我们完成机器的一系列操作,而我们只要专注于我们的具体业务逻辑。这_Facade_模式的作用。
适用性
在遇到以下情况使用_Facade_模式:
- 为一个复杂的系统提供一个简单的接口。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的简单类。这样使得系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制系统的用户带来了一些使用上的困难。_Facade_模式可以给我们一个缺省的配置,而这一配置对绝大多数用户足够了。比如我们使用电脑的时候,我们不会逐一项的对系统进行配置,它默认的配置对我们来说就够用了,而如果你要让系统提供web、ftp等服务时,为了达到最好的性能,就可能详细的配置一下。_Facade_就是我们需要的那个缺省配置。
- 当你需要构建一个层次结构的子系统时,使用_Facade_模式定义子系统中的每层入口点。如果子系统之间是相互依赖的,你可以使用_Facade_进行通讯,从而简化它们的依赖关系。
结构
参与者
- Facade
- 知道哪些子系统负责处理请求
- 将客户的请求代理给适当的子系统对象
- Subsystem classes
- 实现子系统功能
- 处理Facade指派的任务
- 没有Facade的信息,及没有指向Facade的引用或指针。
协作
- 客户程序通过发送请求给Facade的方式与子系统通讯,Facade将消息转发给合适的子系统对象。尽管是子系统的相关对象做实际的工作,但Facade模式本身也必须将它的接口转换成子系统的接口。
- 使用Facade的客户程序不需要直接访问子系统对象。
相关模式
_Abstract Factory_模式与_Facade_模式一起使用可以提供一个接口,这一接口可用来以一种子系统独立的方式创建子系统对象。_Abstract Factory_也可以代替_Facade_模式隐藏那些与平台相关的类。
_Mediator_模式与_Facade_模式的相似之处是,它抽象了一些已有的类的功能。然而,_Mediator_的目的是对同事之间的任意通信进行抽象,通常集中不属于任何单个对象的功能。_Mediator_的同事对象知道中介者并与它通信,而不是直接与其它同类对象通信。相对而言,_Facade_模式仅对于系统对象的接口进行抽象,从而使它们更容易使用:它并不定义新功能,子系统也不知道_Facade_的存在。
通常来讲,仅需要一个Facade对象,因此Facade对象通常属于_Singleton_模式。