Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Mediator pattern
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{confused|Broker pattern}} {{short description|Software architecture design pattern}} In [[software engineering]], the '''mediator pattern''' defines an object that [[Encapsulation (computer programming)|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. In object-oriented programming, programs often consist of many [[class (computer science)|classes]]. [[Business logic]] and [[computation]] are distributed among these classes. However, as more classes are added to a program, especially during [[Software maintenance|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 within 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 reducing [[Coupling (computer programming)|coupling]]. ==Overview== The mediator<ref name="GoF">{{cite book|author=Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides|title=Design Patterns: Elements of Reusable Object-Oriented Software|year=1994|publisher=Addison Wesley|isbn=0-201-63361-2|pages=[https://archive.org/details/designpatternsel00gamm/page/273 273ff]|url-access=registration|url=https://archive.org/details/designpatternsel00gamm/page/273}}</ref> design pattern is one of the twenty-three well-known [[Design Patterns|design patterns]] that describe how to solve recurring design problems to design flexible and reusable object-oriented software, that is, objects that are easier to implement, change, test, and reuse. ===Problems that the mediator design pattern can solve=== Source:<ref>{{cite web |title=The Mediator design pattern - Problem, Solution, and Applicability |url=http://w3sdesign.com/?gr=b05&ugr=proble |first=Günther |last=Franke |website=w3sDesign |access-date=2017-08-12}}</ref> * Tight coupling between a set of interacting objects should be avoided. * It should be possible to change the interaction between a set of objects independently. Defining a set of interacting objects by accessing and updating each other directly is inflexible because it tightly couples the objects to each other and makes it impossible to change the interaction independently from (without having to change) the objects. And it stops the objects from being reusable and makes them hard to test. ''Tightly coupled objects'' are hard to implement, change, test, and reuse because they refer to and know about many different objects. ===Solutions described by the mediator design pattern === * Define a separate (mediator) object that encapsulates the interaction between a set of objects. * Objects delegate their interaction to a mediator object instead of interacting with each other directly. The objects interact with each other indirectly through a mediator object that controls and coordinates the interaction. This makes the objects ''loosely coupled''. They only refer to and know about their mediator object and have no explicit knowledge of each other. See also the UML class and sequence diagram below. == Definition == The essence of the mediator pattern is to "define an object that encapsulates how a set of objects interact". It promotes loose coupling by keeping objects from referring to each other explicitly, and it allows their interaction to be varied independently.<ref>{{cite book |first1=Erich |last1=Gamma |author-link1=Erich Gamma |first2=Richard |last2=Helm |first3=Ralph |last3=Johnson |author-link3=Ralph Johnson (computer scientist) |first4=John |last4=Vlissides |author-link4=John Vlissides |title=[[Design Patterns]] |date= 1994 |publisher=[[Addison-Wesley]] |isbn=0-201-63361-2}}</ref><ref>{{cite web |url=http://sourcemaking.com/design_patterns/mediator |title=Mediator Design Pattern |website= SourceMaking}}</ref> Client classes can use the mediator to send messages to other clients, and can receive messages from other clients via an event on the mediator class. ==Structure== ===UML class and sequence diagram=== [[File:w3sDesign Mediator Design Pattern UML.jpg|frame|none|A sample UML class and sequence diagram for the mediator design pattern.<ref>{{cite web|title=The Mediator design pattern - Structure and Collaboration| url=http://w3sdesign.com/?gr=b05&ugr=struct |first=Günther |last=Franke |website=w3sDesign |access-date=2017-08-12}}</ref>]] In the above [[UML]] [[class diagram]], the <code>Colleague1</code> and <code>Colleague2</code> classes do not refer to (and update) each other directly. Instead, they refer to the common <code>Mediator</code> interface for controlling and coordinating interaction (<code>mediate()</code>), which makes them independent from one another with respect to how the interaction is carried out. The <code>Mediator1</code> class implements the interaction between <code>Colleague1</code> and <code>Colleague2</code>. The [[UML]] [[sequence diagram]] shows the run-time interactions. In this example, a <code>Mediator1</code> object mediates (controls and coordinates) the interaction between <code>Colleague1</code> and <code>Colleague2</code> objects. Assuming that <code>Colleague1</code> wants to interact with <code>Colleague2</code> (to update/synchronize its state, for example), <code>Colleague1</code> calls <code>mediate(this)</code> on the <code>Mediator1</code> object, which gets the changed data from <code>Colleague1</code> and performs an <code>action2()</code> on <code>Colleague2</code>. Thereafter, <code>Colleague2</code> calls <code>mediate(this)</code> on the <code>Mediator1</code> object, which gets the changed data from <code>Colleague2</code> and performs an <code>action1()</code> on <code>Colleague1</code>. ===Class diagram=== [[File:Mediator design pattern.png|frame|none|The mediator behavioural design pattern]] ;Participants '''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 of the ''Colleagues'' and their purposes with regards to inter-communication. '''Colleague''' - defines the interface for communication with other ''Colleagues'' through its ''Mediator'' '''ConcreteColleague''' - implements the Colleague interface and communicates with other ''Colleagues'' through its ''Mediator'' == Example == === C# === The mediator pattern ensures that components are [[loosely coupled]], such that they do not call each other explicitly, but instead do so through calls to a mediator. In the following example, the mediator registers all Components and then calls their {{Code|SetState}} methods. <syntaxhighlight lang="csharp"> interface IComponent { void SetState(object state); } class Component1 : IComponent { internal void SetState(object state) { throw new NotImplementedException(); } } class Component2 : IComponent { internal void SetState(object state) { throw new NotImplementedException(); } } // Mediates the common tasks class Mediator { internal IComponent Component1 { get; set; } internal IComponent Component2 { get; set; } internal void ChangeState(object state) { this.Component1.SetState(state); this.Component2.SetState(state); } } </syntaxhighlight> 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 would not allow for the [[Delegation (object-oriented programming)|delegate]] [[callbacks]] (people subscribed to the Mediator class’ MessageReceived event). <syntaxhighlight lang="csharp"> public delegate void MessageReceivedEventHandler(string message, string sender); public class Mediator { public event MessageReceivedEventHandler MessageReceived; public void Send(string message, string sender) { if (MessageReceived != null) { Console.WriteLine("Sending '{0}' from {1}", message, sender); MessageReceived(message, sender); } } } public class Person { private Mediator _mediator; public Person(Mediator mediator, string name) { Name = name; _mediator = mediator; _mediator.MessageReceived += new MessageReceivedEventHandler(Receive); } public string Name { get; set; } private void Receive(string message, string sender) { if (sender != Name) Console.WriteLine("{0} received '{1}' from {2}", Name, message, sender); } public void Send(string message) { _mediator.Send(message, Name); } } </syntaxhighlight> === Java === <!-- Wikipedia is not a list of examples. Do not add examples from your favorite programming language here; this page exists to explain the design pattern, not to show how it interacts with subtleties of every language under the sun. Feel free to add examples here: http://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Mediator --> In the following example, a <code>Mediator</code> object controls the values of several <code>Storage</code> objects, forcing the user code to access the stored values through the mediator. When a storage object wants to emit an event indicating that its value has changed, it also goes back to the mediator object (via the method <code>notifyObservers</code>) that controls the list of the observers (implemented using the [[observer pattern]]). <syntaxhighlight lang="java"> import java.util.HashMap; import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; class Storage<T> { T value; T getValue() { return value; } void setValue(Mediator<T> mediator, String storageName, T value) { this.value = value; mediator.notifyObservers(storageName); } } class Mediator<T> { private final HashMap<String, Storage<T>> storageMap = new HashMap<>(); private final CopyOnWriteArrayList<Consumer<String>> observers = new CopyOnWriteArrayList<>(); public void setValue(String storageName, T value) { Storage storage = storageMap.computeIfAbsent(storageName, name -> new Storage<>()); storage.setValue(this, storageName, value); } public Optional<T> getValue(String storageName) { return Optional.ofNullable(storageMap.get(storageName)).map(Storage::getValue); } public void addObserver(String storageName, Runnable observer) { observers.add(eventName -> { if (eventName.equals(storageName)) { observer.run(); } }); } void notifyObservers(String eventName) { observers.forEach(observer -> observer.accept(eventName)); } } public class MediatorDemo { public static void main(String[] args) { Mediator<Integer> mediator = new Mediator<>(); mediator.setValue("bob", 20); mediator.setValue("alice", 24); mediator.getValue("alice").ifPresent(age -> System.out.println("age for alice: " + age)); mediator.addObserver("bob", () -> { System.out.println("new age for bob: " + mediator.getValue("bob").orElseThrow(RuntimeException::new)); }); mediator.setValue("bob", 21); } } </syntaxhighlight> <!-- Wikipedia is not a list of examples. Do not add examples from your favorite programming language here; this page exists to explain the design pattern, not to show how it interacts with subtleties of every language under the sun. Feel free to add examples here: http://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Mediator --> == See also == * [[Data mediation]] * ''[[Design Patterns]],'' the book which gave rise to the study of design patterns in computer science {{Citation needed|date=May 2021}} * [[Software design pattern]], a standard solution to common problems in software design == References == {{Reflist|1}} == External links == {{wikibooks|Computer Science Design Patterns|Mediator|Mediator implementations in various languages}} * {{cite web |url=https://stackoverflow.com/questions/12534338/is-the-use-of-the-mediator-pattern-recommend |title=Is the use of the mediator pattern recommend? |first= Bodo |last=Kaiser |website=[[Stack Overflow]] |date=2012-09-21}} {{Design Patterns Patterns}} [[Category:Software design patterns]] [[Category:Articles with example C Sharp code]] [[Category:Articles with example Java code]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:Citation needed
(
edit
)
Template:Cite book
(
edit
)
Template:Cite web
(
edit
)
Template:Code
(
edit
)
Template:Confused
(
edit
)
Template:Design Patterns Patterns
(
edit
)
Template:Reflist
(
edit
)
Template:Short description
(
edit
)
Template:Sister project
(
edit
)
Template:Wikibooks
(
edit
)