`
gstarwd
  • 浏览: 1511139 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Facade Pattern

阅读更多

 

一、 门面(Facade)模式

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

医院的例子

用一个例子进行说明,如果把医院作为一个子系统,按照部门职能,这个系统可以划分为挂号、门诊、划价、化验、收费、取药等。看病的病人要与这些部门打交道,就如同一个子系统的客户端与一个子系统的各个类打交道一样,不是一件容易的事情。

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

解决这种不便的方法便是引进门面模式。可以设置一个接待员的位置,由接待员负责代为挂号、划价、缴费、取药等。这个接待员就是门面模式的体现,病人只接触接待员,由接待员负责与医院的各个部门打交道。

什么是门面模式

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

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


二、 门面模式的结构

门面模式是对象的结构模式。门面模式没有一个一般化的类图描述,下图演示了一个门面模式的示意性对象图:

 

在这个对象图中,出现了两个角色:

门面(Facade)角色:客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。

子系统(subsystem)角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。


三、 门面模式的实现

一个系统可以有几个门面类

【GOF】的书中指出:在门面模式中,通常只需要一个门面类,并且此门面类只有一个实例,换言之它是一个单例类。当然这并不意味着在整个系统里只能有一个门面类,而仅仅是说对每一个子系统只有一个门面类。或者说,如果一个系统有好几个子系统的话,每一个子系统有一个门面类,整个系统可以有数个门面类。

为子系统增加新行为

初学者往往以为通过继承一个门面类便可在子系统中加入新的行为,这是错误的。门面模式的用意是为子系统提供一个集中化和简化的沟通管道,而不能向子系统加入新的行为。


四、 在什么情况下使用门面模式

  • 为一个复杂子系统提供一个简单接口
  • 提高子系统的独立性
  • 在层次化结构中,可以使用Facade模式定义系统中每一层的入口。


五、 一个例子

我们考察一个保安系统的例子,以说明门面模式的功效。一个保安系统由两个录像机、三个电灯、一个遥感器和一个警报器组成。保安系统的操作人员需要经常将这些仪器启动和关闭。

不使用门面模式的设计

首先,在不使用门面模式的情况下,操作这个保安系统的操作员必须直接操作所有的这些部件。下图所示就是在不使用门面模式的情况下系统的设计图。

 


可以看出,Client对象需要引用到所有的录像机(Camera)、电灯(Light)、感应器(Sensor)和警报器(Alarm)对象。代码如下:

using System;

public class Camera
{
  
public void TurnOn()
  
{
    Console.WriteLine(
"Turning on the camera.");
  }


  
public void TurnOff()
  
{
    Console.WriteLine(
"Turning off the camera.");
  }


  
public void Rotate(int degrees)
  
{
    Console.WriteLine(
"Rotating the camera by {0} degrees.", degrees);
  }

}


public class Light
{

  
public void TurnOff()
  
{
    Console.WriteLine(
"Turning on the light.");
  }


  
public void TurnOn()
  
{
    Console.WriteLine(
"Turning off the light.");
  }


  
public void ChangeBulb()
  
{
    Console.WriteLine(
"changing the light-bulb.");
  }

}


public class Sensor
{
  
public void Activate()
  
{
    Console.WriteLine(
"Activating the sensor.");
  }


  
public void Deactivate()
  
{
    Console.WriteLine(
"Deactivating the sensor.");
  }


  
public void Trigger()
  
{
    Console.WriteLine(
"The sensor has triggered.");
  }

}


public class Alarm
{

  
public void Activate()
  
{
    Console.WriteLine(
"Activating the alarm.");
  }


  
public void Deactivate()
  
{
    Console.WriteLine(
"Deactivating the alarm.");
  }


  
public void Ring()
  
{
    Console.WriteLine(
"Ringing the alarm.");
  }


  
public void StopRing()
  
{
    Console.WriteLine(
"Stop the alarm.");
  }

}


public class Client
{
  
private static Camera camera1, camera2;
  
private static Light light1, light2, light3;
  
private static Sensor sensor;
  
private static Alarm alarm;

  
static Client()
  
{
    camera1 
= new Camera();
    camera2 
= new Camera();
    light1 
= new Light();
    light2 
= new Light();
    light3 
= new Light();
    sensor 
= new Sensor();
    alarm 
= new Alarm();
  }
  

  
public static void Main( string[] args )
  
{
    camera1.TurnOn();
    camera2.TurnOn();
    light1.TurnOn();
    light2.TurnOn();
    light3.TurnOn();
    sensor.Activate();
    alarm.Activate();
  }

}

 

六、 使用门面模式的设计

一个合情合理的改进方法就是准备一个系统的控制台,作为保安系统的用户界面。如下图所示:

 

程序代码如下:

using System;

public class Camera
{
  
public void TurnOn()
  
{
    Console.WriteLine(
"Turning on the camera.");
  }


  
public void TurnOff()
  
{
    Console.WriteLine(
"Turning off the camera.");
  }


  
public void Rotate(int degrees)
  
{
    Console.WriteLine(
"Rotating the camera by {0} degrees.", degrees);
  }

}


public class Light
{

  
public void TurnOff()
  
{
    Console.WriteLine(
"Turning on the light.");
  }


  
public void TurnOn()
  
{
    Console.WriteLine(
"Turning off the light.");
  }


  
public void ChangeBulb()
  
{
    Console.WriteLine(
"changing the light-bulb.");
  }

}


public class Sensor
{
  
public void Activate()
  
{
    Console.WriteLine(
"Activating the sensor.");
  }


  
public void Deactivate()
  
{
    Console.WriteLine(
"Deactivating the sensor.");
  }


  
public void Trigger()
  
{
    Console.WriteLine(
"The sensor has triggered.");
  }

}


public class Alarm
{

  
public void Activate()
  
{
    Console.WriteLine(
"Activating the alarm.");
  }


  
public void Deactivate()
  
{
    Console.WriteLine(
"Deactivating the alarm.");
  }


  
public void Ring()
  
{
    Console.WriteLine(
"Ringing the alarm.");
  }


  
public void StopRing()
  
{
    Console.WriteLine(
"Stop the alarm.");
  }

}


public class SecurityFacade
{
  
private static Camera camera1, camera2;
  
private static Light light1, light2, light3;
  
private static Sensor sensor;
  
private static Alarm alarm;

  
static SecurityFacade()
  
{
    camera1 
= new Camera();
    camera2 
= new Camera();
    light1 
= new Light();
    light2 
= new Light();
    light3 
= new Light();
    sensor 
= new Sensor();
    alarm 
= new Alarm();
  }

  
  
public void Activate()
  
background-col
分享到:
评论

相关推荐

    设计模式之外观模式(Facade Pattern)

    **外观模式(Facade Pattern)**是一种结构型设计模式,它主要解决的是复杂系统或子系统对外暴露一个简单统一的接口,使得客户端无需关心内部复杂的交互细节。这种模式在实际开发中广泛应用,尤其在大型项目中,它能...

    外观模式(Facade Pattern)-结构型模式

    设计模式面面观(13):外观模式(Facade Pattern)-结构型模式 http://blog.csdn.net/fanweiwei/archive/2008/04/17/2299641.aspx

    c++-设计模式之外观模式(Facade Pattern)

    外观模式(Facade Pattern)是一种结构型设计模式,用于为复杂子系统提供一个简单的接口。它通过封装系统内部的复杂性,提供一个统一的接口,使得客户端能够更加方便地使用子系统的功能。这种模式通常用于简化代码、...

    外观模式 Facade Pattern

    ### 外观模式 (Facade Pattern) #### 概述 外观模式是一种重要的设计模式,属于结构型模式之一。其核心在于通过引入一个简单的接口来隐藏一个系统中存在的复杂性,从而简化了客户端对该系统的使用。该模式的主要...

    FacadePattern.unitypackage

    FacadePattern.unitypackage是C#版设计模式中的外观模式,采用unity举例和C#举例,详细说明了外观模式的用法。

    设计模式 之 “门面模式[Facade Pattern]”

    门面模式(Facade Pattern)是软件工程中一种常用的结构型设计模式,它的主要目的是提供一个统一的接口,用来简化系统中一组复杂的接口或类的使用。这个模式将复杂的子系统接口封装在一个简单的门面对象中,使得...

    Wrapper facade pattern

    **包装器外观模式(Wrapper Facade Pattern)** 包装器外观模式是一种软件设计模式,它将一个复杂的组件或者一组组件的接口进行简化,提供一个统一的、更易用的访问方式。这种模式通常用于隐藏底层系统的复杂性,为...

    设计模式面面观(14):享元模式(Facade Pattern)-结构型模式

    设计模式面面观(14):享元模式(Facade Pattern)-结构型模式 http://blog.csdn.net/fanweiwei/archive/2008/04/25/2326692.aspx

    解析C#设计模式编程中外观模式Facade Pattern的应用

    外观模式(Facade Pattern)是设计模式中的一种结构型模式,其主要目的是为了简化客户端与复杂系统之间的交互。在C#编程中,外观模式通常用于减少客户端对子系统组件的依赖,提供一个统一的、高层次的接口,使得...

    设计模式之外观模式 facade

    外观模式(Facade Pattern)是设计模式中的一种结构型模式,主要目的是为了解决复杂的系统接口问题,提供一个简单的统一入口,使得客户端可以更方便地使用系统。在Java中,外观模式通常用来隐藏系统的复杂性,对外只...

    [结构型模式] 外观模式的理解

    在给定的文件`FacadePattern.cpp`和`FacadePattern.h`中,我们可以预期看到C++实现的外观模式示例。通常,外观模式包含以下几个关键角色: 1. **外观(Facade)类**:这是对外部世界提供服务的接口,它封装了对子...

    Java24种设计模式,Java24种设计模式,24种设计模式,学会了这24种设计模式,可以打遍天下无敌手,设计模式非常重要

    7、门面模式FACADE PATTERN 8、适配器模式ADAPTER PATTERN 9、模板方法模式TEMPLATE METHOD PATTERN 10、建造者模式BUILDER PATTERN 11、桥梁模式BRIDGE PATTERN 12、命令模式COMMAND PATTERN 13、装饰模式...

    C#版 24种设计模式

    适配器模式(Adapter Pattern) 提供者模式(Provider Pattern) 外观模式(Facade Pattern) 享元模式(Flyweight Pattern) 原型模式(Prototype Pattern) 责任链模式(Chain of Responsibility Pattern) 中介者模式...

    常见设计模式的解读和对应代码示例,包括设计原则和软件工程中类之间的依赖关系

    1、基础概念 1.2 类间关系 关联关系(Association) 聚合关系(Aggregation) 组合关系(Composition) 依赖关系(Dependency) 泛化关系(Generalization) ...外观模式(Facade Pattern) 享元模式(Flyweight Pattern)

    C#设计模式_设计模式_C#_

    外观模式(Facade Pattern) 11. 享元模式(Flyweight Pattern) 12. 代理模式(Proxy Pattern) 行为型: 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 16. 观察者...

    用Java实现23种设计模式

    外观模式(Facade Pattern) 享元模式(Flyweight Pattern) 代理模式(Proxy Pattern) 3. 行为型模式 责任链模式(Chain of Responsibility Pattern) 命令模式(Command Pattern) 解释器模式(Interpreter...

    23种设计模式 (创建型,结构型,行为型)

    外观模式(Facade Pattern) 11. 享元模式(Flyweight Pattern) 12. 代理模式(Proxy Pattern) 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 行为型: ...

    设计模式代码——c#

    10. 外观模式(Facade Pattern) 11. 享元模式(Flyweight Pattern) 12. 代理模式(Proxy Pattern) 行为型 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) ...

Global site tag (gtag.js) - Google Analytics