fm

famous-mediator

Utilities to use a mediator design pattern in Famo.us apps

Showing:

Popularity

Downloads/wk

4

GitHub Stars

8

Maintenance

Last Commit

7yrs ago

Contributors

1

Package

Dependencies

0

Size (min+gzip)

0.5KB

License

MIT

Type Definitions

Tree-Shakeable

No?

Categories

Readme

famous-mediator

A design pattern that decouples modules using the mediator pattern.

Getting started

Install using bower or npm

  bower install famous-mediator
  npm install famous-mediator

Benefits

Use the mediator pattern to decouple modules

  • Promotes clean, reusable modules
  • Clear seperation of concerns - no more sneaky business logic in your templates!
  • Is the perfect place for hacks, experiments, monkey-patches and workarounds. And because all of your "bad" code is in the Mediators, your actual code base stays clean! (True story!)

Example

Imagine you have a router module and a pages module:

1. Router.js - just tracks navigation and doesn't know about other modules

  function Router(){
    // blablabla
    this.name = 'router';
    Engine.emit('created',this) // broadcast created event
    // blablabla
  }

2. PageController.js - just displays pages but doesn't know how to route & navigate!

  function PageController(){
    // blablabla
    this.name = 'pages';   // name your module
    Engine.emit('created',this) // broadcast created event
    // blablabla
  }

  // It emits an application wide event if a link is clicked.
  PageController.prototype.onLinkClick = function(event) {
    Engine.emit('link-clicked',event.target.getAttribute('href'));
  }
}

3. RouteMediator.js - couples the router and pages together!

  var Mediator = require('famous-mediator');

  // Router -> PageController
  Mediator.ready(['router','pages'],function(router,pages){
    router.on('change',function(name){
      pages.setPage(name);
    });
  });

  // PageController -> Router
  //
  // mediator translates 'link-clicked' from page to an actual
  // navigation in the router.
  Mediator.on('link-clicked',['router'],function(href,router){
    router.set(href);
  });

Usage

The idea is to write Mediator singletons that couple modules together by:

  1. Listen to events from one module, or listen to global events.
  2. Call public API of another module

Step 1: Create modules

The Famo.us Engine is used as a global eventbus to announce creation of modules. If you want to register a module, simple add to your constructor function:

  Engine.emit('created',this)

A module MUST have a name to be registered. This name can be found on:

  • this.options.id = 'myCoolModule'
  • this.options.name = 'myCoolModule'
  • this.id = 'myCoolModule'
  • this.name = 'myCoolModule'

Note:

I am using the Engine so that this Mediator module becomes an optional dependency. This enables component authors to facilitate a meditator pattern without enforcing this pattern on all users.

Step 2: Couple modules

The module with the name myCoolModule is accessible using Mediator.ready(moduleArray,readyCallback):

  var Mediator = require('famous-mediator');
  Mediator.ready(['myCoolModule'],function(myCoolModule){ .... });

You can also mediate using global events and Mediator.on(eventName,moduleArray,eventcallback)

  // in PageController.js
  Engine.emit('link-clicked','/homepage');

  // in RouterMediator.js
  Engine.on('link-clicked',['router'],function(href,router){
    router.set(href);
  })

As you can see, you can specify a module array to ensure modules are ready.

Tips

Use global events where you can

  • If there is only a single instance of the module
  • If the context of the module is not important

Example: A 'navigate' or 'tweet' event doesn't care about its sender or context Counter example: A 'click' event might mean different things depending on its context (surface).

Write multiple mediators

Write mediators for routing, error handling, data-flow, etc. This makes it easier to maintain your software. (i.e. when you decide to switch from an REST API to Firebase, you can simply rewrite the data mediator)

If you hack, hack in the mediators

Keep your codebase clean and only add hacks in your mediators.

  • Mediators are application-specific and have little code. They are by definition not re-usable (because they couple). This makes it the perfect place to write hacks (which is usually highly app-specific code).
  • Mediators are high-level which make them safer to hack. When you tweak/modify/hack low-level code, you risk regression bugs and breaking everything that depends on it.

Changelog

0.2.0 (1/10/2014)

  • Added Mediator.ready and Mediator.on
  • Updated README.

Contribute

Feel free to contribute to this project in any way. The easiest way to support this project is by giving it a star.

Contact

© 2014 - Mark Marijnissen

Rate & Review

Great Documentation0
Easy to Use0
Performant0
Highly Customizable0
Bleeding Edge0
Responsive Maintainers0
Poor Documentation0
Hard to Use0
Slow0
Buggy0
Abandoned0
Unwelcoming Community0
100