The Mediator Pattern
Gof: Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently."
The relationships that link specific objects to each other are hidden. Ideally, all objects involved only have visibility on the mediator, and any association objects involved in the interaction with the mediator.
Some real-time procedural systems have a "main control loop" that runs over and over, updating parts of the system as things change. Such a control loop can be used as a clearing house for the behaviors of, say, a video game. Mediators accomplish a very similar goal.
10-base-T sockets in various rooms of a building all connect back to a wiring closet. This closet contains the routers and network hubs that enable the connections to function when someone plugs a computer into them. The mediator is essentially a wiring closet for software elements to connect to.
Modern development tools often offer drag-and-drop mechanisms for creating graphical user interfaces, database connections, and other system elements. It is unadvisable to embed business logic in the code these tools generate, as it becomes difficult to test, reuse, and modify. A Mediator can be introduced to encapsulate all coupling between the generated code and the handcrafted application logic. The Mediator contains only the “wiring” between these elements. The elements do not couple to each other directly in any way.
Questions, concerns, credibility checks
Because the Mediator can only be tested in integration, care should be taken to ensure that it does not contain complex failure modes. Ideally, the Mediator should have no significant application logic beyond dispatching requests.
Mediators can serve as a kind of “application roadmap” since all events, requests, and services are routed through it. The more readable and clear its code is, the better it will serve this useful role.
Options in implementation
If flexible connections are needed the Observer can be used when implementing the Mediator.
If any significant logic is required (caching or remoting dispatches, etc…) then a Proxy should be used to add it, making it testable as a separate issue.
The Mediator itself is a candidate for creating a Mock allowing for easier testing of all the elements that couple to it. Testing the Mediator itself is an integration issue, and thus it will be tested less frequently than other parts of the system.
The main benefit of the mediator is the decoupling it promotes between elements of a system. It does increase delegation slightly, and thus may have a slight impact on performance.