外观模式

外观模式


          外观模式:为子系统中的一组接口,提供一个一致的界面,此模式定义一个高层接口,这个接口使得这一子系统更加容易使用。

          外观模式,又称为门面模式,定义中提到的子系统是指在设计中为了降低复杂性根据一定的规则(比如业务、功能),对系统进行的划分。

          子系统中封装有一些类。客户程序在使用子系统的时候,可能会像下图一样零乱。


外观模式_第1张图片


          客户类紧紧地依赖在子系统的实现上,当子系统发生变化时,很可能要影响到客户类的调用,而且,子系统在不断优化、可重用化的重构路上,会产生更多更小的类,这对使用子系统的客户类来说要完成一个工作流程,似乎要记住的接口太多了。

          为了解决这种问题产生了外观模式,下图是使用了门面模式后的图,这样就减少了客户程序和子系统之间的耦合,增加了可维护性。


外观模式_第2张图片


          考虑使用外观模式的三个阶段:

          首先,在设计初期阶段,应该要有意识的将不同的两个层分离,比如经典的三层架构,就需要考虑在数据访问层和业务逻辑层,业务逻辑层和表示层的层与层之间建立外观Façade,这样就可以为复杂的子系统提供一个简单的接口,使得耦合大大降低。

          其次,在开发阶段,子系统往往因为不断地重构演化而变得越来越复杂,大多数的模式使用时也都会产生很多很小的类,这本是好事,但也给外部调用它们的用户程序带来了使用上的困难,增加外观Façade可以提供一个简单的接口,减少它们之间的依赖。

          第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但因为它包含非常重要的功能,新的需求开开发必须要依赖于它,此时用外观模式Façade也是非常适合的,可以为新系统开发一个外观Façade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Façade对象交互,Façade与遗留代码交互所有复杂的工作。


外观模式_第3张图片


          具体组成:

          客户角色:调用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的接口,直接开发新系统调用这些接口即可,可以减少很多不必要的麻烦。

你可能感兴趣的:(外观模式)