Back to: Design Patterns in C# With Real-Time Examples
Bridge Design Pattern Real-Time Example in C# – Send Message
In this article, I am going to discuss a Real-Time Example of the Bridge Design Pattern in C# – Send Message. Please read our previous article where we discussed the Bridge Design Pattern in C# with Examples.
As already discussed, in Bridge Design Pattern there are two layers i.e. Abstraction and Implementation. As per the Bridge Design Pattern, if we do make any changes in the Implementation layer then it won’t affect the Abstraction Layer and in the same way, if we do any changes in the abstraction layer then it won’t affect the Implementation layer. With this kept in mind let us proceed to this article where we will discuss the real-time example send a message using the Bridge Design Pattern.
Bridge Design Pattern Real-Time Example in C# – Send Message
Please have a look at the following diagram. On the left-hand side, you can see the abstraction layer. Let’s say you want to send a message to the corresponding person. On the right-hand side, you can see two implementations. You can Email the message or SMS the message to the corresponding person. So, you have two options to send the message and the abstraction will use one of the implementations to send the message to the corresponding person.
Later if you want to add any new implementation to the Implementation layer then it will not affect the Abstraction layer. This is one of the best examples of the Bridge Design Pattern.
Implementation of Bridge Design Pattern Real-Time Example in C# – Send Message
Let us implement the above example in C# using the Bridge Design Pattern step by step. Let us first understand the class diagram and then we will implement the example using C#.
Class Diagram of Bridge Design Pattern Real-Time Example – Send Message:
Please have a look at the following image which shows the class diagram of the Send Message Example. As you can see, here we have the bridge interface i.e. IMessageSender which contains the SendMessage abstract method. Then this Implementor interface is implemented by two classes i.e. SmsMessageSender and EmailMessageSender and both classes provide the implementation for the SendMessage method. Then we have the AbstractMessage abstraction class which will be our abstraction layer. Then this AbstractMessage abstraction class is implemented by two Concrete Abstraction classes i.e. LongMessage and ShortMessage and provides implementation to the SendMessage abstract method. Further, if you notice the AbstractMessage abstract class contains one field of type IMessageSender interface.
Step1: Creating Abstract Implementer (IMessageSender)
This is going to be an interface. Create an interface with the name IMessageSender.cs and then copy and paste the following code into it. This interface will be implemented by concrete implementer classes. This interface has one method i.e. SendMessage which takes the message as a string parameter. This Interface acts as a bridge between the abstraction class and implementer classes.
namespace BridgePatternRealTimeExample { // This is going to be an interface that acts as a bridge between the Abstraction Layer and Implementation Layer // The following Implementor Interface defines the operations for all implementation classes. // It doesn't have to match the Abstraction's interface. // In fact, the two interfaces can be entirely different. public interface IMessageSender { void SendMessage(string Message); } }
Step2: Creating Concrete Implementer (SmsMessageSender and EmailMessageSender)
These are going to be concrete classes that implement the IMessageSender interface and provide the implementation for the SendMessage method. In our example, there are two concrete implementers i.e. SmsMessageSender and EmailMessageSender. Each Concrete Implementation corresponds to a specific platform.
SmsMessageSender
Create a class file with the name SmsMessageSender.cs and then copy and paste the following code into it. This class implements the IMessageSender interface and provides implementations for the SendMessage method. This SendMessage method is used to send the message using SMS.
using System; namespace BridgePatternRealTimeExample { // This is going to be a class that implements the Implementor Interface i.e. IMessageSender // It also provides the implementation details for the associated Abstraction class // Each Concrete Implementation corresponds to a specific platform, in this case sending messages using SMS public class SmsMessageSender : IMessageSender { public void SendMessage(string Message) { //Send a message using SMS Console.WriteLine("'" + Message + "' : This Message has been sent using SMS"); } } }
EmailMessageSender:
Create a class file with the name EmailMessageSender.cs and then copy and paste the following code into it. This class also implements the IMessageSender interface and also provides implementations for the SendMessage method. This SendMessage method is used to send the message using Email.
using System; namespace BridgePatternRealTimeExample { // This is going to be a class that implements the Implementor Interface i.e. IMessageSender // It also provides the implementation details for the associated Abstraction class // Each Concrete Implementation corresponds to a specific platform, in this case sending messages using Email public class EmailMessageSender : IMessageSender { public void SendMessage(string Message) { Console.WriteLine("'" + Message + "' : This Message has been sent using Email"); } } }
Step3: Creating Abstraction (AbstractMessage )
This is going to be an abstract class. So, create a class with the name AbstractMessage.cs and then copy and paste the following code into it. This class has one protected member i.e. messageSender which will be available to the subclasses and one abstract method i.e. SendMessage which is going to be implemented by the concrete abstraction classes.
namespace BridgePatternRealTimeExample { //This is an abstract class that going to be implemented by the Concrete Abstraction //It contains a reference to an object of type IMessageSender Interface i.e. messageSender //and delegates all of the real work to this object (the class that implements IMessageSender Interface). //It can also act as the base class for other abstractions. public abstract class AbstractMessage { protected IMessageSender messageSender; public abstract void SendMessage(string Message); } }
Step4: Creating Concrete Abstraction (ShortMessage and LongMessage)
These are going to be concrete classes and implement the AbstractMessage abstract class. In our example, we are going to create two concrete classes i.e. ShortMessage and LongMessage.
ShortMessage:
Create a class file with the name ShortMessage.cs and then copy and paste the following code into it. In the constructor, we have initialized the superclass messageSender variable as well as providing the implementation for the SendMessage method.
using System; namespace BridgePatternRealTimeExample { // This is going to be a concrete class which inherits from the Abstraction class i.e. AbstractMessage. // This Concrete Abstraction Class implements the operations defined by AbstractMessage class. public class ShortMessage : AbstractMessage { //The constructor expected an argument of type object which implements the IMessageSender interface public ShortMessage(IMessageSender messageSender) { //Initialize the super class messageSender variable this.messageSender = messageSender; } public override void SendMessage(string Message) { if (Message.Length <= 10) { messageSender.SendMessage(Message); } else { Console.WriteLine("Unable to send the message as length > 10 characters"); } } } }
LongMessage:
Create a class file with the name LongMessage.cs and then copy and paste the following code into it. In the constructor, initialize the messageSender variable and provide the implementation for the SendMessage method.
namespace BridgePatternRealTimeExample { // This is going to be a concrete class that inherits from the Abstraction class i.e. AbstractMessage. // This Concrete Abstraction Class implements the operations defined by AbstractMessage class. public class LongMessage : AbstractMessage { public LongMessage(IMessageSender messageSender) { //Initialize the super class messageSender variable this.messageSender = messageSender; } public override void SendMessage(string Message) { messageSender.SendMessage(Message); } } }
Step5: Client
In our example, the Main method of the Program class is going to be the Client Code. So, please modify the Main method of the Program class as shown below.
using System; namespace BridgePatternRealTimeExample { class Program { static void Main(string[] args) { // Except for the initialization phase, where an Abstraction object i.e. LongMessage or ShortMessage // linked with a specific Implementation object i.e. new EmailMessageSender() or new SmsMessageSender(), // the client code should only depend on the Abstraction class i.e. AbstractMessage Console.WriteLine("Select the Message Type 1. For longmessage or 2. For shortmessage"); int MessageType = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Please enter the message that you want to send"); string Message = Console.ReadLine(); if (MessageType == 1) { AbstractMessage longMessage = new LongMessage(new EmailMessageSender()); longMessage.SendMessage(Message); } else { AbstractMessage shortMessage = new ShortMessage(new SmsMessageSender()); shortMessage.SendMessage(Message); } Console.ReadKey(); } } }
Output:
In the next article, I am going to discuss the Composite Design Pattern in C# with Examples. Here, in this article, I try to explain the Real-Time Example of the Bridge Design Pattern in C# – Send Message. I hope you understood the need and use of the Bridge Design Pattern in C#.