外观模式
外观模式:为子系统中的一组接口,提供一个一致的界面,此模式定义一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式,又称为门面模式,定义中提到的子系统是指在设计中为了降低复杂性根据一定的规则(比如业务、功能),对系统进行的划分。
子系统中封装有一些类。客户程序在使用子系统的时候,可能会像下图一样零乱。
客户类紧紧地依赖在子系统的实现上,当子系统发生变化时,很可能要影响到客户类的调用,而且,子系统在不断优化、可重用化的重构路上,会产生更多更小的类,这对使用子系统的客户类来说要完成一个工作流程,似乎要记住的接口太多了。
为了解决这种问题产生了外观模式,下图是使用了门面模式后的图,这样就减少了客户程序和子系统之间的耦合,增加了可维护性。
考虑使用外观模式的三个阶段:
首先,在设计初期阶段,应该要有意识的将不同的两个层分离,比如经典的三层架构,就需要考虑在数据访问层和业务逻辑层,业务逻辑层和表示层的层与层之间建立外观Façade,这样就可以为复杂的子系统提供一个简单的接口,使得耦合大大降低。
其次,在开发阶段,子系统往往因为不断地重构演化而变得越来越复杂,大多数的模式使用时也都会产生很多很小的类,这本是好事,但也给外部调用它们的用户程序带来了使用上的困难,增加外观Façade可以提供一个简单的接口,减少它们之间的依赖。
第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但因为它包含非常重要的功能,新的需求开开发必须要依赖于它,此时用外观模式Façade也是非常适合的,可以为新系统开发一个外观Façade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Façade对象交互,Façade与遗留代码交互所有复杂的工作。
具体组成:
客户角色:调用facade角色来完成要得到的功能。
门面角色( facade):这是门面模式的核心,它被客户角色调用,因此它熟悉子系统的功能,它内部根据客户角色已有的需求预定了几种功能组合。
子系统角色:实现了子系统的功能,对它而言,facade角色就和客户角色一样是未知的,它没有任何facade角色的信息和链接。
Facade模式的一个典型应用就是进行数据库连接。
一般我们在每一次对数据库进行访问,都要进行以下操作:先得到connect 实例,然后打开connect 获得连接,得到一个statement,执行 sql 语句进行查询,得到查询结果集。
可以将这些步骤提取出来,封装在一个类里面,这样,每次执行数据库访问只需要将必要的参数传递到这个类中就可以了。
外观模式基本代码结构:
<span style="font-size:24px;">namespace 外观模式 { class Program { static void Main(string[] args) { Facade facade = new Facade(); facade.MethodA(); facade.MethodB(); Console.Read(); } } } //外观模式基本代码 //四个子系统的类 class SubSystemOne { public void MethodOne() { Console.WriteLine("子系统方法一"); } } class SubSystemTwo { public void MethodTwo() { Console.WriteLine("子系统方法二"); } } class SubSystemThree { public void MethodThree() { Console.WriteLine("子系统方法三"); } } class SubSystemFour { public void MethodFour() { Console.WriteLine("子系统方法四"); } } //外观类 class Facade { SubSystemOne one; SubSystemTwo two; SubSystemThree three; SubSystemFour four; public Facade() { one = new SubSystemOne(); two = new SubSystemTwo(); three = new SubSystemThree(); four = new SubSystemFour(); } public void MethodA() { Console.WriteLine("\n方法组A() ---- "); one.MethodOne(); two.MethodTwo(); four.MethodFour(); } public void MethodB() { Console.WriteLine("\n方法组B() ---- "); two.MethodTwo(); three.MethodThree(); } } </span>
什么时候使用外观模式:
1、当你要为一个复杂子系统提供一个简单接口时。
2、客户程序与抽象类的实现部分之间存在着很大的依赖性,引入facade 将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
3、当你需要构建一个层次结构的子系统时,使用facade 模式定义子系统中每层的入口点,如果子系统之间是相互依赖的,你可以让它们仅通过facade 进行通讯,从而简化了它们之间的依赖关系。
外观模式的优点:
1、它对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。
2、它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的,松耦合关系使得子系统的组件变化不会影响到它的客户。
3、Facade 模式有助于建立层次结构系统,也有助于对对象之间的依赖关系分层,Facade 模式可以消除复杂的循环依赖关系,这一点在客户程序与子系统是分别实现的时候尤为重要,在大型软件系统中降低编译依赖性至关重要,在子系统类改变时,希望尽量减少重编译工作以节省时间。
4、用Facade 可以降低编译依赖性,限制重要系统中较小的变化所需的重编译工作,Facade模式同样也有利于简化系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。
5、如果应用需要,它并不限制它们使用子系统类,因此,你可以让客户程序在系统易用性和通用性之间加以选择。
6、对于复杂难以维护的老系统,直接去改或去扩展都可能产生很多问题,分两个小组,一个开发Façade与老系统的交互,另一个只要了解Façade的接口,直接开发新系统调用这些接口即可,可以减少很多不必要的麻烦。