三、門面模式的實現
一個系統可以有幾個門面類
【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();
}
}