Facade外观模式

转载 2007年10月11日 09:23:00

Facade外 观模式,是一种结构型模式,它主要解决的问题是:组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合 面临很多变化的挑战。在这里我想举一个例子:比如,现在有一辆汽车,我们(客户程序)要启动它,那我们就要发动引擎(子系统1),使四个车轮(子系统2)转动。但是实际中我们并不需要用手推动车轮使其转动,我们踩下油门,此时汽车再根据一些其他的操作使车轮转动。油门就好比系统给我们留下的接口,不论汽车是以何种方式转动车轮,车轮变化成什么牌子的,我们要开走汽车所要做的还是踩下油门。

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

Façade外观模式的结构大概是这样的:

       这个图是我对Facade模式的理解,如果大家觉得有什么不对的地方欢迎给我指出。

       我就上面说的那个情形写一下实现代码,首先我们要实现三个子系统(WheelEngineBody):

  internal class Wheel

    {

        public string WheelCircumrotate()

        {

            return "BMW's Wheel is Circumrotating";

        }

 

        public string WheelStop()

        {

            return "BMW's Wheel is stoped";

        }

    }


  internal class Wheel

    {

        public string WheelCircumrotate()

        {

            return "BMW's Wheel is Circumrotating";

        }

 

        public string WheelStop()

        {

            return "BMW's Wheel is stoped";

        }

    }

   

  internal class Body

    {

        public Wheel[] wheels = new Wheel[4];

        public Engine engine = new Engine();

        public Body()

        {

            for (int i = 0; i < wheels.Length; i++)

            {

                wheels[i] = new Wheel();

            }

        }

}

 

  

 

然后,我们再来实现汽车的Facade

class CarFacade

    {

        Body body = new Body();

 

        public void Run()

        {

            Console.WriteLine(body.engine.EngineWork());

            for(int i = 0; i < body.wheels.Length; i++)

            {

                             Console.WriteLine(body.wheels[i].WheelCircumrotate());

            }

        }

 

        public void Stop()

        {

            Console.WriteLine(body.engine.EngineStop());

            for (int i = 0; i < body.wheels.Length; i++)

            {

                Console.WriteLine(body.wheels[i].WheelStop());

            }

        }

}


 

现在我们来使用客户端程序验证一下,代码如下:

class Program

    {

        static void Main(string[] args)

        {

            CarFacade car = new CarFacade();

            car.Run();

            car.Stop();

            Console.Read();

        }

}

      

       执行结果如下;

       BMW's Engine is Working

BMW's Wheel is Circumrotating

BMW's Wheel is Circumrotating

BMW's Wheel is Circumrotating

BMW's Wheel is Circumrotating

BMW's Engine is stoped

BMW's Wheel is stoped

BMW's Wheel is stoped

BMW's Wheel is stoped

BMW's Wheel is stoped

 

正如上面所说:客户端代码(Program)不需要关心子系统,它只需要关心CarFacade所留下来的和外部交互的接口,而子系统是在CarFacade中聚合。

 

Façade模式的几个要点:

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

2Facade设计模式更注重从架构的层次去看整个系统,而不是单个类的层次。Facade很多时候更是一种架构设计模式。


 =====================================================================


外部与一个子系统的通讯必须通过一个统一的门面(Facade)对象进行,这就是Facade模式。

  现代的软件系统都是比较复杂的,设计模式的任务就是协助设计师处理复杂系统的设计。

   设计师处理复杂系统的一个常见方法便是将其"分而治之",把一个系统划分为几个较小的子系统。但是这样做了以后,设计师往往仍然会发现一个子系统内仍然 有太多的类型要处理。而使用一个子系统的使用端往往只关注一些特定的功能,却要同时与子系统内部的许多对象打交道后才能达到目的,请见下面的对象图。


图4、Facade架构模式的结构图。

  这就是一种不便,它使得系统的逻辑变得不必要的复杂,维护成本提高,复用率降低。

  用一个范例说明,中国大陆的医院便是一个子系统,按照部门职能,这个系统可以划分为挂号、门诊、划价、化验、收银、取药等。看病的病人要与这些部门打交道,就如同一个子系统的使用端与一个子系统的各个类型打交道一样,不是一件容易的事情。

  首先病人必须先挂号,然后门诊。如果医生要求化验,病人必须首先划价,然后缴款,才能到化验部门做化验。化验后,再回到门诊室,请见下面的对象图。


