`
flysky
  • 浏览: 65545 次
社区版块
存档分类
最新评论

设计模式(15)-Facade Pattern(zz)

    博客分类:
  • java
阅读更多
原文:http://www.cnblogs.com/zhenyulu/articles/55992.html


一、 门面(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()
  {
    camera1.TurnOn();
    camera2.TurnOn();
    light1.TurnOn();
    light2.TurnOn();
    light3.TurnOn();
    sensor.Activate();
    alarm.Activate();
  }

  public void Deactivate()
  {
    camera1.TurnOff();
    camera2.TurnOff();
    light1.TurnOff();
    light2.TurnOff();
    light3.TurnOff();
    sensor.Deactivate();
    alarm.Deactivate();
  }
}

public class Client
{
  private static SecurityFacade security;

  public static void Main( string[] args )
  {
    security = new SecurityFacade();
    security.Activate();
    Console.WriteLine("\n--------------------\n");
    security.Deactivate();
  }
}



参考文献:
阎宏,《Java与模式》,电子工业出版社
[美]James W. Cooper,《C#设计模式》,电子工业出版社
[美]Alan Shalloway  James R. Trott,《Design Patterns Explained》,中国电力出版社
[美]Robert C. Martin,《敏捷软件开发-原则、模式与实践》,清华大学出版社
[美]Don Box, Chris Sells,《.NET本质论 第1卷:公共语言运行库》,中国电力出版社
posted on 2004-10-24 00:13 吕震宇 阅读(6640) 评论(10)  编辑 收藏 引用 网摘 所属分类: 设计模式

评论
# re: 设计模式(15)-Facade Pattern 2004-10-25 09:09 HiRong
通过这个例子我只看到你将复杂度从一个类移到另一个类而已,并不能看到Facade Pattern的好处。如果再增加一个对象,比如说后勤人员可以控制一些灯的开和关,这时才能体现出Facade Pattern的用途。  回复  更多评论
 

# re: 设计模式(15)-Facade Pattern 2004-10-25 09:36 lichdr
還是能看到好處的,就是寫前端的人不用管後端的事,它只跟那個facade打交道就行了。前後端隔離了

當然前後端一個人干的就沒只是把複雜度從一個類到另 一個類而已了。  回复  更多评论
 

# re: 设计模式(15)-Facade Pattern 2004-11-17 17:28 luoluo
这个例子客户端需要调用服务来做的事情的流程 不是很复杂

医院的例子更好一些 病人要看病 需要做一系列的事情 比较复杂

facade就显得很方便  回复  更多评论
 

# re: 设计模式(15)-Facade Pattern 2005-08-01 10:00 BigHead
如果有很多Client这就体现出好处,可以试想下,如果Camera Light Sensor Alarm这几个类的实现改变了导致使用类也要改变的话,直接修改SecurityFacade就可以了.前提是这些改变不会导致连 SecurityFacade的接口也要改变.这就给维护带来了很好的简单性,这也就是松耦合带来的好处了.




facade模式的其他相关内容:
1.谁能给我解释下Facade模式???
http://www.javanb.com/j2ee/1/10508.html
我来举例子帮你说明:

1)、假设你有一个类,里面分别提供了对某表的insert,update,delete,select方法。如果人家要对此表操作,就调用你这个类。可是你想这么做:对于那些高安全性的开发者,你可以给整个类的各种方法。可是对那些低安全性的开发者(比如第三方合作者),就只给select方法。
于是你再做了一个类,只有select方法(其实就是调用前面那个类的select),把这个facade类开发给低安全性开发者。这就是facade的第一个作用:隐藏

2)、假设你有多个类,分别管理多表的操作。现在有个需求,可能一个事务涉及到多表的操作(比如用户登录,先要在用户表验证密码,然后再到登录日志表记一笔),那么你可以做一个facade,把这一系列的操作封装成一个方法。人家不用跟底层的单表打交道,只简单调用你的facade的方法就OK。这就是 facade的第二个作用:封装

其他的作用我不清楚,我也没用过。但就上面这2个作用,让你有充分的理由用FACADE。

2.设计模式之Facade(外观 总管 Manager)
http://java.ccidnet.com/art/3741/20040325/542091_1.html

Facade模式的定义: 为子系统中的一组接口提供一个一致的界面.
Facade一个典型应用就是数据库JDBC的应用.

3.关于JDBC facade 的疑问
http://www.jdon.com/jive/thread.jsp;jsessionid=8C27EB638A4561796FB7BF7DC68CDD07?forum=91&thread=6316
一个facade 要这样
private static ConnectionManager connManager = null;
private Connection conn = null;
private Statement stmt = null;
private PreparedStatement prepstmt = null;
private CallableStatement callstmt = null;


可能还有
private ResultSet rs = null;
private ResultSetMetaData rsmd = null;

实现的一个类是很大的,而且每次调用都要new facade
这样是否有问题?

我的意思是说 每次都生成这样大的一个对象,是不是很慢?


re: 当然 你使用singleton
分享到:
评论

相关推荐

    C#设计模式-吕震宇

    设计模式(15)-Facade Pattern 设计模式(14)-Flyweight Pattern C#设计模式(13)-Proxy Pattern C#设计模式(12)-Decorator Pattern C#设计模式(11)-Composite Pattern C#设计模式(10)-Adapter ...

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

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

    设计模式精解-GoF-23种设计模式解析--附C++源代码

    设计模式是软件工程中的一种最佳实践,用于解决在软件开发过程中常见的问题。这些模式是由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位大师,通常被称为GoF(Gang of Four),在他们的经典著作...

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

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

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

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

    design-pattern-java.pdf

    扩展系统功能——装饰模式(三) 扩展系统功能——装饰模式(四) 外观模式-Facade Pattern 深入浅出外观模式(一) 深入浅出外观模式(二) 深入浅出外观模式(三) 享元模式-Flyweight Pattern 实现对象的复用——...

    设计模式精解-GoF 23种设计模式解析附C++实现源码

    ### 设计模式精解——GoF 23种设计模式解析及C++实现源码 #### 引言 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。GoF(Gang of Four)所提出的23种设计模式,被认为是面向对象...

    base-facade.zip

    "base-facade.zip"这个压缩包文件的名称暗示了其内容可能与软件设计模式中的“基类门面”(Base Facade)有关。在软件工程中,门面模式是一种结构型设计模式,它提供了一个统一的接口,用来简化一个复杂的系统或者子...

    设计模式 - Design Pattern

    "Design Pattern"这个压缩包文件很可能包含了一些关于设计模式的实例和文档,特别是提到了"design-pattern\doc\api"目录下的"index.html",这可能是一个交互式的文档或者教程,通过实例帮助开发者更好地理解设计模式...

    设计模式精解-GoF 23种设计模式解析附C++.pdf

    ### 设计模式精解——GoF 23种设计模式解析及C++实现 #### 0. 引言 设计模式作为面向对象编程的核心组成部分,是软件开发者在长期实践中总结出来的最佳实践。通过深入理解这些设计模式,我们可以更好地进行面向...

    Laravel开发-laravel-facade-dump

    在Laravel框架中,"Laravel开发-laravel-facade-dump"是一个项目或工具,其目的是为了创建Laravel立面(Facade)结构的JSON转储。这个转储可以帮助开发者理解Laravel Facades的工作原理,并生成最新的备忘单,便于在...

    vue-input-facade:专为Vue创建的轻量级且无依赖的输入屏蔽库

    import { InputFacade , facade , filter } from 'vue-input-facade' export default { components : { InputFacade } , directives : { facade } , filters : { facade : filter } , // ... rest of component

    CoreJava-DesignPattern

    CoreJava-DesignPattern 创意设计模式 -- Abstract Factory - Done -- Builder - Done -- Factory Method -- Object Pool -- Prototype - Done -- Singleton - Done 结构设计模式 -- Adapter -- Bridge -- ...

    java设计模式源码-DesignPattern:设计模式(Java实现源码)

    java 设计模式 源码 欢迎访问DesignPattern项目 DesignPattern项目是设计模式...外观模式(facadePattern) 享元模式(flyweightPattern) 代理模式(proxyPattern) 责任链模式(chainPattern) 命令模式(commandPatter

    设计模式整理代码-pattern.zip

    这里我们关注的是一个名为"pattern.zip"的压缩包文件,它包含了23种经典的设计模式,这些模式在实践中被广泛使用,提高了代码的可读性、可维护性和可扩展性。这篇文章将详细探讨这些设计模式及其应用。 首先,23种...

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

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

    08-Facade.rar

    门面(Facade)设计模式是一种结构型设计模式,它的主要目的是提供一个统一的接口,用来访问子系统中的多个接口,使子系统更加容易被使用。这个模式简化了客户端与复杂系统之间的交互,使得客户端无需了解子系统内部...

    设计模式精解-GoF23种设计模式解析附C++实现源码

    设计模式是软件工程中的一种重要思想,它是在特定情境下,为解决常见问题而形成的一套最佳实践。GoF(Gang of Four)23种设计模式是软件开发中的经典,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides...

    goshop-facade-ocr-2.2-SNAPSHOT.jar

    goshop-facade-ocr-2.2-SNAPSHOT.jar 发现没有此jar ,就传了

Global site tag (gtag.js) - Google Analytics