BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Design Patterns
.NET 1.1+

Bridge Design Pattern

The bridge pattern is a design pattern that separates the abstract elements of a class from its technical implementation. This provides a cleaner implementation of real-world objects and allows the implementation details to be changed easily.

Example Bridge

In the opening paragraphs of this article I described an example use for the bridge pattern. In the example, the abstraction would be used to build a message that must be sent to another system. Depending upon the available infrastructure, the message would be sent using email, using a message queue or via a web service. In the remaining sections of this article we will implement the basic structure of this messaging system and create a simple program that demonstrates its use.

The code to fully implement such a messaging system would be larger than it needs to be to demonstrate the concepts and would be difficult to test without a web server, mail server and message queue system. To simplify the example, we will not actually integrate with any of these systems. Instead we will output messages that describe what would happen in reality. Again, C# 3.0 automatic property syntax has been used and will need to be expanded for earlier versions of the .NET framework.

We can start by implementing the abstract base class for the implementation. This class defines a single method signature that will be used to send a message. The method will accept three parameters for the title and body of the message and the importance of the message, expressed as an integer.

public abstract class MessageSenderBase
{
    public abstract void SendMessage(string title, string details, int importance);
}

We can now define the three initial concrete implementations. As we are using the bridge pattern, further messaging implementations could be added as required in the future.

public class EmailSender : MessageSenderBase
{
    public override void SendMessage(string title, string body, int importance)
    {
        Console.WriteLine("Email\n{0}\n{1}\n{2}\n", title, body, importance);
    }
}


public class MsmqSender : MessageSenderBase
{
    public override void SendMessage(string title, string body, int importance)
    {
        Console.WriteLine("MSMQ\n{0}\n{1}\n{2}\n", title, body, importance);
    }
}


public class WebServiceSender : MessageSenderBase
{
    public override void SendMessage(string title, string body, int importance)
    {
        Console.WriteLine("Web Service\n{0}\n{1}\n{2}\n", title, body, importance);
    }
}

The next step is to create the base class for abstractions. This class will describe a message with three properties for the title, body and importance of the message. A fourth property will be used to hold a reference to an implementation object. The class will also include a Send method that calls the SendMessage method of the referenced implementation.

public class Message
{
    public MessageSenderBase MessageSender { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
    public int Importance { get; set; }

    public virtual void Send()
    {
        MessageSender.SendMessage(Title, Body, Importance);
    }
}

Finally, we will refine the Message class with a subclass that has an extra property for holding additional information. This class could be used when the software is being operated by a user. If an error occurs, the user could be asked for any information that they can provide to help determine the problem. These "UserComments" will be appended to the body of the message before sending.

public class UserEditedMessage : Message
{
    public string UserComments { get; set; }

    public override void Send()
    {
        string fullBody = string.Format("{0}\nCOMMENTS\n{1}", Body, UserComments);
        MessageSender.SendMessage(Title, fullBody, Importance);
    }
}

Testing the Bridge

To test the bridge example classes we can use a console application containing all of the above code. Add the code shown below to the Main method then execute the program. The test code creates a message and sends it using each type of message sender. It then creates another message, this time with user comments. Finally, it sends the new message using one of the available message sender implementations.

MessageSenderBase email = new EmailSender();
MessageSenderBase queue = new MsmqSender();
MessageSenderBase web = new WebServiceSender();

Message message = new Message();
message.Title = "Error";
message.Body = "An error occurred";
message.Importance = 1;

message.MessageSender = email;
message.Send();

message.MessageSender = queue;
message.Send();

message.MessageSender = web;
message.Send();

UserEditedMessage userEdited = new UserEditedMessage();
userEdited.Title = "Error";
userEdited.Body = "An error occurred";
userEdited.Importance = 1;
userEdited.UserComments = "Crashed when I clicked Submit";

userEdited.MessageSender = email;
userEdited.UserComments = "Additional comments";
userEdited.Send();

/* OUTPUT

Email
Error
An error occurred
1

MSMQ
Error
An error occurred
1

Web Service
Error
An error occurred
1

Email
Error
An error occurred
COMMENTS
Additional comments
1

*/
8 April 2009