您的位置:首页 > 编程语言 > Java开发

java设计模式-门面模式Facade

2012-03-21 10:39 429 查看
设计模式》一书中对Facade模式的意图是这样叙述的:

为子系统中的一组接口提供一个统一接口。Facade模式定义了一个更高层的接口,使子系统更加容易使用。通过这个模式我们能够更容易地使用一个复杂的系统,要么只使用系统的一部分功能,要么是以特殊方式使用系统。这里我们的系统就很复杂,但我们只需要使用一部分功能。因此,我们最后得到了一个更简单、更容易使用,或者说按我们的需要量身订做的系统。



图6-2 将客户与子系统隔离开来
大多数工作还是需要由底层系统完成。Facade模式提供了一组容易理解的方法,这些方法使用底层系统来实现新定义的函数。
facade模式:关键特征

意图 希望简化原有系统的使用方式。需要定义自己的接口。
问题 只需要使用某个复杂系统的子集,或者,需要以一种特殊的方式与系统交互。
解决方案 Facade为原有系统的客户提供了一个新的接口。
参与者与协作者 为客户提供的一个简化接口,使系统更容易使用。
效果 Facade模式简化了对所需子系统的使用过程。但是,由于Facade并不完整,因此客户可能无法使用某些功能。
实现

定义一个(或多个)具备所需接口的新类。

让新的类使用原有的系统。



图6-3 Facade模式的通用结构图

Facade不仅可以用来通过方法调用创建更简单的接口,还能用来减少客户必须处理的对象数量。例如,假设有一个Client对象必须处理Database、Model、Element对象。Client必须首先通过Database对象打开数据库,获取Model对象,然后再查询Model对象,获取Element对象,最后请求Element对象的信息。如果能够创建一个可供Client查询的Database Facade,那么以上过程将容易得多(参见图6-4)。



如果Facade能够设计成无状态的(也就是说,其中没有存储状态),则一个Facade对象就能够被多个其他对象使用。在后面的第21章中,我将讲述如何实现这一点,其中用到了Singleton模式和Double-Checked Locking模式。

Facade模式提出了一种通用方法;它为我提供了起点。这个模式的Facade部分实际上就是创建了一个新的接口供客户使用,来代替系统的原有接口。我之所以能够这样做,是因为Client对象并不需要原系统提供的所有功能。

Facade模式还可以用来隐藏或者封装系统。Facade类能够将系统作为自己的私有成员包含进来。在此情况下,原系统将与Facade类联系起来,但Facade类的客户无需看到。
封装系统的原因很多,包括:
● 跟踪系统的使用情况——通过强制所有对系统的访问都必须经过 Facade,可以很容易地监视系统的使用情况。
● 改换系统——未来可能需要切换系统。通过将原系统作为 Facade 类的一个私有成员,可以最省力地将切换到新的系统。当然,可能还要做很多工作,但是至少我只需在一个地方修改代码(Facade类)就行了。
Facade的几个要点:
从客户程序的角度来看,Facade模式不仅简化了整个组件系统的接口,同时对于组件内部与外部客户程序来说,从某种程度上也达到了一种“解耦”的效果——内部子系统的任何变化不会影响到Façade接口的变化。
Façade设计模式更注重从架构的层次去看整个系统,而不是单个类的层次。Façade很多时候更是一种架构设计模式。
Façade设计模式并非一个集装箱,可以任意地放进任何多个对象。Façade模式中组件的内部应该是“相互耦合关系比较大的一系列组件”,而不是一个简单的功能集合。
注意区分Façade模式、Adapter模式、Bridge模式与Decorator模式。Façade模式注重简化接口,Adapter模式注重转换接口,Bridge模式注重分离接口(抽象)与其实现,Decorator模式注重稳定接口的前提下为对象扩展功能。
适用性:
1.为一个复杂子系统提供一个简单接口。
2.提高子系统的独立性。
3.在层次化结构中,可以使用Facade模式定义系统中每一层的入口。

实例:

门面模式应用背景:为复杂的子系统提供一个简单的接口

门面模式包括两种角色:门面角色和子系统角色.

门面角色:客户端可以调用的方法,此角色知晓一个或者多个子系统角色的功能和责任

子系统角色:可以同时包括一个或者多个子系统角色,不是单独的一个类,而是类的集合

下面看一个例子:

门卫通常需要抄作多种仪器,包括每种仪器的具体操作,这样子来说对于门卫来说工作量就增加了很多

出错的概率也变大了,一个合理的设计就是,为门卫设计一个统一控制的操作台,简化门卫的工作。

请看代码:

Client.java

/*

* 客户端通过安全门面来调用各个子系统

* 客户端角色

*/

public class Client {

public static void main(String[] args){

SecurityFacade sf = new SecurityFacade();

sf.active();

sf.inactive();

}

}

下面几个类的角色是子系统角色

Camera.java

/*

* 子系统角色,是一个功能的集合,一般是很多类的一个集合

*/

public class Camera {

public void run(){

System.out.println("摄像机启动");

}

public void stop(){

System.out.println("摄像机停止");

}

}

Ring.java

public class Ring {

public void run(){

System.out.println("门铃启动");

}

public void stop(){

System.out.println("门铃停止");

}

}

Sensor.java

public class Sensor {

public void run(){

System.out.println("监视器启动");

}

public void stop(){

System.out.println("监视器停止");

}

}

SecurityFacade.java

/*

* 门面角色

*/

public class SecurityFacade {

private Camera camera;

private Ring ring;

private Sensor sensor;

public SecurityFacade(){

camera = new Camera();

ring = new Ring();

sensor = new Sensor();

}

public void active(){

camera.run();

ring.run();

sensor.run();

}

public void inactive(){

camera.stop();

ring.stop();

sensor.stop();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: