1) Seperate Layout from Content
- The AppView from Timbre is a counter-example: it mixes a generic UI component (a sidepanel menu slider) with app specific views (MenuView, PageView, animating stripes).
- Better create a generic SidepanelLayout, and populate with content.
2) Modules are self-contained and loosely coupled.
- Modules emit events
- Modules have a public API or respond to events
- The semantics should be in the domain of the module: i.e. a Todo-Item-View might have a method "updateContent", but not a method "onRestApiDataReceived". It's up to the "Mediator" to translate "RestApiDataReceived" to an "updateContent"
3) Content & Layout modules may have hierarchical dependencies.
- A parent may initialize its children.
- A parent might expect certain events from its children.
4) Service modules use an Adapter or Facade pattern.
- The adapter simplifies and abstract a more low-level api, and can optionally add security. For example, a DataService might implement roles and permissions and abstract from a RestApiService.
5) Mediators "couple" the app by listening to events and calling public APIs.
- A mediator adds virtually no logic and is as thin as possible.
- A mediator listens to the event of one module, and calls the public api of another module.
- Mediators are app-specific, throw-away code.
6) Mediators expect lifecycle events from modules
i.e. imagine a Todo-list app with multiple Todo items, which all need to be updated with the latest data from a Firebase service module.
A todo item might announce its existence as follows:
Engine.emit('created',this);
Using the Engine singleton to emit "created" and "destroyed" events is very useful. It provides an single entry-point for mediators to start coupling, and it makes sure that Content, Layout and Services have absolutely NO external dependencies and NO knowledge WHATSOEVER about other APIs.
7) A mediator is allowed to have many many dependencies
8) Mediators are singletons
9) Multiple mediators are allowed
i.e. a DataMediator to couple a RestAPI with Content modules, a AudioMediator to play audio when the user presses a button, etc, etc.
- mediators are allowed to be "one-size-fits-all": i.e. it can respond to both a RestAPI service and a Firebase Service. Depending on which module is instantiated in the app, it updates content using the public API of content modules.