Design Patterns - mobitile/mobitile.github.io GitHub Wiki

Dependency Injection

This is very common and well-known pattern it helps build extensible application, in MobiTile dependency injection is implemented through Parsley's Inversion of Control Container. In brief each functional area defines one special class called Config that contains all that need to be available for injection, then these Config classes are registered in Parsley by passing their instance during building Parsley' Context. Now when these classes are registered in Context the instances they define are available for injection. Note that injection is available only for instances that are in Context too. Once dependency and dependant both are in Context it is possible to resolve dependency using [Inject] metadata tag:

[Inject]
public var albums:Albums;

For more info see Parsley's documentation

Command

The Command pattern is main implementation for Application layer. It is useful when need to incapsulate some functionality and make possibility to use it in the future. Note that in MobiTile Commands pattern is implemented through spicelib-commands library and follows convention it defines. So Command SHOULD contain public method public function execute():* where functionality is performed, and COULD contain public variable public var callback:Function; for asynchronous commands. For more information see documentation of the Parsley Framework.

This pattern includes three actors - Message, Command and Interceptor

  • Message - the simple data-transfer object that used to trigger specified one or more Commands, it can contains data that can be used by Command;
  • Command - the implementation of Command, usually in MobiTile it calls correspond method of Domain and handles of its result.
  • Interceptor - this class can intercepts message before corresponded Commands are triggered and can delay or interrupt them, it is useful for Commands used for delete, in this case Intercepter can ask User if he/she definitely want to remove some thing and if he/she answers YES the Command is performed and interrupted for NO.

To bound these three classes together these three classes should be registered in Parsley' Context. There are various ways for this, but in MobiTile next is common (let's see SettingsFeedsRemoveCommand command):

  • register Command in Config class:
public var settingsFeedsRemoveCommand:RootConfigurationElement = MappedCommands.map().command(SettingsFeedsRemoveCommand).build();
  • register Interceptor in Config:
public var settingsFeedsRemoveInterceptor:SettingsFeedsRemoveInterceptor = new SettingsFeedsRemoveInterceptor();
  • then in some place in application call Parsley's message dispatcher passing instance of the Message to it:
[MessageDispatcher]
public var dispatch:Function;

dispatch(new SettingsFeedsRemoveMessage(settings.selectedFeeds));

Presentation Model

One of many patterns for working with Views in MobiTile each screen and some of popup has its own Presentation Model counterpart. This classes ends by PM suffix, for example DasboardPM is Presentation Model for DashboardScreen screen. Presentation Model classes represent behaviour and state of corresponded view, this more about that. In brief PM binds view with other system.

Contracting Design

It means approach when Interface is building block for the design and Class that implements it just a particular case of implementation. Should not confuse with Design by Contract that is more concrete and usually is supported by language. Let's see Services as example, Service is a common implementation for Infrastructure layer and it is just Interface. Each Service defines a contract for concrete area of responsibility. For example, FeedbackService defines contract for feedback responsibility and has two methods function log():Promise and function crashReport():Promise; in application we use this Service for design without knowing implementation details. Implementation comes to play in only one place in Config file:

public var feedbackService:FeedbackServiceImpl = new FeedbackServiceImpl();

It makes application be independed from implementation that makes it more extensible.