The Mediator is a behavioral design pattern in which objects, instead of communicating directly with each other, communicate only through a central message passing object (the Mediator). The Mediator pattern facilitates both loose couple and high cohesion.
Coupling measures the degree to which program modules rely on other modules. Loose couplingimplies each component can operate or be tested independently of other components. Tight coupling implies each component "knows" the details or inner workings of other components. The Mediator almost entirely eliminates coupling between participating objects by becoming the only outside point of contact. All a module needs to know is how to broadcast messages through the Mediator — it doesn't matter whether 0, 1, or even 100 other modules act on those messages.
myObject.someFunction(args)
, then one change in how your program works may cause a ripple effect of changes through several modules. TL;DR: tight coupling causes headachesCohesion is a measure of how focused a piece of code is. High cohesion implies a component's properties and methods are strongly related, and work toward one or more closely related tasks.Low cohesion implies a component may handle two or more unrelated or dissimilar tasks.
The following example was built on ideas presented by Paul Marcotte. I especially like his comparison between the Mediator pattern and the Observer pattern:
"Instead of using the Observer pattern to explicitly set many-to-many listeners and events, Mediator allows you to broadcast events globally across colleagues."
Mediator = function() {
var debug = function() {
// console.log or air.trace as desired
};
var components = {};
var broadcast = function(event, args, source) {
if (!event) {
return;
}
args = args || [];
//debug(["Mediator received", event, args].join(' '));
for (var c in components) {
if (typeof components[c]["on" + event] == "function") {
try {
//debug("Mediator calling " + event + " on " + c);
source = source || components[c];
components[c]["on" + event].apply(source, args);
} catch (err) {
debug(["Mediator error.", event, args, source, err].join(' '));
}
}
}
};
var addComponent = function(name, component, replaceDuplicate) {
if (name in components) {
if (replaceDuplicate) {
removeComponent(name);
} else {
throw new Error('Mediator name conflict: ' + name);
}
}
components[name] = component;
};
var removeComponent = function(name) {
if (name