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 ofDomain
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.