9.外觀模式(Facade)
門面模式要求一個子系統的外部與其內部的通信必須通過一個統一的門面(Facade)對象進行,也就是對於子系統的操作通過暴漏出來的門面進行操作就行,並不需要了解具體的操作是什麼,比如對於玩具汽車的操作,我們只需要按下前進按鈕就行了,並不需要知道其具體是如何操作的。
這是對外觀模式,也就是門面模式使用最多的一張圖,在這個圖裏面,有兩個角色:
門面(Facade)角色:客戶端可以調用這個角色的方法。此角色知曉相關的(一個或者多個)子系統的功能和責任。在正常情況下,本角色會將所有從客戶端發來的請求委派到相應的子系統去。
子系統(subsystem)角色:可以同時有一個或者多個子系統。每一個子系統都不是一個單獨的類,而是一個類的集合。每一個子系統都可以被客戶端直接調用,或者被門面角色調用。子系統並不知道門面的存在,對於子系統而言,門面僅僅是另外一個客戶端而已。
一個系統可以有幾個門面類
【GOF】的書中指出:在門面模式中,通常只需要一個門面類,並且此門面類只有一個實例,換言之它是一個單例類。當然這並不意味着在整個系統裏只能有一個門面類,而僅僅是說對每一個子系統只有一個門面類。或者說,如果一個系統有好幾個子系統的話,每一個子系統有一個門面類,整個系統可以有數個門面類。
爲子系統增加新行爲
初學者往往以爲通過繼承一個門面類便可在子系統中加入新的行爲,這是錯誤的。因爲這並不是門面模式的用意所在,門面模式的用意是爲子系統提供一個集中化和簡化的溝通管道,而不是有了一個新的添加新的行爲的渠道。
例子:
如上圖所示,一個警報系統using System;
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 SecurityFacade
{
private static Camera camera1, camera2;
private static Light light1, light2, light3;
private static Sensor sensor;
private static Alarm alarm;
static SecurityFacade()
{
camera1 = new Camera();
camera2 = new Camera();
light1 = new Light();
light2 = new Light();
light3 = new Light();
sensor = new Sensor();
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();
}
}
public class Client
{
private static SecurityFacade security;
public static void Main( string[] args )
{
security = new SecurityFacade();
security.Activate();
Console.WriteLine("\n--------------------\n");
security.Deactivate();
}
}
就可以方便的讓client通過system進行警報系統的管理。
10. 橋接模式(bridge)