图5、描述病人在医院里的体验。图中的方框代表医院。

  解决这种不便的方法便是引进Facade模式。仍然通过医院的范例说明,可以设置一个接待员的位置,由接待员负责代为挂号、划价、缴费、取药等。这个接待员就是Facade模式的体现,病人只接触接待员,由接待员负责与医院的各个部门打交道,请见下面的对象图。


图6、描述经过Facade模式的改装后,病人在医院里的体验。图中的方框代表医院。

  Facade模式要求一个子系统的外部与其内部的通讯必须通过一个统一的门面(Facade)对象进行。Facade模式提供一个高等级的接口,使得子系统更易于使用。

  使用了Facade模式之后,本章的第一个图中所描述的一个子系统的使用端对象所面对的复杂关系就可以简化为下面这个样子。


图7、Facade架构模式的结构图

  描述经过Facade模式的改装后,一个子系统的使用端与子系统的关系。图中的大方框代表一个子系统。

  就如同医院的接待员一样,Facade模式的门面类型将使用端与子系统的内部复杂性分隔开,使得使用端只需要与门面对象打交道,而不需要与子系统内部的很多对象打交道。

浅谈JAVA设计模式之——外观模式(Facade)

一、概述 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 二、适用性 1.当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断...
  • l1028386804
  • l1028386804
  • 2015年05月07日 23:32
  • 3232

结合laravel Facade看外观模式怎么用?

在laravel中,我们经常通过facade来实现全局调用某个方法而不需要实例化一个对象,今天就来扒一扒它是怎样做到的。所有的Facade都是继承自同一个抽象父类Illuminate\Support\...
  • Many7Hong7
  • Many7Hong7
  • 2016年10月02日 21:00
  • 1862

设计模式(结构型)之外观模式(Facade Pattern)

一个客户类需要和多个业务类交互,而这些业务类经常会作为整体出现,由于涉及到的类比较多,导致使用时代码较为复杂。外观模式通过引入一个新的外观类(Facade)来实现该功能,外观类为多个业务类的调用提供统...
  • yanbober
  • yanbober
  • 2015年05月04日 09:29
  • 2422

设计模式系列·Facade模式之MVC的烦恼

流行的MVC架构模式如今的Web开发,各种框架风起云涌,势如破竹。从国民第一的ThinkPhp到称霸全球的Laravel,这些框架有一个共同特征,都采用了MVC的架构模式。没有任何意外,王小二的公司用...
  • u011509781
  • u011509781
  • 2017年03月26日 17:20
  • 269

外观模式(Facade)

定义:为子系统中的一组接口提供一个一致的界面,Facede模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式的结构和说明:Facade:定义子系统的多个模块对外的高层接口,通常需要调...
  • qq924862077
  • qq924862077
  • 2016年11月29日 22:18
  • 506

设计模式C++实现:包装器外观模式(Wrapper Facade)

包装器外观模式(Wrapper Facade)把现有的非面向对象的API所提供的函数和数据,封装在更加简洁的、健壮的、可移植的、可维护的和内聚的面向对象的类接口中。 一般通过两种方式实现跨平台: ...
  • renyican
  • renyican
  • 2015年12月28日 11:43
  • 938

JAVA设计模式之门面模式(外观模式)

医院的例子   现代的软件系统都是比较复杂的,设计师处理复杂系统的一个常见方法便是将其“分而治之”,把一个系统划分为几个较小的子系统。如果把医院作为一个子系统,按照部门职能,这个系统可以划分为挂号、门...
  • jason0539
  • jason0539
  • 2014年04月02日 07:16
  • 25275

Unity3d之设计模式(四)外观模式

一、定义 外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 解释:简单来说,客户端需要调用一个特别复杂的子系统中的多个接口,如果直接...
  • qq563129582
  • qq563129582
  • 2016年12月15日 18:24
  • 663

Facade模式详解--设计模式(11)

Facade模式 一 意图   为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 二 动机   将一个系统划分成为若干个子系统有...
  • fanyun_01
  • fanyun_01
  • 2016年06月29日 08:57
  • 1214

c++设计模式-----Facade外观模式

Facade外观模式:          外观模式很简单,如果有一个系统,有许许多多的子系统的组成。而这这些系统在组成一个完整的系统的时候存在一定的关系,先使用哪个子系统,后使用哪个子系统,这是一个...
  • chenxun2009
  • chenxun2009
  • 2015年09月19日 21:10
  • 568
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Facade外观模式
举报原因:
原因补充:

(最多只允许输入30个字)