门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面对(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.");
}
}