系统间耦合的复杂度

在A方案中,客户系统 与 子系统 产生了 很多紧耦合关系
image.png
【例子】很多系统中,都有数据访问系统

  • 数据访问涉及到很多层面的对象:连接对象、命令对象、数据表、参数对象等等
  • 如果不加约束,你很容易写出一种方案,外部对象(客户系统)会与连接对象、命令对象..进行直接的耦合
  • 这个耦合是非常不好的,能够看到系统非常的散漫

好的方案是什么,使用一个间接层(Facade)

  • 加一层接口,这一层的接口隔离,将连接对象、命令对象、参数对象、表接口隔离起来
  • 客户只能facade打交道,内部之间和Facade进行耦合

动机

上述A方案的问题在于组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合面临很多变化的挑战。

比如,如果数据库从MySQL改成Oracle,里面的数据连接、数据加载都可能会发生变化。如果没有用Facade模式,A方案就会有激烈的震动。而B方案,不管内部怎么变,外部的用法还是一致的。

模式定义

为子系统中的一组接口提供一个一致(稳定)的界面,Facade的模式定义了一个高层接口,这个接口使得这一子系统更加容易使用(复用)。——《设计模式》GoF。

实质上,就是用隔离的方式,把变化和稳定拆解开来。

结构

Facade模式没有一个特定的代码结构。甚至,代码结构看起来相差特别大的,千差万别的代码,可能都是Facade模式。

它只是第一种思想的表达,是一种子系统与客户系统之间解耦的方式。
image.png

要点总结

从客户程序的角度来看,Facade模式简化了整个组件系统的接口,对于组件内部与外部客户程序来说,达到了一种“解耦”的效果——内部子系统的任何变化不会影响到Facade接口的变化。

Facade设计模式要注重从架构的层次去看整个系统,而不是单个类的层次。Facade很多时候更是一种架构设计模式。
比如:计算机本身就是一个Facade模式的应用

  • 电脑有很多外部接口(显示器、键盘、鼠标、电源、USB等等),这些接口是和用户打交道的,不变的
  • 但内部的CPU、内存条、硬盘、主板,是产品在更新换代中经常会变的。但面向用户的外部接口是不变的

Facade设计模式并非一个集装箱,可以任意地放进任何多个对象。Facade模式中组件的内部应该是“相互耦合关系比较大的一系列组件”,而不是一个简单的功能集合。