Mediator pattern

From Wikipedia, the free encyclopedia
Jump to: navigation, search

In Software Engineering, the mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program's running behavior.

Usually a program is made up of a large number of classes. So the logic and computation is distributed among these classes. However, as more classes are developed in a program, especially during maintenance and/or refactoring, the problem of communication between these classes may become more complex. This makes the program harder to read and maintain. Furthermore, it can become difficult to change the program, since any change may affect code in several other classes.

With the mediator pattern, communication between objects is encapsulated with a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby lowering the coupling.

Definition[edit]

The essence of the Mediator Pattern is to "Define an object that encapsulates how a set of objects interact". Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.[1]

This pattern is best illustrated in code as the source describes it a lot more concisely than in prose. One central class (the mediator) is used by many ‘client’ classes to send messages with (n.b. ‘client’ is my own term not one from the original pattern description). A ‘client’ or several ‘client’ classes then have a reference to this mediator instance as a private field, and use it to send messages. The mediator has an event which each ‘client’ subscribes to. This event is fired each time the mediator sends a message.

Participants[edit]

Mediator - defines the interface for communication between Colleague objects

ConcreteMediator - implements the Mediator interface and coordinates communication between Colleague objects. It is aware of all the Colleagues and their purpose with regards to inter communication.

ConcreteColleague - communicates with other Colleagues through its Mediator

Example[edit]

C#[edit]

Mediator pattern ensures that the components are loosely coupled, such that they don't call each others explicitly, rather they always use a separate Mediator implementation to do those jobs.Here you can see the mediator Registers all the Components within it and then calls its method when required.

//IVSR: Mediator pattern
public interface IComponent
{
    void SetState(object state);
}
 
public class Component1 : IComponent
{
    #region IComponent Members
 
    public void SetState(object state)
    {
        //Do Nothing
        throw new NotImplementedException();
    }
 
    #endregion
}
 
public class Component2 : IComponent
{
    #region IComponent Members
 
    public void SetState(object state)
    {
        //Do nothing
        throw new NotImplementedException();
    }
 
    #endregion
}
 
// Mediates the common tasks
public class Mediator
{
    public IComponent Component1
    {
        get;
        set;
    }
    public IComponent Component2
    {
        get;
        set;
    }
 
    public void ChangeState(object state)
    {
        this.Component1.SetState(state);
        this.Component2.SetState(state);
    }
}

A chat room could use the Mediator pattern, or a system where many ‘clients’ each receive a message each time one of the other clients performs an action (for chat rooms, this would be when each person sends a message). In reality using the Mediator pattern for a chat room would only be practical when used with remoting. Using raw sockets wouldn’t allow for the delegate callbacks (people subscribed to the Mediator class’ MessageReceived event).

namespace IVSR.DesignPatterns.Mediator
{
  public delegate void MessageReceivedEventHandler(string message, string from);
 
  public class Mediator
  {
      public event MessageReceivedEventHandler MessageReceived;
      public void Send(string message, string from)
      {
          if (MessageReceived != null)
          {
              Console.WriteLine("Sending '{0}' from {1}", message, from);
              MessageReceived(message, from);
          }
      }
  }
 
  public class Person
  {
      private Mediator _mediator;
      public string Name
      {
          get;
          set;
      }
      public Person(Mediator mediator, string name)
      {
          Name = name;
          _mediator = mediator;
          _mediator.MessageReceived += new MessageReceivedEventHandler(Receive);
      }
      private void Receive(string message, string from)
      {
          if (from != Name)
              Console.WriteLine("{0} received '{1}' from {2}", Name, message, from);
      }
      public void Send(string message)
      {
          _mediator.Send(message, Name);
      }
  }
}

Java[edit]

In the following example a mediator object controls the status of three collaborating buttons: for this it contains three methods (book(), view() and search()) that set the status of the buttons. The methods are called by each button upon activation (via the execute() method in each of them).

Hence here the collaboration pattern is that each participant (here the buttons) communicates to the mediator its activity and the mediator dispatches the expected behavior to the other participants.

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
//Colleague interface
interface Command {
    void execute();
}
 
//Abstract Mediator
interface IMediator {
    public void book();
    public void view();
    public void search();
    public void registerView(BtnView v);
    public void registerSearch(BtnSearch s);
    public void registerBook(BtnBook b);
    public void registerDisplay(LblDisplay d);
}
 
//Concrete mediator
class Mediator implements IMediator {
 
    BtnView btnView;
    BtnSearch btnSearch;
    BtnBook btnBook;
    LblDisplay show;
 
    //....
    public void registerView(BtnView v) {
        btnView = v;
    }
 
    public void registerSearch(BtnSearch s) {
        btnSearch = s;
    }
 
    public void registerBook(BtnBook b) {
        btnBook = b;
    }
 
    public void registerDisplay(LblDisplay d) {
        show = d;
    }
 
    public void book() {
        btnBook.setEnabled(false);
        btnView.setEnabled(true);
        btnSearch.setEnabled(true);
        show.setText("booking...");
    }
 
    public void view() {
        btnView.setEnabled(false);
        btnSearch.setEnabled(true);
        btnBook.setEnabled(true);
        show.setText("viewing...");
    }
 
    public void search() {
        btnSearch.setEnabled(false);
        btnView.setEnabled(true);
        btnBook.setEnabled(true);
        show.setText("searching...");
    }
 
}
 
//A concrete colleague
class BtnView extends JButton implements Command {
 
    IMediator med;
 
    BtnView(ActionListener al, IMediator m) {
        super("View");
        addActionListener(al);
        med = m;
        med.registerView(this);
    }
 
    public void execute() {
        med.view();
    }
 
}
 
//A concrete colleague
class BtnSearch extends JButton implements Command {
 
    IMediator med;
 
    BtnSearch(ActionListener al, IMediator m) {
        super("Search");
        addActionListener(al);
        med = m;
        med.registerSearch(this);
    }
 
    public void execute() {
        med.search();
    }
 
}
 
//A concrete colleague
class BtnBook extends JButton implements Command {
 
    IMediator med;
 
    BtnBook(ActionListener al, IMediator m) {
        super("Book");
        addActionListener(al);
        med = m;
        med.registerBook(this);
    }
 
    public void execute() {
        med.book();
    }
 
}
 
class LblDisplay extends JLabel {
 
    IMediator med;
 
    LblDisplay(IMediator m) {
        super("Just start...");
        med = m;
        med.registerDisplay(this);
        setFont(new Font("Arial", Font.BOLD, 24));
    }
 
}
 
class MediatorDemo extends JFrame implements ActionListener {
 
    IMediator med = new Mediator();
 
    MediatorDemo() {
        JPanel p = new JPanel();
        p.add(new BtnView(this, med));
        p.add(new BtnBook(this, med));
        p.add(new BtnSearch(this, med));
        getContentPane().add(new LblDisplay(med), "North");
        getContentPane().add(p, "South");
        setSize(400, 200);
        setVisible(true);
    }
 
    public void actionPerformed(ActionEvent ae) {
        Command comd = (Command) ae.getSource();
        comd.execute();
    }
 
    public static void main(String[] args) {
        new MediatorDemo();
    }
 
}

See also[edit]

References[edit]

External links[edit]