门面(Facade)模式

      门面模式是对象的结构模式。外部与一个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式。
子系统的客户端
       
如今的软件系统比较复杂,设计模式的任务就是协助设计师处理复杂系统的设计。
       设计师处理复杂系统的一个常见方法便是将其分而治之,把一个系统划分成几个较小的子系统。但是这么做后,发现一个子系统内仍然有太多的类要处理。而使用一个子系统的客户端往往只关注一些特定的功能,需要同时与子系统内部的许多对象打交道后才能达到目的,其对象图如下所示:
                                            门面(Facade)模式
       上图描述的是一个客户端必须与许多对象打交道才能完成一个功能,图中的大方框代表一个子系统。这就是一个种不便,它使得系统的逻辑变得不必要的复杂,不易复用,且难以维护。
  
医院的例子
       用一个例子说明,如果把医院看做一个子系统,按照部门的职能,这个系统可以划分为挂号、门诊、划价、取药等。看病人的病人要和这些部门打交道,就如同一个子系统的客户端与这个系统下的各个类打交道一样,不是一件容易的事。
       首先    病人必须先挂号,然后门诊。如果医生需要化验,病人必须先划价,然后缴款,才能到化验部去化验。化验完成后在回到门诊,如下图所示:  
                                            门面(Facade)模式
       上图所描述的就是病人在医院的体验,途中的方框代表医院。
       解决这种不便的方法便是引进门面模式。仍然通过医院的例子来说明,可以设置一个接待员的位置,由接待员负责代为挂号、划价、取药、门诊、交费等。这个接待员就是门面模式的体现,病人只接触接待员,由接待员负责和医院的各个部门打交道。如下图所示:
                                          门面(Facade)模式
 
什么是门面模式
       门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面对象(Facade)进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
      使用门面模式之后,子系统的客户端对象所面对的复杂关系就可以得到简化,如下图所示:

                                                 门面(Facade)模式
        上图描述的是经过门面模式改装后,一个子系统客户端与子系统内部类的关系,图中大方框代表一个子系统。
       如同医院的接待员一样,门面模式的门面类将客户端与子系统的内部复杂性分割开来,使得客户端只需要和门面对象打交道,而不需要和子系统内部的多个对象打打交道。

门面模式的结构
       门面模式是对象的结构模式。它只包含两个角色:
     (1)门面(Facade)角色:客户端可以调用这个角色的方法。此角色知晓相关的子系统的功能和责任。在正常情况下,门面角色会将所有从客户端发出的请求委派到相应的子系统中取。

     (2)子系统角色:在一个门面模式的系统中,可以有一个或者多个子系统角色,没一个子系统角色都不是一个单独的类,而是一个类的集合。每一个子系统都可以直接被客户端或者门面角色调用。子系统并不知道门面角色的存在,对子系统而言,门面只不过是另一个客户端而已。

门面模式的实现
      

为子系统增加新的行为
      
初学者往往以为通过继承一个门面类便可以在子系统中增加新的功能,这是错误的。门面模式的用意是为子系统提供一个集中化和简化的沟通管道,而不能像子系统中增加新功能。
      如果一个门面模式不能将子系统的所有行为提供给外界,那么可以通过修改门面类或者继承门面类的方法,使门面类或其子类能够将子系统的行为提供给外界。但是如果一个子系统没有某个行为,想通过修改门面类或者继承门面类的办法来提供这个新的行为是错误的。


在什么情况下使用门面模式
      
为一个复杂的子系统提供一个简单的接口
      
子系统往往因为不断演化而变得越来越复杂,使用门面模式可以使得子系统更具有可复用性。Facade模式可以提供一个简单的默认视图,对大多数用户来说这个视图已经足够用了,而那些需要进一步继承的用户可以越过Facade层直接对子系统进行继承。

子系统的独立性
      
一般而言,子系统和其他子系统之间、客户端与实现化层之间存在着很大的依赖性。引入Facade模式将一个子系统与它的客户端以及其他的子系统分离,可以提高子系统的独立性和可移植性。
层次化结构
     
在构件一个层次化的系统时,可以使用Facade模式定义系统中每一层的入口。如果层与层之间是相互依赖的,则可以限定他们仅通过Facade进行通信,从而简化了层与层之间的依赖关系。

迪米特法则
      
迪米特法则说:“只与你直接的朋友们通信”。迪米特法则要求每一个对象与其他对象的相互作用均是短程的,而不是长程的。只要可能,朋友的数目越少越好。换而言之,一个对象只应当知道它的直接合作者的接口。
     
门面模式创造出一个门面对象,将客户端所涉及的属于一个子系统的协作伙伴的数目减到最少,使得客户端与子系统内部的对象的相互作用被门面对象所取代。显然门面模式就是实现代码重构以便达到迪米特法则要求的第一个方式。

 















  
      

你可能感兴趣的:(门面(Facade)模式)