原文地址: http://blog.csdn.net/deanjob/archive/2007/03/06/1522192.aspx
使用Facade模式可以说是后台设计和编码人员的一个必备素质。我不止碰到过一个这样的后台开发人员,他们认为只要把后台功能完成了就万事大吉,而没有站在后台使用者的角度来看一看自己写出来的代码。其实,我们写出来的后台代码是要给别人使用的,所以我们提供给使用者的接口要越简单越好,这不单是对使用者好,同时对开发者也是好处多多的,至少你的接口简单了,你和使用者的交流就容易了。
而Facade 模式中的Facade类正是这样一个用户接口,它和后台中的多个类产生依赖关系,而后台的客户类则只跟Facade类产生依赖关系。为什么要这么做?其中的原因十分简单:后台的开发者熟悉他自己开发的各个类,也就容易解决和多个类的依赖关系,而后台的使用者则不太熟悉后台的各个类,不容易处理和它们之间的依赖;因此,后台的开发者自己在Facade类中解决了与后台多个类之间的依赖,后台的使用者只需要处理和Facade类的依赖即可。
好了,闲话少说。我们下面就以几个具体的例子来看一看Facade模式是怎么使用的。实际编程中,能使用到Facade模式的情况有很多,以下就分两种情况来具体说一说Facade模式的使用。可能还会有其他的情况,大家在实践中也可以加以补充。
第一种情况,客户类要使用的功能分布在多个类中,这些类可能相互之间没有什么关系;客户在使用后台的时候,必须先初始化要使用到的功能所在的类,然后才能使用。这时候,适合将这些功能集中在一个Facade类里,还可以替用户做一些初始化的工作,以减轻用户的负担。
例如,以商店为例。假如商店里出售三种商品:衣服、电脑和手机。这三种商品都是由各自的生产厂商卖出的,如下:
public class CoatFactory
{
public Coat saleCoat()
{
……
return coat;
}
……
}
然后是电脑的厂家类:
public class ComputerFactory
{
public Computer saleComputer()
{
……
return computer;
}
……
}
最后是手机商类:
public class MobileFactory
{
public Mobile saleMobile()
{
……
return mobile;
}
……
}
如果没有商店,我们就不得不分别跟各自的生产商打交道,如下:
//买衣服
CoatFactory coatFactory = new CoatFactory();
coatFactory.saleCoat();
//买电脑
ComputerFactory computerFactory = new ComputerFactory();
computerFactory.saleComputer();
//买手机
MobileFactory mobileFactory = new MobileFactory();
mobileFactory.saleMobile();
对我们顾客来说,和这么多的厂家类打交道,这显然是够麻烦的。
这样,我们就需要创建一个商店类了,让商店类和这些厂家打交道,我们只和商店类打交道即可,如下:
public class Store
{
public Coat saleCoat()
{
CoatFactory coatFactory = new CoatFactory();
return coatFactory.saleCoat();
}
public Computer saleComputer()
{
ComputerFactory computerFactory = new ComputerFactory();
return computerFactory.saleComputer();
}
public Mobile saleMobile()
{
MobileFactory mobileFactory = new MobileFactory();
return mobileFactory.saleMobile();
}
}
好了,现在我们要买东西,不用去跟那么多的厂家类打交道了。
Store store =new Store();
//买衣服
store.saleCoat();
//买电脑
store.saleComputer();
//买手机
store.saleMobile();
呵呵,这样对我们客户类来说,是不是简单多了。
第二种情况客户要完成的某个功能,可能需要调用后台的多个类才能实现,这时候特别要使用Facade模式。不然,会给客户的调用带来很大的麻烦。请看下面的例子。
我经常看到后台编码人员,强迫它们的使用者写出如下的代码:
……
String xmlString = null;
int result = 0;
try
{
xmlString = gdSizeChart.buildDataXML(incBean);
String path = "D:/Eclipse3.0/workspace/PLMSuite/AppWeb/PM/productSpecification/gridfile.xml";
File f = new File(path);
PrintWriter out = new PrintWriter(new FileWriter(f));
out.print(xmlString);
out.close();
System.out.println("\r\n\r\n sumaryAction" + xmlString + "\r\n\r\n");
request.setAttribute("xmlString", xmlString);
}
catch(Exception ex)
{
ex.printStackTrace();
}
这段代码前面即省略号省略掉的一部分是客户类调用后台的一部分代码,是一个相对独立的功能。后面这一部分也是一个相对独立的功能,而后台代码设计人员却把这个功能留给客户类自己来实现。
我就很怀疑,让客户类做这么多事情,到底要你的后台做什么?你还不如直接把所有的事情都给客户类做了得了。因为,你后台做了一半,剩下的一部分给客户类做,客户类根本就不明白怎么回事,或者说他不清楚你的思路,这样做下去更加困难。可能这点逻辑对你来说,很简单。但使用者不明白你的思路啊,他不知道来龙去脉,怎么往下写?
如果在这里有一个Facade类,让它来做不该由客户类来做的事,是不是简单多了呢?如下是一个Facade类:
public class Facade
{
public static void doAll(PE_MeasTableExdBean incBean, HttpServletRequest request)
{
……
request.setAttribute(“xmlString”,Facade.getFromOut(incBean));
}
private static String getFromOut(PE_MeasTableExdBean incBean)
{
try
{
xmlString = gdSizeChart.buildDataXML(incBean);
String path = "D:/Eclipse3.0/workspace/PLMSuite/AppWeb/PM/productSpecification/gridfile.xml";
File f = new File(path);
PrintWriter out = new PrintWriter(new FileWriter(f));
out.print(xmlString);
out.close();
System.out.println("\r\n\r\n sumaryAction" + xmlString + "\r\n\r\n");
return xmlString;
}
catch(Exception ex)
{
ex.printStackTrace();
return null;
}
}
}
那么客户类的调用就是下面的样子:
Facade.doAll(incBean,request);
这样,客户是不是轻松多了?值得注意的是,Facade类中的getFromOut方法其实不应该在Facade类中,本文为了简单起见而放在了这个类中,对Facade类来说是不符合单一职责原则的。
最后总结一下第二种情况的模式。后台为实现某一个功能有如下类:
public class ClassA
{
public void doA()
{
……
}
……
}
public class ClassB
{
public void doB()
{
……
}
……
}
public class ClassC
{
public void doC()
{
……
}
……
}
如果客户类需要这样调用:
……
ClassA a = new ClassA();
a.doA();
ClassB b = new ClassB();
b.doB();
ClassC c = new ClassC();
c.doC();
……
那么就适合做一个Facade类,来替客户类来完成上述的功能,如下:
public class Facade
{
public void doAll()
{
ClassA a = new ClassA();
a.doA();
ClassB b = new ClassB();
b.doB();
ClassC c = new ClassC();
c.doC();
}
}
则客户类的调用如下:
……
Facade Facade = new Facade();
Facade.doAll();
分享到:
相关推荐
本文将深入探讨FACADE模式、Adapter模式以及Singleton和Proxy模式的基本概念、应用场景和关键要素。 首先,FACADE(外观)模式是一种接口型模式,它的主要作用是为复杂的子系统提供一个简单的接口,使得客户端无需...
设计模式之门面模式(Facade模式),介绍门面模式,实际例子分析,代码讲解等
**C++ Facade模式** Facade模式,又称为外观模式,是设计模式中的一种结构型模式。在软件工程中,它为子系统提供了一个统一的入口,简化了客户端对复杂子系统的访问,使得客户端无需了解子系统内部的具体实现细节。...
**Facade模式** Facade模式是一种设计模式,它提供了一个统一的接口,用来访问子系统中的一组接口。这个统一的接口使得客户端不必了解子系统组件的内部细节,简化了客户端与复杂系统之间的交互。在软件工程中,当一...
**Java实现的简单应用:Facade模式范例** Facade模式,也称为门面模式,是一种结构型设计模式,它提供了一个统一的接口,用于与复杂的子系统进行交互。这个模式简化了客户端与子系统之间的交互,使得客户端只需要...
**外观(Facade)模式**是一种结构型设计模式,它的主要目的是提供一个统一的接口,用于客户端访问复杂的子系统。在大型软件系统中,通常由多个模块或子系统组成,每个子系统都有自己的功能,而客户端可能需要与这些...
在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不需要... 这是第11节:结构型模式Facade外观模式
外观模式(Facade Pattern)是设计模式中的一种结构型模式,主要目的是为了解决复杂的系统接口问题,提供一个简单的统一入口,使得客户端可以更方便地使用系统。在Java中,外观模式通常用来隐藏系统的复杂性,对外只...
**Ajax与Facade模式** 在Web开发中,Ajax(Asynchronous JavaScript and XML)技术允许我们创建交互性更强、响应更快的网页。它通过在后台与服务器进行少量数据交换,实现了页面的部分更新,而无需刷新整个页面。...
在软件设计模式的世界里,`Command`(命令)和`Facade`(外观)模式是非常重要的两种设计模式。它们分别服务于不同的目的,但都是为了提高代码的可读性、可维护性和灵活性。 `Command`模式是一种行为设计模式,它将...
eclipse工程文件 包含代码 有助理解 门面(Facade)模式 <br>外部与一个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式。 <br>医院的例子 <br>用一个例子进行说明,如果把医院...
**外观(Facade)设计模式**是一种结构型设计模式,它为复杂的系统或子系统提供一个统一、简洁的接口,使得客户端可以更容易地与其交互。在软件工程中,当一个系统包含多个子系统或者组件,而这些子系统之间相互依赖...
在Java中,当你有一个复杂的子系统,而你希望客户端代码能够以一种更简洁、更易于理解的方式来与之交互时,就可以使用Facade模式。这个模式通过创建一个新类(外观类),将子系统中的一系列接口聚合到一起,客户端只...
**外观模式(Facade Pattern)**是一种结构型设计模式,它主要解决的是复杂系统或子系统对外暴露一个简单统一的接口,使得客户端无需关心内部复杂的交互细节。这种模式在实际开发中广泛应用,尤其在大型项目中,它能...
- **意图**:为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,使得这一子系统更加容易使用。 - **动机**:简化外部客户程序与系统间的交互接口,解耦外部客户程序的演化和内部子系统的变化...
实验内容: 1) 家庭影院中有CD机,DVD机,收音机Turner,录影机Recorder,功放Amplifier,升降屏幕Screen等,请为家庭影院系统设计一个请设计一个门面,通过它可以方便的操作其他设备放电影等。...
外观模式属于结构型模式,其意图是为子系统中的一组接口提供一个一致的界面,Façade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。在项目设计中,把一个系统划分成为若干个子系统由利于降低系统的...