Search code examples
javascriptdesign-patternsmediatorfacade

How do I use the mediator pattern with multiple instances of a mediator in Javascript?


From what I understand, using the mediator pattern looks something like:

  • Modules only publish, but don't subscribe. The mediator subscribes to events and makes other modules do things based on those events.

For example, let's say we have a javascript editor. Let's say there's an editor (for the code) and a run tab (where you can click run and see the output of the code). Each of these is its own module. When the user clicks run, the run tab module outputs an event like "runButtonClicked", the mediator subscribes to this event and runs the code when that event is triggered. This example is a little contrived and simplified, but hopefully this gives some idea of what I'm trying to achieve.

So let's say you have some "class", Mediator, that each module communicates with through Pub/Sub.

If I'm understanding this pattern correctly, then this all makes sense. But a problem seems to arise when you want to have multiple instances of this core "application" on the page -- how does the app know which events to respond to and which should be left for the other instances on the page?

It seems like I'd want multiple mediators, but I'm not sure how these would be passed into the objects.

var mediator = new Mediator();
var moduleOne = new moduleOne(mediator);
var moduleTwo = new moduleTwo(mediator);

This method seems problematic because I want access to those two modules inside of the mediator.

I've also heard of the sandbox/facade patterns being used with the mediator, but I'm not sure if either of those would help (that is, I don't understand them very well).

Update I just found Mediator pattern and creation, which seems like a possible solution. But I'd also like to know if I'm using and thinking about these patterns correctly.


Solution

  • Each instance of the application will need its own event space (or channel) so its events do not pollute the other instances. If the application instances need to talk to one another, then that may require a further event space. Depending on the eventing library you use, there are several ways to do this:

    1. jQuery events support namespaces, so if each application instance has a unique name, you can use the application name as a namespaces to segregate events.
    2. The EventEmitter library supports the creation of multiple EventEmitter instances, unlike jQuery where the events are managed by the jQuery singleton. In this case, you can attach to each application its own EventEmitter instance.

    3. You can also roll your own using the mediator pattern if your library does not have good mechanisms for creating event spaces. In this case, you can create one mediator for each namespace.

    The Mediator pattern can be used in conjunction with options 1 & 2, and the list above is by no means exhaustive.

    This method seems problematic because I want access to those two modules inside of the mediator.

    In order to connect the mediator with the modules it manages, I think you need a separate method to do that. Perhaps something like

    var mediator = new Mediator();
    var moduleOne = new moduleOne;
    var moduleTwo = new moduleTwo;
    moduleOne.mediator = mediator;
    mediator.register(moduleOne);
    moduleTwo.mediator = mediator;
    mediator.register(moduleTwo);