Skip to content

Commit a403c84

Browse files
committed
Add explanation for mediator pattern
1 parent 86362e1 commit a403c84

File tree

1 file changed

+178
-7
lines changed

1 file changed

+178
-7
lines changed

mediator/README.md

Lines changed: 178 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,192 @@ tags:
1111
---
1212

1313
## Intent
14-
Define an object that encapsulates how a set of objects interact.
15-
Mediator promotes loose coupling by keeping objects from referring to each
16-
other explicitly, and it lets you vary their interaction independently.
14+
15+
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling
16+
by keeping objects from referring to each other explicitly, and it lets you vary their interaction
17+
independently.
18+
19+
## Explanation
20+
21+
Real-world example
22+
23+
> Rogue, wizard, hobbit, and hunter have decided to join their forces and travel in the same
24+
> party. To avoid coupling each member with each other, they use the party interface to
25+
> communicate with each other.
26+
27+
In plain words
28+
29+
> Mediator decouples a set of classes by forcing their communications flow through a mediating
30+
> object.
31+
32+
Wikipedia says
33+
34+
> In software engineering, the mediator pattern defines an object that encapsulates how a set of
35+
> objects interact. This pattern is considered to be a behavioral pattern due to the way it can
36+
> alter the program's running behavior. In object-oriented programming, programs often consist of
37+
> many classes. Business logic and computation are distributed among these classes. However, as
38+
> more classes are added to a program, especially during maintenance and/or refactoring, the
39+
> problem of communication between these classes may become more complex. This makes the program
40+
> harder to read and maintain. Furthermore, it can become difficult to change the program, since
41+
> any change may affect code in several other classes. With the mediator pattern, communication
42+
> between objects is encapsulated within a mediator object. Objects no longer communicate directly
43+
> with each other, but instead communicate through the mediator. This reduces the dependencies
44+
> between communicating objects, thereby reducing coupling.
45+
46+
**Programmatic Example**
47+
48+
In this example, the mediator encapsulates how a set of objects interact. Instead of referring to
49+
each other directly they use the mediator interface.
50+
51+
The party members `Rogue`, `Wizard`, `Hobbit`, and `Hunter` all inherit from the `PartyMemberBase`
52+
implementing the `PartyMember` interface.
53+
54+
```java
55+
public interface PartyMember {
56+
57+
void joinedParty(Party party);
58+
59+
void partyAction(Action action);
60+
61+
void act(Action action);
62+
}
63+
64+
@Slf4j
65+
public abstract class PartyMemberBase implements PartyMember {
66+
67+
protected Party party;
68+
69+
@Override
70+
public void joinedParty(Party party) {
71+
LOGGER.info("{} joins the party", this);
72+
this.party = party;
73+
}
74+
75+
@Override
76+
public void partyAction(Action action) {
77+
LOGGER.info("{} {}", this, action.getDescription());
78+
}
79+
80+
@Override
81+
public void act(Action action) {
82+
if (party != null) {
83+
LOGGER.info("{} {}", this, action);
84+
party.act(this, action);
85+
}
86+
}
87+
88+
@Override
89+
public abstract String toString();
90+
}
91+
92+
public class Rogue extends PartyMemberBase {
93+
94+
@Override
95+
public String toString() {
96+
return "Rogue";
97+
}
98+
}
99+
100+
// Wizard, Hobbit, and Hunter are implemented similarly
101+
```
102+
103+
Our mediator system consists of `Party` interface and its implementation.
104+
105+
```java
106+
public interface Party {
107+
108+
void addMember(PartyMember member);
109+
110+
void act(PartyMember actor, Action action);
111+
}
112+
113+
public class PartyImpl implements Party {
114+
115+
private final List<PartyMember> members;
116+
117+
public PartyImpl() {
118+
members = new ArrayList<>();
119+
}
120+
121+
@Override
122+
public void act(PartyMember actor, Action action) {
123+
for (var member : members) {
124+
if (!member.equals(actor)) {
125+
member.partyAction(action);
126+
}
127+
}
128+
}
129+
130+
@Override
131+
public void addMember(PartyMember member) {
132+
members.add(member);
133+
member.joinedParty(this);
134+
}
135+
}
136+
```
137+
138+
Here's a demo showing the mediator pattern in action.
139+
140+
```java
141+
// create party and members
142+
Party party = new PartyImpl();
143+
var hobbit = new Hobbit();
144+
var wizard = new Wizard();
145+
var rogue = new Rogue();
146+
var hunter = new Hunter();
147+
148+
// add party members
149+
party.addMember(hobbit);
150+
party.addMember(wizard);
151+
party.addMember(rogue);
152+
party.addMember(hunter);
153+
154+
// perform actions -> the other party members
155+
// are notified by the party
156+
hobbit.act(Action.ENEMY);
157+
wizard.act(Action.TALE);
158+
rogue.act(Action.GOLD);
159+
hunter.act(Action.HUNT);
160+
```
161+
162+
Here's the console output from running the example.
163+
164+
```
165+
Hobbit joins the party
166+
Wizard joins the party
167+
Rogue joins the party
168+
Hunter joins the party
169+
Hobbit spotted enemies
170+
Wizard runs for cover
171+
Rogue runs for cover
172+
Hunter runs for cover
173+
Wizard tells a tale
174+
Hobbit comes to listen
175+
Rogue comes to listen
176+
Hunter comes to listen
177+
Rogue found gold
178+
Hobbit takes his share of the gold
179+
Wizard takes his share of the gold
180+
Hunter takes his share of the gold
181+
Hunter hunted a rabbit
182+
Hobbit arrives for dinner
183+
Wizard arrives for dinner
184+
Rogue arrives for dinner
185+
```
17186

18187
## Class diagram
188+
19189
![alt text](./etc/mediator_1.png "Mediator")
20190

21191
## Applicability
192+
22193
Use the Mediator pattern when
23194

24-
* a set of objects communicate in well-defined but complex ways. The resulting interdependencies are unstructured and difficult to understand
25-
* reusing an object is difficult because it refers to and communicates with many other objects
26-
* a behavior that's distributed between several classes should be customizable without a lot of subclassing
195+
* A set of objects communicate in well-defined but complex ways. The resulting interdependencies are unstructured and difficult to understand
196+
* Reusing an object is difficult because it refers to and communicates with many other objects
197+
* A behavior that's distributed between several classes should be customizable without a lot of subclassing
27198

28-
## Real world examples
199+
## Known uses
29200

30201
* All scheduleXXX() methods of [java.util.Timer](http://docs.oracle.com/javase/8/docs/api/java/util/Timer.html)
31202
* [java.util.concurrent.Executor#execute()](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-)

0 commit comments

Comments
 (0)