门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面对象(Facade)进行。
迪米特法则:只与你直接的朋友们通信。
此设计模式需要一个设计不是很好的系统进行改造来进行对比Facade倒底做些什么。
以下为一个设计不是很好的系统:
可以看出,Client对象需要引用到所有的Camera,Light,Sensor,Alarm对象。Client必须对保安系统全知全能,这是一个不利于复用的做法,源代码如下所示:
//Client.java
package
com.javapatterns.facade.security;
public
class
Client
{
static
private
Camera camera1 =
new
Camera();
static
private
Camera camera2 =
new
Camera();
static
private
Light light1 =
new
Light();
static
private
Light light2 =
new
Light();
static
private
Light light3 =
new
Light();
static
private
Sensor sensor =
new
Sensor();
static
private
Alarm alarm =
new
Alarm();
public
static
void
main(String[] args)
{
camera1.turnOn();
camera2.turnOn();
light1.turnOn();
light2.turnOn();
light3.turnOn();
sensor.activate();
alarm.activate();
}
}
//Camera.java
package
com.javapatterns.facade.security;
public
class
Camera
{
public
void
turnOn()
{
System.out.println(
"Turning on the camera."
);
}
public
void
turnOff()
{
System.out.println(
"Turning off the camera."
);
}
public
void
rotate(
int
degrees)
{
System.out.println(
"rotating the camera by "
+ degrees +
" degrees."
);
}
}
//Light.java
package
com.javapatterns.facade.security;
public
class
Light
{
public
void
turnOn()
{
System.out.println(
"Turning on the Light."
);
}
public
void
turnOff()
{
System.out.println(
"Turning off the Light."
);
}
public
void
changeBulb()
{
System.out.println(
"changing the light-bulb."
);
}
}
//Sensor.java
package
com.javapatterns.facade.security;
public
class
Sensor
{
public
void
activate()
{
System.out.println(
"Activating the sensor."
);
}
public
void
deactivate()
{
System.out.println(
"Deactivating the sensor."
);
}
public
void
trigger()
{
System.out.println(
"The sensor has been triggered."
);
}
}
//Alarm.java
package
com.javapatterns.facade.security;
public
class
Alarm
{
public
void
activate()
{
System.out.println(
"Activating the alarm."
);
}
public
void
deactivate()
{
System.out.println(
"Deactivating the alarm."
);
}
public
void
ring()
{
System.out.println(
"Ringing the alarm."
);
}
public
void
stopRing()
{
System.out.println(
"Ringing stopped."
);
}
}
一个合情合理的改进方法就是准备一个系统的控制台,作为安保系统的用户界面。用户只需要操作这个简化的界面就可以操控所有的内部仪器,这实际上就是门面模式的用意。
如下所示的设计图:
可以看出,门面SecurityFacade对象承担了与保安系统内部各个对象打交道的任务,而客户对象只需要与门面对象打交道即可。
这是客户端与保安系统之间的一个门户,使得客户端与子系统之间的关系变得简单和易于管理。
//Client.java
package
com.javapatterns.facade.securityfacade;
public
class
Client
{
private
static
SecurityFacade security =
new
SecurityFacade();
public
static
void
main(String[] args)
{
security.activate();
}
}
//SecurityFacade.java
package
com.javapatterns.facade.securityfacade;
public
class
SecurityFacade
{
private
Camera camera1 =
new
Camera();
private
Camera camera2 =
new
Camera();
private
Light light1 =
new
Light();
private
Light light2 =
new
Light();
private
Light light3 =
new
Light();
private
Sensor sensor =
new
Sensor();
private
Alarm 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();
}
}
//Camera.java
package
com.javapatterns.facade.securityfacade;
public
class
Camera
{
public
void
turnOn()
{
System.out.println(
"Turning on the camera."
);
}
public
void
turnOff()
{
System.out.println(
"Turning off the camera."
);
}
public
void
rotate(
int
degrees)
{
System.out.println(
"Rotating the camera by "
+ degrees +
" degrees."
);
}
}
//Light.java
package
com.javapatterns.facade.securityfacade;
public
class
Light
{
public
void
turnOn()
{
System.out.println(
"Turning on the light."
);
}
public
void
turnOff()
{
System.out.println(
"Turning off the light."
);
}
public
void
changeBulb()
{
System.out.println(
"Changing the light-bulb."
);
}
}
//Sensor.java
package
com.javapatterns.facade.securityfacade;
public
class
Sensor
{
public
void
activate()
{
System.out.println(
"Activating on the sensor."
);
}
public
void
deactivate()
{
System.out.println(
"Deactivating on the sensor."
);
}
public
void
trigger()
{
System.out.println(
"The sensor has been triggered."
);
}
}
//Alarm.java
package
com.javapatterns.facade.securityfacade;
public
class
Alarm
{
public
void
activate()
{
System.out.println(
"Activating the alarm."
);
}
public
void
deactivate()
{
System.out.println(
"Deactivating the alarm."
);
}
public
void
ring()
{
System.out.println(
"Ring the alarm."
);
}
public
void
stopRing()
{
System.out.println(
"Stop the alarm."
);
}
}
实例:我们可以认为HibernateTemplate是SessionFactory、Session、Query等类的门面,当客户端程序需要进行持久化查询时,程序无须调用这些类,而是直接调用HibernateTemplate门面类的方法即可。