Tuesday, April 16, 2013

Book Review: Appcelerator Titanium: Patterns and Best Practices


Authors: Boydlee Pollentine and Trevor Ward


This book targets developers who are already familiar with the Titanium Mobile API and JavaScript programming.  Topics covered span JavaScript programming practices to application architecture.  Each area is discussed at a fairly high level, which makes for an easy read.  The authors do a nice job of offering suggestions that can help developers create well structured applications.  Specific chapters are:


  1. Understanding JavaScript Patterns
  2. Titanium Best Practices
  3. Building and Application Using CommonJS and the MVC Pattern,
  4. Cross Platform Design Methods
  5. Using JSONDB as an Alternative to SQLite


JavaScript variable scope is different from that of most of the strongly typed languages.  Add CommonJS into the mix and you have even more scope considerations.  The first two chapters navigate the developer through object scope, show how to avoid “gotyas” associated with something as simple as placement of a curly brace, and show in general how to write clean JavaScript in CommonJS modules.  The authors also take you into the Titanium Studio environment and show how to enable strict JavaScript validation using JSLint.

The third chapter provides a nice overview of how to structure an application using CommonJS with an MVC pattern.  Changing from namespace applications to CommonJS can be difficult to get your arms around.  Pollentine and Ward do a nice job of laying out specific examples for organizing the different application components, for bootstrapping an MVC application, and for managing interactions across components.  This includes examples of using callback functions, which is  a key technique for developing Titanium Mobile applications.

Chapter 4 is more than just cross platform considerations.  The authors start by reinforcing some of the changes in component sizing introduced in Titanium 2.0.  They also discuss in general how to implement common styling across an entire application.  Then they show methods for overlaying platform specific styling as needed.

The last chapter is an introduction to using JSONDB for persistent data.  It’s presented very nicely within the context of implementing a news reader application.  The authors demonstrate all the standard CRUD operations.  

Overall, I would say this book does a nice job of filling the void between having learned the Titanium Mobile API, and knowing how to structure a production quality application.   I like the way the author’s present their best practices as recommendations, rather than “THIS is how you MUST do it.”  I’d recommend this book for any Titanium Mobile developer.

Wednesday, November 28, 2012

Applying MVC Architecture to Titanium Mobile Apps

Appcelerator's Titanium Mobile is a great tool for cross-platform mobile development.  Appcelerator publishes documentation and guides, the Kitchen Sink project gives a view into some best practices, and project templates can get you started quickly.  However overall application architecture is left to the developer, and designing any substantial app can be a daunting task.  This article describes my approach for implementing the Model-View-Controller (MVC) architecture within Titanium Mobile Apps.  Note: I'm assuming the use of CommonJS for everything.

Project Layout

Here's the basic structure I like to use for projects.

  • application - Contains application-specific code.  This keeps the folders containing actual code from being separated by those containing images or other general components.
  • images - Contains all the image files for the project
  • lib - Contains reusable, general purpose libraries.  For me this is usually underscore.js, underscore.string.js, and internal libraries that I extend as I go.
Then, within the application folder components are organized into the MVC structure.

  • controller - Contains the business logic components which access data via model components and present information to the user via the user interface components.
  • model - Contains components that provide data access.  That means remote data as well as local data, which might include application properties.  Ideally you could change the underlying data source used by you model components without changing any of your other code.
  • ui - Contains our application-specific user interface components.

Example

I generally like to setup each controller and data entity with corresponding function calls.  My recent work has been on a Customer Relations Management app that involves a fair amount of standard database maintenance functions.  So, many of the controllers have functions for list, detail, create, edit, and delete.  Their corresponding data entities then have the same or similar functions.  The consistency makes maintenance straightforward.

If we were implementing an app that allows users to maintain a list of customers we might have these components:

Controller

  • customerController - Provides access to list, detail, edit, create, and deleteRecord functions.  ("delete" is a keyword so I usually use deleteRecord.)  I've found that controllers are often non-instantiable libraries, so they are named with an initial lowercase.

Model

  • customerEntity - Used by the customerController to access data.  It might implement list, detail, create, and deleteRecord functions.  This example is named for non-instantiable library. 

View

  • CustomerListView - Used by customerController to display a list of customers.  User interface components are generally instantiable, so they are usually named with an initial uppercase.
  • CustomerDetailView - Used by customerController to display details for a single record.  (Instantiable)
  • CustomerEditView - Used by customerController to edit existing records and to create new records.  (Instantiable)
Here's what it would look like within the project.  Note that the user interface elements are further organized into folders named for their controller.  I've also added a model.js library which would contain application-specific functions common to multiple data entities.


If you want to apply this structure to everything, you could add an application controller which might handle your bootstrap logic and open your application window.  Perhaps you'd have an application entity that would manage access to configuration settings.


Now as we add more and more functionality the structure stays very organized.



Why Bother?

If you don't currently separate business logic from user interface code, you might think, "That's all very nice, but why bother doing this?  I'm still writing the same code.  It's just in different places now.  If I want to add a field to a screen I'll have to edit two or three files instead of one!"  Well, consider this:  What if during the design phase you notice that the views which list records are pretty much the same.  You might write a single component that you instantiate with the data and callback functions that it needs to function.  Part of a customer controller that uses this generic list view might look something like this:


var ListView = require('/lib/ui/ListView'),
    customerEntity = require('/application/model/customerEntity');
.
.
.
var create = function(args){
//Some code to display the edit view with what it needs for a new record.
};

var detail = function(args){
//Some code to display record detail.
};

var list = function(args){
// Define the fields which the list view is supposed to display
var fieldDefinitions = [
{fieldName: 'company_name', type:'text', ....},
{fieldName: 'address', type:'text', ....},
{fieldName: 'referral_source', type:'text', ....},
{fieldName: 'initial_contact', type:'date', ....}
    ],
    listData = customerEntity.list(),
     customerListView = new ListView({
fieldDefs : fieldDefinitions ,
data : listData
onRowClick : detail
onNewClick : create
     }); .
.
.
};


At this point you've replaced a bunch of potentially mind-numbing UI code with a reusable component that you can add to your personal library, you've guaranteed consistency across all the listing type views, and now you have a only single object to maintain for all of your lists.

What if you can do the same thing for the detail and edit views?  Now, to add a field to your detail view you just need to adjust your data entity to include the field, and define it's attributes in the fieldDefinition object for the generic detail view.  This type of code reuse is one of the benefits of separating business logic from user interface.

Additionally, from a maintenance perspective it's nice to have the components separated.  You can address changes to business logic without wading through lines of display logic.  Having data access encapsulated provides you some extra flexibility that you may need as your app matures.  You may need to change one aspect of your app that has always used live remote data to something that can now function offline with a local database.  Under this type of architecture you should be able to make that change without ever touching your controller or the associated user interface.

Wrap-Up

OK, I started with a nice overview of how to structure an app according to MVC, and provided some nice conceptual examples.  Then I had to go and include a potentially confusing code snippet!  If the code doesn't make sense to you, just set it aside for now.  Take another look when you need to do something similar.   I think it's a powerful approach which I've implemented, but it can make the head spin if you haven't done something like this before.  Perhaps a topic for another day!