Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
What is Facade and how to implement in C#?
The Facade design pattern provides a simplified interface to a complex subsystem. It acts as a wrapper that hides the complexity of multiple classes and their interactions behind a single, easy-to-use interface.
This pattern is particularly useful when working with complex APIs, legacy systems, or when you need to provide a unified interface to a set of interfaces in a subsystem.
Key Components
The Facade pattern consists of the following components −
-
Facade: The main interface that clients interact with. It delegates requests to appropriate subsystem objects.
-
Subsystems: The complex classes that implement the actual functionality. They are not aware of the facade and work independently.
-
Client: Uses the facade instead of calling subsystem objects directly.
Implementing Facade Pattern in C#
Let's implement a home automation system where the facade simplifies controlling multiple devices −
using System;
// Subsystem classes
public class LightSystem {
public void TurnOnLights() {
Console.WriteLine("Lights are ON");
}
public void TurnOffLights() {
Console.WriteLine("Lights are OFF");
}
}
public class MusicSystem {
public void TurnOnMusic() {
Console.WriteLine("Music system is ON");
}
public void TurnOffMusic() {
Console.WriteLine("Music system is OFF");
}
public void SetVolume(int level) {
Console.WriteLine($"Music volume set to {level}");
}
}
public class AirConditioner {
public void TurnOnAC() {
Console.WriteLine("Air conditioner is ON");
}
public void TurnOffAC() {
Console.WriteLine("Air conditioner is OFF");
}
public void SetTemperature(int temp) {
Console.WriteLine($"AC temperature set to {temp}°C");
}
}
// Facade class
public class SmartHomeFacade {
private LightSystem lights;
private MusicSystem music;
private AirConditioner ac;
public SmartHomeFacade() {
lights = new LightSystem();
music = new MusicSystem();
ac = new AirConditioner();
}
public void LeaveHome() {
Console.WriteLine("Leaving home - turning off all systems:");
lights.TurnOffLights();
music.TurnOffMusic();
ac.TurnOffAC();
Console.WriteLine("All systems are OFF<br>");
}
public void ArriveHome() {
Console.WriteLine("Arriving home - setting up comfortable environment:");
lights.TurnOnLights();
music.TurnOnMusic();
music.SetVolume(5);
ac.TurnOnAC();
ac.SetTemperature(22);
Console.WriteLine("Welcome home!<br>");
}
public void MovieMode() {
Console.WriteLine("Setting up movie mode:");
lights.TurnOffLights();
music.TurnOnMusic();
music.SetVolume(8);
ac.SetTemperature(20);
Console.WriteLine("Movie mode activated!<br>");
}
}
// Client code
public class Program {
public static void Main(string[] args) {
SmartHomeFacade smartHome = new SmartHomeFacade();
smartHome.ArriveHome();
smartHome.MovieMode();
smartHome.LeaveHome();
}
}
The output of the above code is −
Arriving home - setting up comfortable environment: Lights are ON Music system is ON Music volume set to 5 Air conditioner is ON AC temperature set to 22°C Welcome home! Setting up movie mode: Lights are OFF Music system is ON Music volume set to 8 AC temperature set to 20°C Movie mode activated! Leaving home - turning off all systems: Lights are OFF Music system is OFF Air conditioner is OFF All systems are OFF
Using Facade with External APIs
Here's another example showing how Facade can simplify working with multiple external services −
using System;
// Complex subsystems (simulating external APIs)
public class EmailService {
public void SendEmail(string to, string subject, string body) {
Console.WriteLine($"Email sent to {to}: {subject}");
}
}
public class SMSService {
public void SendSMS(string phoneNumber, string message) {
Console.WriteLine($"SMS sent to {phoneNumber}: {message}");
}
}
public class LoggingService {
public void LogActivity(string activity) {
Console.WriteLine($"[LOG] {DateTime.Now:HH:mm:ss} - {activity}");
}
}
// Facade for notification system
public class NotificationFacade {
private EmailService emailService;
private SMSService smsService;
private LoggingService logger;
public NotificationFacade() {
emailService = new EmailService();
smsService = new SMSService();
logger = new LoggingService();
}
public void SendWelcomeNotification(string email, string phone, string name) {
logger.LogActivity($"Sending welcome notification to {name}");
emailService.SendEmail(email, "Welcome!", $"Welcome {name}!");
smsService.SendSMS(phone, $"Welcome {name}! Thanks for joining us.");
}
public void SendOrderConfirmation(string email, string phone, int orderId) {
logger.LogActivity($"Sending order confirmation for Order #{orderId}");
emailService.SendEmail(email, "Order Confirmed", $"Order #{orderId} confirmed");
smsService.SendSMS(phone, $"Order #{orderId} confirmed. Track your order online.");
}
}
public class Program {
public static void Main(string[] args) {
NotificationFacade notifications = new NotificationFacade();
notifications.SendWelcomeNotification("john@example.com", "+1234567890", "John");
Console.WriteLine();
notifications.SendOrderConfirmation("john@example.com", "+1234567890", 12345);
}
}
The output of the above code is −
[LOG] 14:25:30 - Sending welcome notification to John Email sent to john@example.com: Welcome! SMS sent to +1234567890: Welcome John! Thanks for joining us. [LOG] 14:25:30 - Sending order confirmation for Order #12345 Email sent to john@example.com: Order Confirmed SMS sent to +1234567890: Order #12345 confirmed. Track your order online.
Benefits of Facade Pattern
-
Simplifies complex systems: Provides a clean, easy-to-use interface.
-
Loose coupling: Clients depend on the facade, not the subsystems.
-
Improved maintainability: Changes to subsystems don't affect client code.
-
Better organization: Groups related functionality under one interface.
Conclusion
The Facade pattern provides a simplified interface to complex subsystems, making them easier to use and maintain. It's particularly valuable when working with legacy code, external APIs, or any complex system where you want to hide implementation details from clients.
