Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1567863

Browse files
committed
add Mediator Pattern
1 parent 722eeda commit 1567863

File tree

9 files changed

+304
-3
lines changed

9 files changed

+304
-3
lines changed

BehavioralPatterns/BehavioralPatterns.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
<Reference Include="System.Xml" />
4444
</ItemGroup>
4545
<ItemGroup>
46+
<Compile Include="Mediator\ParticipantColleague.cs" />
47+
<Compile Include="Mediator\ChatRoomMediator.cs" />
48+
<Compile Include="Mediator\TestMediator.cs" />
4649
<Compile Include="NullObject\ConsoleLog.cs" />
4750
<Compile Include="NullObject\ILog.cs" />
4851
<Compile Include="NullObject\NullLog.cs" />
@@ -61,10 +64,12 @@
6164
</ItemGroup>
6265
<ItemGroup>
6366
<None Include="App.config" />
67+
<None Include="doc\Mediator.cd" />
6468
<None Include="doc\NullObject.cd" />
6569
<None Include="doc\Observer.cd" />
6670
<None Include="doc\Strategy.cd" />
6771
<None Include="doc\TemplateMethod.cd" />
72+
<None Include="Mediator\README.md" />
6873
<None Include="NullObject\README.md" />
6974
<None Include="Observer\README.md" />
7075
<None Include="Strategy\README.md" />
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace BehavioralPatterns.Mediator
8+
{
9+
public interface IChatRoom
10+
{
11+
void RegisterParticipant(IParticipant participant);
12+
void Send(String from, String to, string message);
13+
}
14+
15+
public class ChatRoom : IChatRoom
16+
{
17+
18+
private readonly IDictionary<string, IParticipant> _participants = new Dictionary<string, IParticipant>();
19+
20+
public void RegisterParticipant(IParticipant participant)
21+
{
22+
this._participants.Add(participant.GetName(), participant);
23+
}
24+
25+
public void Send(string from, string to, string message)
26+
{
27+
if (this._participants.ContainsKey(to))
28+
{
29+
this._participants[to].Receive(from, message);
30+
}
31+
else
32+
{
33+
throw new ArgumentException("{0} not found", to);
34+
}
35+
}
36+
}
37+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace BehavioralPatterns.Mediator
8+
{
9+
public interface IParticipant
10+
{
11+
string GetName();
12+
void Send(string to, string message);
13+
void Receive(string from, string message);
14+
}
15+
16+
public class Participant : IParticipant
17+
{
18+
private readonly string _name;
19+
private readonly IChatRoom _chatRoom;
20+
21+
public Participant(string name, IChatRoom chatRoom)
22+
{
23+
this._name = name;
24+
this._chatRoom = chatRoom;
25+
26+
this._chatRoom.RegisterParticipant(this);
27+
}
28+
29+
public string GetName()
30+
{
31+
return this._name;
32+
}
33+
34+
public void Send(string to, string message)
35+
{
36+
this._chatRoom.Send(this._name, to, message);
37+
}
38+
39+
public void Receive(string from, string message)
40+
{
41+
Console.WriteLine("{0} to {1}: {2}", from, this._name, message);
42+
}
43+
}
44+
45+
46+
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Mediator
2+
3+
Use the Mediator Pattern to centralize complex communications and control between related objects.
4+
5+
## Problem
6+
7+
* Tight coupling between a set of interacting objects should be avoided.
8+
* It should be possible to change the interaction between a set of objects independently.
9+
10+
*Tightly coupled objects* are hard to implement, change, test and reuse.
11+
12+
## Solution
13+
14+
* Define a `Mediator` object that encapsulates the interaction between a set of objects.
15+
* Objects delegate their interaction to a mediator object instead of interacting with each other directly.
16+
17+
This makes the objects *loosely coupled*.
18+
19+
The Mediator is commonly used to coordinate related GUI components.
20+
21+
## Benefits
22+
23+
* Colleagues classes may become more reusable and are decoupled from the system.
24+
* Simplifies maintenance of the system by centralizing control logic.
25+
* Simplifies and reduces the variety of messages sent between objects in the system.
26+
27+
## Drawbacks
28+
29+
* Without proper design, the mediator object can become overly complex.
30+
* Single point of failure
31+
* Hard to test --> Objects should be mocked
32+
33+
## Example
34+
35+
![Mediator Pattern](/Diagrams/Mediator.png)
36+
37+
Mediator
38+
```cs
39+
public interface IChatRoom
40+
{
41+
void RegisterParticipant(IParticipant participant);
42+
void Send(String from, String to, string message);
43+
}
44+
```
45+
46+
ConcreteMediator
47+
```cs
48+
public class ChatRoom : IChatRoom
49+
{
50+
private readonly IDictionary<string, IParticipant> _participants = new Dictionary<string, IParticipant>();
51+
52+
public void RegisterParticipant(IParticipant participant)
53+
{
54+
this._participants.Add(participant.GetName(), participant);
55+
}
56+
57+
public void Send(string from, string to, string message)
58+
{
59+
if (this._participants.ContainsKey(to))
60+
{
61+
this._participants[to].Receive(from, message);
62+
}
63+
else
64+
{
65+
throw new ArgumentException("{0} not found", to);
66+
}
67+
}
68+
}
69+
```
70+
71+
Colleague
72+
```cs
73+
public interface IParticipant
74+
{
75+
string GetName();
76+
void Send(string to, string message);
77+
void Receive(string from, string message);
78+
}
79+
```
80+
81+
ConcreteColleague
82+
```cs
83+
public class Participant : IParticipant
84+
{
85+
private readonly string _name;
86+
private readonly IChatRoom _chatRoom;
87+
88+
public Participant(string name, IChatRoom chatRoom)
89+
{
90+
this._name = name;
91+
this._chatRoom = chatRoom;
92+
93+
this._chatRoom.RegisterParticipant(this);
94+
}
95+
public string GetName()
96+
{
97+
return this._name;
98+
}
99+
100+
public void Send(string to, string message)
101+
{
102+
this._chatRoom.Send(this._name, to, message);
103+
}
104+
105+
public void Receive(string from, string message)
106+
{
107+
Console.WriteLine("{0} to {1}: {2}", from, this._name, message);
108+
}
109+
}
110+
```
111+
112+
Usage
113+
```cs
114+
IChatRoom chatRoom = new ChatRoom();
115+
116+
IParticipant einstein = new Participant("Einstein", chatRoom);
117+
IParticipant newton = new Participant("Newton", chatRoom);
118+
IParticipant galileo = new Participant("Galileo", chatRoom);
119+
120+
newton.Send(galileo.GetName(), "I discoverd laws of motion");
121+
einstein.Send(newton.GetName(), "I discovered how gravity works");
122+
```
123+
124+
## Common Structure
125+
126+
![Common structure of mediator pattern](https://upload.wikimedia.org/wikipedia/commons/9/92/W3sDesign_Mediator_Design_Pattern_UML.jpg)
127+
128+
* Mediator (IChatRoom)
129+
* defines an interface for communicating with Colleague objects
130+
* ConcreteMediator (ChatRoom)
131+
* implements cooperative behavior by coordinating Colleague objects.
132+
* knows and maintains its colleagues.
133+
* Colleague (IParticipant)
134+
* defines an interface for using Colleague objects.
135+
* ConcreateColleague (Participant)
136+
* each colleague knows its Mediator object
137+
* each colleague communicates with its mediator whenever it would have otherwise communicated with another colleague.
138+
139+
_[Source: http://www.dofactory.com/net/mediator-design-patternttp://www.dofactory.com/net/adapter-design-pattern]_
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace BehavioralPatterns.Mediator
8+
{
9+
public class TestMediator
10+
{
11+
public static void Run()
12+
{
13+
IChatRoom chatRoom = new ChatRoom();
14+
15+
IParticipant einstein = new Participant("Einstein", chatRoom);
16+
IParticipant newton = new Participant("Newton", chatRoom);
17+
IParticipant galileo = new Participant("Galileo", chatRoom);
18+
19+
newton.Send(galileo.GetName(), "I discoverd laws of motion");
20+
einstein.Send(newton.GetName(), "I discovered how gravity works");
21+
22+
Console.ReadKey();
23+
}
24+
}
25+
}

BehavioralPatterns/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
using System.Linq;
44
using System.Text;
55
using System.Threading.Tasks;
6+
using BehavioralPatterns.Mediator;
67

78
namespace BehavioralPatterns
89
{
910
class Program
1011
{
1112
static void Main(string[] args)
1213
{
13-
Observer.TestEvents.Run();
14+
TestMediator.Run();
1415
}
1516
}
1617
}

BehavioralPatterns/doc/Mediator.cd

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<ClassDiagram MajorVersion="1" MinorVersion="1">
3+
<Class Name="BehavioralPatterns.Mediator.ChatRoom" BaseTypeListCollapsed="true">
4+
<Position X="1.25" Y="3" Width="1.5" />
5+
<TypeIdentifier>
6+
<HashCode>AAAAAAAAAAAAAIAAAEAAAAAAAAAAAAAAAAAQAAAAAAA=</HashCode>
7+
<FileName>Mediator\ChatRoomMediator.cs</FileName>
8+
</TypeIdentifier>
9+
<ShowAsCollectionAssociation>
10+
<Field Name="_participants" />
11+
</ShowAsCollectionAssociation>
12+
<Lollipop Position="0.2" />
13+
</Class>
14+
<Class Name="BehavioralPatterns.Mediator.Participant" BaseTypeListCollapsed="true">
15+
<Position X="5.25" Y="2.75" Width="1.5" />
16+
<AssociationLine Name="_chatRoom" Type="BehavioralPatterns.Mediator.IChatRoom" ManuallyRouted="true">
17+
<Path>
18+
<Point X="5.25" Y="3.816" />
19+
<Point X="4.071" Y="3.816" />
20+
<Point X="4.071" Y="0.872" />
21+
<Point X="2.75" Y="0.872" />
22+
</Path>
23+
</AssociationLine>
24+
<TypeIdentifier>
25+
<HashCode>AAAAIAAAAAAAAAAAAEAAACAAAAAAAAAQAAAAAAAABAA=</HashCode>
26+
<FileName>Mediator\ParticipantColleague.cs</FileName>
27+
</TypeIdentifier>
28+
<ShowAsAssociation>
29+
<Field Name="_chatRoom" />
30+
</ShowAsAssociation>
31+
<Lollipop Position="0.2" />
32+
</Class>
33+
<Interface Name="BehavioralPatterns.Mediator.IChatRoom">
34+
<Position X="1.25" Y="0.5" Width="1.5" />
35+
<TypeIdentifier>
36+
<HashCode>AAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAQAAAAAAA=</HashCode>
37+
<FileName>Mediator\ChatRoomMediator.cs</FileName>
38+
</TypeIdentifier>
39+
</Interface>
40+
<Interface Name="BehavioralPatterns.Mediator.IParticipant">
41+
<Position X="5.25" Y="0.5" Width="1.5" />
42+
<TypeIdentifier>
43+
<HashCode>AAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAQAAAAAAAABAA=</HashCode>
44+
<FileName>Mediator\ParticipantColleague.cs</FileName>
45+
</TypeIdentifier>
46+
</Interface>
47+
<Font Name="Segoe UI" Size="9" />
48+
</ClassDiagram>

Diagrams/Mediator.png

29.1 KB
Loading

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Design Patterns in C# / .NET
44
[![Build Status](https://travis-ci.org/tk-codes/DesignPatterns.NET.svg?branch=master)](https://travis-ci.org/tk-codes/DesignPatterns.NET)
55
![Language C#](https://img.shields.io/badge/language-c%23-blue.svg)
66
![status in progress](https://img.shields.io/badge/status-in%20progress-brightgreen.svg)
7-
![number of patterns](https://img.shields.io/badge/patterns-12-red.svg)
7+
![number of patterns](https://img.shields.io/badge/patterns-13-red.svg)
88

99
## Creational Patterns
1010

@@ -37,7 +37,7 @@ Design Patterns in C# / .NET
3737
| | Command |
3838
| | Interpreter
3939
| | Iterator
40-
| | Mediator
40+
|:heavy_check_mark: | [Mediator](/BehavioralPatterns/Mediator)|
4141
| | Memento
4242
| :heavy_check_mark: | [Null Object](/BehavioralPatterns/NullObject) |
4343
| :heavy_check_mark:| [Observer](/BehavioralPatterns/Observer/) |

0 commit comments

Comments
 (0)