Design Patterns In Action Part-2: Implementing Facade Pattern in Email Service
What is the Facade pattern?
The Facade pattern is a design pattern that provides a simplified interface to a complex system. The goal of the pattern is to make it easier to use and understand the system by hiding its complexity behind a simplified interface.
The Facade pattern achieves this by providing a single interface to a set of subsystems, rather than exposing the subsystems directly to client code. The Facade class acts as a mediator between client code and the subsystems, providing a simplified interface that encapsulates the details of the subsystems.
By using the Facade pattern, client code can interact with the system without needing to know the details of its subsystems. This makes the system easier to use and understand, as client code only needs to interact with the Facade interface, rather than the entire system.
Lets implement Facade Pattern in a practical scenerio.
Our Scenario
We will implement an email service that has multiple subsystems, including authentication, message composition, and message sending. The email service will be implemented using the Facade pattern to provide a simplified interface to these subsystems.
Implementation
First, we have defined three classes that represent the subsystems of the email service:
class EmailAuthenticationSystem {
public bool Authenticate(string username, string password) {
// Authenticate user using provided credentials
return true; // Return true if authentication succeeds
}
}
class EmailCompositionSystem {
public string ComposeMessage(string recipient, string subject, string body) {
// Compose message with provided recipient, subject, and body
return "Email message"; // Return the composed email message
}
}
class EmailSendingSystem {
public void SendEmail(string recipient, string message) {
// Send email message to provided recipient
Console.WriteLine("Email sent to " + recipient + ": " + message);
}
}
The EmailAuthenticationSystem
class provides a method Authenticate
that takes in a username and password, and returns true if the authentication succeeds.
The EmailCompositionSystem
class provides a method ComposeMessage
that takes in a recipient, subject, and body, and returns the composed email message.
The EmailSendingSystem
class provides a method SendEmail
that takes in a recipient and a message, and sends the email message to the provided recipient.
Next, we define the EmailService
class that acts as a facade for the subsystems:
class EmailService {
private EmailAuthenticationSystem authSystem;
private EmailCompositionSystem compSystem;
private EmailSendingSystem sendSystem;
public EmailService() {
authSystem = new EmailAuthenticationSystem();
compSystem = new EmailCompositionSystem();
sendSystem = new EmailSendingSystem();
}
public bool Authenticate(string username, string password) {
return authSystem.Authenticate(username, password);
}
public void SendEmail(string recipient, string subject, string body) {
if (Authenticate("user123", "password")) { // Authenticate user before sending email
string message = compSystem.ComposeMessage(recipient, subject, body); // Compose email message
sendSystem.SendEmail(recipient, message); // Send email message
}
}
}
The EmailService
class has private fields for the EmailAuthenticationSystem
, EmailCompositionSystem
, and EmailSendingSystem
objects. In the constructor, we have created new instances of these objects.
The Authenticate
method of the EmailService
class calls the Authenticate
method of the EmailAuthenticationSystem
object to authenticate the user with the provided username and password. It returns true if the authentication succeeds.
The SendEmail
method of the EmailService
class first authenticates the user by calling the Authenticate
method. If the authentication succeeds, it composes an email message by calling the ComposeMessage
method of the EmailCompositionSystem
object, and then sends the email message by calling the SendEmail
method of the EmailSendingSystem
object.
Finally, we have the client code:
class Client {
static void Main(string[] args) {
EmailService emailService = new EmailService();
// Send email
emailService.SendEmail("recipient@example.com", "Subject", "Body");
}
}
In the Main
method of the Client
class, we have created a new instance of the EmailService
class, and then have called its SendEmail
method with the recipient, subject, and body of the email.
Conclusion
Overall, the Facade pattern is a powerful design pattern that can improve the usability and maintainability of software systems by providing a simplified interface to complex subsystems, and by decoupling client code from implementation details.