3.5 The Mediator Pattern
When an application grows, it can be bad news for maintainability if every module can talk to every other module. A better strategy is to have all modules communicate through a mediator instead of directly. In this lesson we see one way to achieve this inter-module communication.
1.Introduction2 lessons, 09:16
2.Creational Design Patterns1 lesson, 09:14
3.Behavioural Patterns6 lessons, 1:11:30
4.Structural Patterns5 lessons, 38:41
5.Conclusion1 lesson, 01:43
3.5 The Mediator Pattern
Hi, folks. In this lesson, we're going to look at the mediator pattern. Let's say we have a series of different modules that are used together to build up a web page. Maybe they go together to build the UI of your application. It's important that these modules be kept separate from each other. Not completely isolated from the entire system, they just shouldn't be aware of each other. They might still need to share data with each other, though. Rather than communicating directly, because then they would have to know about each other, we should instead implement a mediator, which handles all of the requests from each of the modules. And fields them out to the appropriate module that can satisfy or handle the request. The participants in this pattern are just the different modules, which are know formally as the colleagues and the mediator. So let's put together a basic example. First of all let's create a new folder called mediator. Inside this we can add a colleague constructor. The constructor has passed an ID for the colleague and an instance of the mediator. Both of these arguments are set as properties of the colleague instance. We can also add a couple of methods to the colleague's prototype, one of which is used to receive messages. This method will receive the message as an argument and to keep the example simple, let's just log the message to the console. The receiveMessage method receives the message as an argument, and just logs this, along with some other information, to the console. We can return true once the logging has occurred. You'll see why this is useful in just a minute. We can also add a sendMessage method for sending messages via the mediator This method receives the message to send, and optionally a recipient to send it to. Based on whether the recipient is specified, we can either use the mediator's send method to send a message to a specific colleague, or use the mediator's broad cusp method to send a message to all colleagues. We can pass the current instance of the colleague to the broadcast method as the second argument, so that we can avoid sending the message to the colleague that sent it. With this module we won't return the constructor. Instead, we'll return an object, which exposes a create method. Inside this method we can initialize a new colleague and register it with the meditator before passing back the new colleague. Next, we can add the mediator constructor in a new file called mediator.js. The mediator constructor will need to store all of the colleagues it is mediating for, but we won't have these up front, so initially, we can set the colleagues property to an empty array. We can return the constructor at the end of the module. The first method we need to add is a method which allows colleagues to register themselves with the mediator. What we need to do is push the colleague into the array of colleagues. Next, we can add the send method, which sends a message to an individual colleague. This method is passed the recipientId as the first argument and the message to send as the second argument. We now need to iterate through some of the items in the colleague's array. The sum method works a little bit like the forEach method, in that it invokes the callback for some of the items in the array. It will keep invoking the callback until the callback returns true when it stops. Which is perfect for us, because the same method is used to send a message to a specific colleague. So once it's been sent, we don't need to send any further messages after the intended recipient is found in the array. Inside the callback, we can check the ID property of the colleague to see if it matches the ID passed to the method. If it does, we can return the value returned by the colleagues receivedMessage method, which if you remember from a few minutes ago, will be true. That's why we've returned true from the colleagues receivedMessage method. Next, we can add the simpler broadcast message, which sends the message to all colleagues. The method just receives the message to send. It uses the forEach method to iterate all the items in the array and invoke their received message method, passing in the message. We can filter out the sender of the broadcast by comparing the current colleague.id with the sender.id. So all we need to do now is wire things up in the init module. First, we should load the colleague and mediator modules we just created. We can then create a mediator and some colleagues. We can then have each colleague send a message. The first two colleges send direct messages to each other, but the third college just sends a broadcast, which both of the others should receive. So now, let's update the main file to load the files for this example. And let's run this example in the browser now. So we're seeing a script error. Let's see what's happening. That's on line nine of the mediator.js file. And there's a typo there. I've typed desk.colleague instead of desk.colleagues. And there's a final error now on line 22 of mediator.js and the sender property is not defined. So that's here. And we just need to specify that as an argument. And this time it's working as expected. The colleague3 sent the broadcast. But, as you can see, it doesn't receive it, only the other two modules do. So, in this lesson we looked at the mediator pattern. This pattern is great for decoupling a group of modules that all need to communicate with each other. Instead of every module depending on every other module, and ending up with a tangled mess, we can introduce a mediator, which all the other modules depend on, and which handles all of the communication between them. Thanks for watching.