Skip to content

Commit d48b3db

Browse files
author
Badacadabra
committed
Add Mediator (ES5 + ES6 + CoffeeScript + TypeScript)
1 parent fb53d36 commit d48b3db

File tree

7 files changed

+410
-0
lines changed

7 files changed

+410
-0
lines changed
2.67 KB
Binary file not shown.
30.1 KB
Loading

doc/GoF/Behavioral/Mediator/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Synopsis
2+
3+
Tom and Dick are neighbors. Dick makes a lot of noise on Sunday mornings, which drives Tom crazy. Communication has become difficult between them because of this.
4+
5+
# Problem
6+
7+
If Tom and Dick cannot talk to each other directly, Dick will continue to make noise and Tom will get angry every Sunday.
8+
9+
# Solution
10+
11+
When communication is difficult between two objects or in a system (here the neighborhood), the solution is delegation to a third-party object. This object will make communication easier between all other objects.
12+
13+
This is exactly the solution proposed by the Mediator pattern. To implement this pattern, we need:
14+
15+
* An abstract representation of a neighbor (abstract class should be preferred because it centralizes the reference to the mediator)
16+
* An abstract representation of a neighborhood mediator (abstract class or interface)
17+
* Concrete neighbors (Tom and Dick)
18+
* A concrete mediator (Harry)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# ==============================
2+
# ABSTRACT COLLEAGUE
3+
# ==============================
4+
5+
class Neighbor
6+
constructor: (mediator) ->
7+
throw new Error "You cannot instantiate an abstract class!" if @constructor is Neighbor
8+
@_mediator = mediator
9+
10+
send: (message) ->
11+
throw new Error "You cannot instantiate an abstract class!"
12+
13+
receive: (message, sender) ->
14+
throw new Error "You cannot instantiate an abstract class!"
15+
16+
# ==============================
17+
# ABSTRACT MEDIATOR
18+
# ==============================
19+
20+
class Mediator
21+
constructor: ->
22+
throw new Error "You cannot instantiate an abstract class!" if @constructor is Mediator
23+
24+
send: (message, neighbor) ->
25+
throw new Error "You cannot instantiate an abstract class!"
26+
27+
# ==============================
28+
# CONCRETE COLLEAGUES (NEIGHBORS)
29+
# ==============================
30+
31+
class Tom extends Neighbor
32+
constructor: (mediator) ->
33+
super mediator
34+
35+
send: (message) ->
36+
@_mediator.send(message, @)
37+
38+
receive: (message, sender) ->
39+
"[Tom] Message from #{sender}: '#{message}'\n"
40+
41+
class Dick extends Neighbor
42+
constructor: (mediator) ->
43+
super mediator
44+
45+
send: (message) ->
46+
return @_mediator.send(message, @)
47+
48+
receive: (message, sender) ->
49+
"[Dick] Message from #{sender}: '#{message}'\n"
50+
51+
# ==============================
52+
# CONCRETE MEDIATOR
53+
# ==============================
54+
55+
class Harry extends Mediator
56+
constructor: ->
57+
@_tom = new Tom(@)
58+
@_dick = new Dick(@)
59+
60+
send: (message, neighbor) ->
61+
if neighbor instanceof Tom
62+
@_dick.receive message, "Tom"
63+
else if neighbor instanceof Dick
64+
@_tom.receive message, "Dick"
65+
else
66+
throw new Error "Unknown neighbor"
67+
68+
# ==============================
69+
# CLIENT CODE
70+
# ==============================
71+
72+
harry = new Harry
73+
tom = new Tom harry
74+
dick = new Dick harry
75+
conversation = ""
76+
77+
conversation += tom.send "Could you lower the volume of your music, please?"
78+
conversation += dick.send "Are you serious? The volume is actually very low..."
79+
80+
console.log conversation
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// ==============================
2+
// ABSTRACT COLLEAGUE
3+
// ==============================
4+
5+
abstract class Neighbor {
6+
protected mediator: Mediator;
7+
8+
constructor(mediator: Mediator) {
9+
this.mediator = mediator;
10+
}
11+
12+
public abstract send(message: string): string;
13+
public abstract receive(message: string, sender: string): string;
14+
}
15+
16+
// ==============================
17+
// ABSTRACT MEDIATOR
18+
// ==============================
19+
20+
interface Mediator {
21+
send(message: string, neighbor: Neighbor): string;
22+
}
23+
24+
// ==============================
25+
// CONCRETE COLLEAGUES (NEIGHBORS)
26+
// ==============================
27+
28+
class Tom extends Neighbor {
29+
constructor(mediator: Mediator) {
30+
super(mediator);
31+
}
32+
33+
send(message: string): string {
34+
return this.mediator.send(message, this);
35+
}
36+
37+
receive(message: string, sender: string): string {
38+
return `[Tom] Message from ${sender}: '${message}'\n`;
39+
}
40+
}
41+
42+
class Dick extends Neighbor {
43+
constructor(mediator: Mediator) {
44+
super(mediator);
45+
}
46+
47+
send(message: string): string {
48+
return this.mediator.send(message, this);
49+
}
50+
51+
receive(message: string, sender: string): string {
52+
return `[Dick] Message from ${sender}: '${message}'\n`;
53+
}
54+
}
55+
56+
// ==============================
57+
// CONCRETE MEDIATOR
58+
// ==============================
59+
60+
class Harry implements Mediator {
61+
private tom: Tom = new Tom(this);
62+
private dick: Dick = new Dick(this);
63+
64+
send(message: string, neighbor: Neighbor): string {
65+
if (neighbor instanceof Tom) {
66+
return this.dick.receive(message, "Tom");
67+
} else if (neighbor instanceof Dick) {
68+
return this.tom.receive(message, "Dick");
69+
} else {
70+
throw new Error("Unknown neighbor");
71+
}
72+
}
73+
}
74+
75+
// ==============================
76+
// CLIENT CODE
77+
// ==============================
78+
79+
let harry: Mediator = new Harry(),
80+
tom: Neighbor = new Tom(harry),
81+
dick: Neighbor = new Dick(harry),
82+
conversation: string = "";
83+
84+
conversation += tom.send("Could you lower the volume of your music, please?");
85+
conversation += dick.send("Are you serious? The volume is actually very low...");
86+
87+
console.log(conversation);
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
'use strict';
2+
3+
// ==============================
4+
// ABSTRACT COLLEAGUE
5+
// ==============================
6+
7+
var Neighbor = (function() {
8+
function Neighbor(mediator) {
9+
if (this.constructor === Neighbor) {
10+
throw new Error("You cannot instantiate an abstract class!");
11+
}
12+
this._mediator = mediator;
13+
}
14+
15+
Neighbor.prototype.send = function (message) {
16+
throw new Error("You cannot instantiate an abstract class!");
17+
};
18+
19+
Neighbor.prototype.receive = function (message, sender) {
20+
throw new Error("You cannot instantiate an abstract class!");
21+
};
22+
23+
return Neighbor;
24+
})();
25+
26+
// ==============================
27+
// ABSTRACT MEDIATOR
28+
// ==============================
29+
30+
var Mediator = (function() {
31+
function Mediator() {
32+
if (this.constructor === Mediator) {
33+
throw new Error("You cannot instantiate an abstract class!");
34+
}
35+
}
36+
37+
Mediator.prototype.send = function (message, neighbor) {
38+
throw new Error("You cannot instantiate an abstract class!");
39+
};
40+
41+
return Mediator;
42+
})();
43+
44+
// ==============================
45+
// CONCRETE COLLEAGUES (NEIGHBORS)
46+
// ==============================
47+
48+
var Tom = (function () {
49+
function Tom(mediator) {
50+
Neighbor.call(this, mediator);
51+
}
52+
Tom.prototype = Object.create(Neighbor.prototype);
53+
Tom.prototype.constructor = Tom;
54+
55+
Tom.prototype.send = function (message) {
56+
return this._mediator.send(message, this);
57+
};
58+
59+
Tom.prototype.receive = function (message, sender) {
60+
return "[Tom] Message from " + sender + ": '" + message + "'\n";
61+
};
62+
63+
return Tom;
64+
})();
65+
66+
var Dick = (function () {
67+
function Dick(mediator) {
68+
Neighbor.call(this, mediator);
69+
}
70+
Dick.prototype = Object.create(Neighbor.prototype);
71+
Dick.prototype.constructor = Dick;
72+
73+
Dick.prototype.send = function (message) {
74+
return this._mediator.send(message, this);
75+
};
76+
77+
Dick.prototype.receive = function (message, sender) {
78+
return "[Dick] Message from " + sender + ": '" + message + "'\n";
79+
};
80+
81+
return Dick;
82+
})();
83+
84+
// ==============================
85+
// CONCRETE MEDIATOR
86+
// ==============================
87+
88+
var Harry = (function () {
89+
var tom = new Tom(this),
90+
dick = new Dick(this);
91+
92+
function Harry() {}
93+
Harry.prototype = Object.create(Mediator.prototype);
94+
Harry.prototype.constructor = Harry;
95+
96+
Harry.prototype.send = function (message, neighbor) {
97+
if (neighbor instanceof Tom) {
98+
return dick.receive(message, "Tom");
99+
} else if (neighbor instanceof Dick) {
100+
return tom.receive(message, "Dick");
101+
} else {
102+
throw new Error("Unknown neighbor");
103+
}
104+
};
105+
106+
return Harry;
107+
})();
108+
109+
// ==============================
110+
// CLIENT CODE
111+
// ==============================
112+
113+
var harry = new Harry(),
114+
tom = new Tom(harry),
115+
dick = new Dick(harry),
116+
conversation = "";
117+
118+
conversation += tom.send("Could you lower the volume of your music, please?");
119+
conversation += dick.send("Are you serious? The volume is actually very low...");
120+
121+
console.log(conversation);

0 commit comments

Comments
 (0)