Facade Pattern เป็น Structural Pattern ที่ให้ Interface เรียบง่าย (Simple Interface) ครอบคลุม Subsystem ที่ซับซ้อน (Complex Subsystem) ทำให้ Client ใช้งานง่ายขึ้น
ผู้เข้าร่วม (Participants)
- Facade: Классที่ให้ Interface เรียบง่าย รู้จัก Subsystems ใดทำหน้าที่อะไร
- Subsystems: คลาสที่ทำงานจริง (Complex Logic) ถูก "Wrap" โดย Facade
ตัวอย่าง: Smart Home Facade
// Subsystems - ซับซ้อน มีหลายเมธอด
public class Lights
{
public void TurnOn() => Console.WriteLine("Lights: ON");
public void TurnOff() => Console.WriteLine("Lights: OFF");
public void Dim(int level) => Console.WriteLine($"Lights: Dimmed to {level}%");
}
public class AirConditioner
{
public void TurnOn() => Console.WriteLine("AC: ON");
public void TurnOff() => Console.WriteLine("AC: OFF");
public void SetTemperature(int temp) => Console.WriteLine($"AC: Temp set to {temp}°C");
}
public class MusicSystem
{
public void TurnOn() => Console.WriteLine("Music: ON");
public void TurnOff() => Console.WriteLine("Music: OFF");
public void PlayPlaylist(string name) => Console.WriteLine($"Music: Playing '{name}'");
}
public class SecuritySystem
{
public void Arm() => Console.WriteLine("Security: ARMED");
public void Disarm() => Console.WriteLine("Security: DISARMED");
}
// Facade - ให้ Interface เรียบง่ายสำหรับ Scenario ต่างๆ
public class SmartHomeFacade
{
private readonly Lights _lights;
private readonly AirConditioner _ac;
private readonly MusicSystem _music;
private readonly SecuritySystem _security;
public SmartHomeFacade()
{
_lights = new Lights();
_ac = new AirConditioner();
_music = new MusicSystem();
_security = new SecuritySystem();
}
// Scenario 1: กลับบ้าน
public void ArriveHome()
{
Console.WriteLine("--- Arriving Home ---");
_security.Disarm();
_lights.TurnOn();
_ac.TurnOn();
_ac.SetTemperature(24);
_music.TurnOn();
_music.PlayPlaylist("Relaxing");
}
// Scenario 2: ออกจากบ้าน
public void LeaveHome()
{
Console.WriteLine("--- Leaving Home ---");
_music.TurnOff();
_ac.TurnOff();
_lights.TurnOff();
_security.Arm();
}
// Scenario 3: ดูหนัง
public void MovieMode()
{
Console.WriteLine("--- Movie Mode ---");
_lights.Dim(10);
_ac.SetTemperature(22);
_music.TurnOff();
}
}
// Client - ใช้งานง่าย ไม่ต้องรู้ Subsystems
static void Main()
{
var home = new SmartHomeFacade();
home.ArriveHome();
Console.WriteLine();
home.MovieMode();
Console.WriteLine();
home.LeaveHome();
}
ผลลัพธ์
--- Arriving Home ---
Security: DISARMED
Lights: ON
AC: ON
AC: Temp set to 24°C
Music: ON
Music: Playing 'Relaxing'
--- Movie Mode ---
Lights: Dimmed to 10%
AC: Temp set to 22°C
Music: OFF
--- Leaving Home ---
Music: OFF
AC: OFF
Lights: OFF
Security: ARMED
ข้อดี
- ลด Complexity ให้ Client (Single Method Call แทนหลาย Subsystem Calls)
- Loose Coupling: Client ไม่ติดกับ Subsystems โดยตรง
- รองรับ Legacy Code: Wrap Legacy System ให้ใช้งานง่าย
- Centralized Control: จัดการ Workflow อยู่ที่เดียว
ข้อควรระวัง
- Facade อาจกลายเป็น "God Class" หากดูแล Subsystems มากเกินไป
- ไม่ควรบังคับ Client ใช้ Facade เท่านั้น ควรยังเข้าถึง Subsystems ได้หากต้องการ (Optional Facade)
ใน .NET Framework
HttpClientเป็น Facade ของ HTTP StackFile,Directory,Pathเป็น Facade ของ File System APIs- ASP.NET Core
IApplicationBuilderเป็น Facade ของ Middleware Pipeline