Skip to content

Commit 72de5a2

Browse files
committed
Add Mediator design pattern implementation
Implemented the Mediator pattern with `ChatRoom` and `Participant` classes to facilitate communication between objects. Updated `Program.cs` to include a demo of the pattern. Updated `README.md` to document the Mediator pattern, including its purpose, usage example, and implementation/test paths. Added `MediatorTests.cs` to verify the functionality of the pattern.
1 parent 0aecf49 commit 72de5a2

File tree

5 files changed

+101
-1
lines changed

5 files changed

+101
-1
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace DesignPatterns.Mediator;
2+
3+
public class ChatRoom
4+
{
5+
private readonly List<Participant> _participants = new();
6+
7+
public void Register(Participant p)
8+
{
9+
if (p is null) throw new ArgumentNullException(nameof(p));
10+
p.Room = this;
11+
_participants.Add(p);
12+
}
13+
14+
public void Broadcast(Participant from, string message)
15+
{
16+
foreach (var p in _participants)
17+
{
18+
if (p != from) p.Receive(from.Name, message);
19+
}
20+
}
21+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace DesignPatterns.Mediator;
2+
3+
public class Participant
4+
{
5+
public string Name { get; }
6+
internal ChatRoom? Room { get; set; }
7+
8+
private readonly List<string> _messages = new();
9+
10+
public Participant(string name)
11+
{
12+
Name = name ?? string.Empty;
13+
}
14+
15+
public IReadOnlyList<string> Messages => _messages;
16+
17+
public void Send(string message)
18+
{
19+
if (Room is null) throw new InvalidOperationException("Participant is not registered with a chat room.");
20+
Room.Broadcast(this, message);
21+
}
22+
23+
internal void Receive(string from, string message)
24+
{
25+
_messages.Add($"{from}: {message}");
26+
}
27+
}

DesignPatterns/Program.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using DesignPatterns.Proxy;
1313
using DesignPatterns.Chain;
1414
using DesignPatterns.Iterator;
15+
using DesignPatterns.Mediator;
1516

1617
Console.WriteLine("Factory pattern demo:");
1718

@@ -146,6 +147,19 @@
146147
cmdRemote.PressUndo();
147148
Console.WriteLine($"After undo, light is on: {light.IsOn}");
148149

150+
// Mediator demo
151+
Console.WriteLine();
152+
Console.WriteLine("Mediator pattern demo:");
153+
var room = new ChatRoom();
154+
var alice = new Participant("Alice");
155+
var bob = new Participant("Bob");
156+
room.Register(alice);
157+
room.Register(bob);
158+
159+
alice.Send("Hello Bob");
160+
Console.WriteLine("Bob's messages:");
161+
foreach (var m in bob.Messages) Console.WriteLine(m);
162+
149163
// Decorator demo
150164
Console.WriteLine();
151165
Console.WriteLine("Decorator pattern demo:");

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Design Patterns Examples
33
This solution demonstrates simple design pattern examples in C# targeting .NET 10 (C# 14).
44

55
Projects
6-
- `DesignPatterns` - Console demo showing Factory, Singleton, Builder, Prototype, Abstract Factory, Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy, Chain of Responsibility, Command, and Iterator patterns.
6+
- `DesignPatterns` - Console demo showing Factory, Singleton, Builder, Prototype, Abstract Factory, Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy, Chain of Responsibility, Command, Iterator, and Mediator patterns.
77
- Factory implementation: `DesignPatterns/Factories`
88
- Singleton implementation: `DesignPatterns/Singleton/Logger.cs`
99
- Builder implementation: `DesignPatterns/Builder/HouseBuilder.cs` and `DesignPatterns/Builder/House.cs`
@@ -19,6 +19,7 @@ Projects
1919
- Chain of Responsibility implementation: `DesignPatterns/Chain/*`
2020
- Command implementation: `DesignPatterns/Command/*`
2121
- Iterator implementation: `DesignPatterns/Iterator/*`
22+
- Mediator implementation: `DesignPatterns/Mediator/*`
2223
- `Tests` - xUnit tests covering the examples.
2324

2425
Included patterns and brief docs
@@ -202,6 +203,20 @@ Included patterns and brief docs
202203
while (it.HasNext()) Console.WriteLine(it.Next());
203204
```
204205
206+
- Mediator Pattern
207+
- Purpose: Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly.
208+
- Example: `DesignPatterns/Mediator/*` contains `ChatRoom` (mediator) and `Participant` (colleagues) that register with the room and broadcast messages.
209+
- Usage snippet:
210+
211+
```csharp
212+
var room = new ChatRoom();
213+
var alice = new Participant("Alice");
214+
var bob = new Participant("Bob");
215+
room.Register(alice);
216+
room.Register(bob);
217+
alice.Send("Hello Bob");
218+
```
219+
205220
Tests
206221
- Tests are written with xUnit in the `Tests` project.
207222
- Factory tests: `Tests/ShapeFactoryTests.cs`
@@ -219,6 +234,7 @@ Tests
219234
- Chain tests: `Tests/ChainTests.cs`
220235
- Command tests: `Tests/CommandTests.cs`
221236
- Iterator tests: `Tests/IteratorTests.cs`
237+
- Mediator tests: `Tests/MediatorTests.cs`
222238
223239
Common commands
224240
- Build solution: `dotnet build`

Tests/MediatorTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using DesignPatterns.Mediator;
2+
3+
namespace Tests;
4+
5+
public class MediatorTests
6+
{
7+
[Fact]
8+
public void Participants_CanSendMessagesViaChatRoom()
9+
{
10+
var room = new ChatRoom();
11+
var alice = new Participant("Alice");
12+
var bob = new Participant("Bob");
13+
14+
room.Register(alice);
15+
room.Register(bob);
16+
17+
alice.Send("Hello Bob");
18+
19+
Assert.Contains("Alice: Hello Bob", bob.Messages);
20+
Assert.Empty(alice.Messages); // sender shouldn't receive own message
21+
}
22+
}

0 commit comments

Comments
 (0)