Click here to Skip to main content
Click here to Skip to main content

Refactoring to Patterns: Mediator Pattern

, 28 Mar 2005
Rate this:
Please Sign up or sign in to vote.
This article details a real world example of how to use the mediator.

Introduction

Developers in .NET sometimes come from scripting language environments that are not strong on Object Oriented methodologies. OO methodologies like Refactoring and using design patterns can be intimidating and the value for the developer is hard to see. What developers new to the OO world, and even more seasoned developers, need to understand is that good design is not beyond scope in any project. Good habits simply must be learned that will make the developer a better designer.

In that mindset, I am submitting the first of several "how to" real world examples, used in my professional life, on how to use patterns in a simple, easy to follow manner. Many of us have ended up either writing or working on in-line, scripting based code. Taking some ideologies from refactoring methodology, is not necessarily a bad thing. Of course, when you are first writing an algorithm or a series of logic statements, it seems easier to start with if....then....else. But as you continue to expand this code to more complex forms, this model can quickly become unmanageable. This is where refactoring and design pattern methodology can play an important and useful part in simplifying, enhancing and making the code more useable (and understandable) to those who practice good OO design.

This article details a real world example of how to use the mediator pattern to help you develop a method to communicate between several classes. The mediator pattern is used when mediation is needed between several classes, to communicate in an indirect manner.

Background

I have used mediators in several different ways throughout my professional career, but the cleanest way to recognize a mediator pattern is any class that facilitates indirect communication between a series of other classes. This example is fairly light in inheritance, simply because I did not want to add too much into the conversion between if...then...else code and the pattern, thus potentially confusing the developer on the minimum requirements of the mediator pattern.

How to use the code

The first thing we should note is the WorkerObject in this example. It contains a constructor that accepts a string parameter, a two way accessor and a method SendMessage:

        public class WorkerObject
        {
            private string _message;
            
            public WorkerObject(string message)
            {
                _message = message;
            }            
            
            public string Message
            {
                get{return _message;}
                set{_message = value;
            }
            
            public SendMessage(string message)
            {
                Console.WriteLine("Message sent : " + message);
            }
        }

Next we see the functional code, as it exists at the beginning of the refactoring effort. Notice the class construction declarations, each passing in a slightly different string variable, and behind that, the if...then...else statement, which checks the Message accessor of the sender object and based on that value not being the same as the sender object, performs the SendMessage method on the appropriate object:

        WorkerObject senderObject = new WorkerObject("message0");
        WorkerObject workerObject1 = new WorkerObject("message1");
        WorkerObject workerObject2 = new WorkerObject("message2");
        WorkerObject workerObject3 = new WorkerObject("message3");
        if(!workerObject1.Message.Equals(senderObject.Message)
        {
            workerObject1.SendMessage(senderObject.Message);
        }
        if(!workerObject2.Message.Equals(senderObject.Message)
        {
            workerObject2.SendMessage(senderObject.Message);
        } 
        if(!workerObject3.Message.Equals(senderObject.Message)
        {
            workerObject3.SendMessage(senderObject.Message);
        }

Now to move this code from the overly cumbersome if...then...else statements, we create a mediator class, DoSomeMediation. This class contains two methods Register and SendMessage. The Register method catalogs all the classes we want to mediate between. The SendMessage method is where the functional code actually exists, and calls all the registered objects, ignoring the passed in object if it exists in the mediator class, and calls the SendMessage method on each class, passing in the passed objects Message accessor:

        public class DoSomeMediation
        {
                private static ArrayList _workerObjects = new ArrayList();

                public static int Register(WorkerObject workerObject)
                {                    
                    return _workerObjects.Add(workerObject);
                }
                public static void SendMessage(WorkerObject senderObject)
                {
                    if(senderObject == null) return;
                    string messageToSend = senderObject.Message;
                    
                    foreach(WorkerObject workerObject in _workerObjects)
                    {
                        //send message to all other objects registered
                        if(!workerObject.Message.Equals(senderObject.Message))
                            workerObject.SendMessage(messageToSend);
                    }
                }
        }

Next we see the execution code. Notice that while we still construct the WorkerObject objects the same way, now instead of the if...then...else code making the determination of which objects to call the SendMessage method on, we let the mediator class handle the communication between the classes.

        WorkerObject senderObject = new WorkerObject("message0");
        WorkerObject workerObject1 = new WorkerObject("message1");
        WorkerObject workerObject2 = new WorkerObject("message2");
        WorkerObject workerObject3 = new WorkerObject("message3");
        DoSomeMediation.Register(senderObject);
        DoSomeMediation.Register(workerObject1);
        DoSomeMediation.Register(workerObject2);
        DoSomeMediation.Register(workerObject3);
        DoSomeMediation.SendMessage(senderObject);

Points of interest

This particular example seems to be redoing the if...then...else statement in a different manner. What does this buy us? Well let's say we wanted to pass into the executed code a collection of WorkerObject objects, instead of the manual construction. Using the if...then...else code we could not make a runtime change to the number or type of objects that could communicate between each other.

This is the third installment in the series I am writing on real world design patterns. All examples and the bulk of this article are taken from my professional experience as an architect. The examples given are templates only, and the designer must keep in mind that they are the ones who must decide where different patterns, if any, may be best used in their code.

Deciding to perform a refactoring effort from the existing code to a pattern must be weighed on the necessity and need of the code itself. Patterns are only design templates, helpers to accommodate better overall design. I must stress that making an effort to use the patterns will strengthen your overall design ability, but like your basic coding skills, it is something that is to be learnt and cultivated.

If this or any other in this series on design patterns is helpful or you have questions or comments please e-mail me at chris.lasater@gmail.com.

History

This is the first revision and is the third installment in a series.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Christopher G. Lasater
Web Developer
United States United States
Christopher G. Lasater
 
I am also a published author, please check out my book:
ISBN: 1-59822-031-4
Title: Design Patterns
Author:Christopher G. Lasater
More from my web site
Amazon.com


Comments and Discussions

 
GeneralNice, but PinmemberHurricaneGordon17-Aug-06 14:55 
GeneralRe: Nice, but Pinmemberchris lasater17-Aug-06 16:34 
QuestionIsn't this from GoF? PinmemberSicle11-Apr-05 14:11 
AnswerRe: Isn't this from GoF? Pinmemberchris lasater13-Apr-05 5:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141216.1 | Last Updated 28 Mar 2005
Article Copyright 2005 by Christopher G. Lasater
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid