Skip to content

Modules

Giuseppe Lanza edited this page Dec 31, 2018 · 4 revisions

A module in MERLin' should be a framework. The core concept of a module is the idea that it should be an isolated sandbox that can live without external dependencies (or with a minimum subset of dependencies) abstracted from the main target and other modules. Making a module as a framework will help you with this job, will give you clear awareness of imports, a clear understanding of the dependency graph and it will help the compiler to do a better job. With this choice you will have for free a series of positive side effects:

  • Mistakes will not propagate to other modules.
  • During development you can build just the module you are working on, saving build time. No need to build the whole app.
  • Testability of the module with unit tests and UITests is very simple.
  • The control over the dependencies will make easier refactoring and if needed replacing the module itself.

Each Module in the app should be usable as a black box without knowing which is its particular architectural implementation.

When creating a module it is necessary to create a class that acts as an interface with the outside world and exposes a rootViewController. This class must conform ModuleProtocol.

If user interaction is possible with a module's ViewController the module should expose the events that represent the user's actions. To do so it must conform to EventsProducer and expose an Observable of EventProtocol to events listeners. For more info about Events please visit the Events and the Listeners pages of this wiki.

The module class is the entry point of a module and is the correct place to perform configuration and dependency injection of the components in the module. If you decided to build your feature module following an MVVM architectural design pattern, the module class is the correct place to set up the view and the view-model, inject dependencies for data interaction, etc.

Build contexts

To build a module instance, a build context is required. A Build context represents the initial conditions that triggered the module to be built, for example, a product detail page Module will need the id of the product it must show, as well as the Product List module will need the id of the category it has to display. It will also contain a disambiguation variable declaring which routing flow caused the creation of the module.

Recommendations

Exposing objects to the rest of the world

A module can expose interfaces for objects it uses and manipulates, but it should never expose the real objects implementations.

Internal routing

In some cases, modularisation is overkill as a particular ViewController might be needed only in one specific use case like filters for a products list. In this case, a module can have internal routing, and handle more than one controller with an internal router (again, all depends on the architectural design pattern you decided to follow).

This kind of approach should be used in case a particular viewController will never be re-used or needed in other app use cases.

Clone this wiki locally