Breaking the monolith: scalable native apps

Building one-off apps that have a single focus (for example games, picture viewers or “ToDo” apps) is relatively easy because those apps can be designed, tested and implemented in a wholistic manner.  In other words, the product teams that build those apps have a very clear picture of what the end product will be. Banking or telecommunications self-serve apps on the other hand are often less clear or constantly evolving.  These apps are generally produced by large organizations with competing or conflicting  internal objectives, timelines and budgets – as a result, these apps (when built as monoliths) are delivered late to market because each feature that is owned by a sub-division of the company has to wait on one or more major pieces provided by other sub-divisions.

How can these apps get to market faster?

Simplify, decompose into reusable units and break dependencies – In other words, large apps can get to market faster by going back to the basics of software design. Let us use a simple example of a restaurant app… Let’s call it CookR.io. CookR.io is (fictitiously) an app that allows a customer to submit an order that gets prepared by a crowd-sourced chef… (Before I go any further, I would like to shamelessly ask that if any reader wishes to build this app, please credit back to this site for inspiration :-D, please and thank you!!!). The app must be available on Android & iOS and must be launched on the same date.

Implementing this is relatively straight forward. Build the app, ship it. How we build this app however, will determine how quickly we can iterate on its features in the future. The typical approach here would be to have a single project with all the logic embedded, maybe sorted by folder structure or package name.

Monolith.png

This approach works, but we can definitely break the app into discrete units.

Step 1: Create a core component that does the basic functionality

A good example is to create an application scaffold that provides the UI layout and interaction design. This scaffold will reference the components defined in step 2 by library version and also have any visual integration points that are required.

Step 2: Identify the discrete functions of the app

In CookR, this could include taking an order, sourcing a chef, providing status update via push notification or processing payments. These units would then be built as components/libraries that can be uniquely versioned, expanded upon or completely re-written at any given time without affecting the progress or delivery targets of the overall application. This also means, that each of these components can have their flows defined and implemented in total isolation. In the case of a large organization, this translates into a situation where separate sub-divisions can quickly meet their own objectives and deliverables without affecting other teams, unless of course they have a hard dependency on a specific version of another component.

Step 3: Integrate each component

With steps one and two out of the way, integrating the components will be a breeze. The only requirement here, is that the core application scaffold defined in step 1 creates visual entry points (buttons, links etc.) that will trigger calls into the components. The components can then take over and deliver the experience that is defined in that component.

Our decomposed application now looks like this:

Componentized.png

As you will see above, the overall application is now less brittle to changes because stable versions of the components (libraries) can be referenced by specific iterations. Departments are then free to re-use, re-create or otherwise augment the functionality provided by these libraries at will. In our example, if the organization decides that the application needs to go to market with a Chef Sourcing functionality that has Facebook integration on March 9… This structure allows all the team to build this entire flow in Chef Sourcing 2.4.1 without affecting any existing code that depends on 2.4.0. The improvements can be unit and functional tested independently without a single code merge request until required (lets say march 7 for example). In practice, the date may not be so close, but the key thing here is that on March 7, depending on the UI design for Facebook integration this feature could be delivered to market with zero code changes to the application, since code changes were only done in the Chef Sourcing library that is consumed by the core application! Neat right?

Of course, this doesn’t account for crazy scheduling or other factors but this approach to mobile application structure opens up a world of possibilities for cross functional team collaboration and faster application delivery.

This is the high level concept… Next week I will use the CookR.io example to illustrate how this can be done on both iOS and Android…

#UntilThenCodeTight #HappyMonday

-Martello Jones

 

Published by Martello Jones

I enjoy working on interesting projects that make life better.

2 Comments

  1. Interesting read….looking forward to next week’s illustration.

    Like

    Reply

  2. […] this post, I will continue where I left off on part one “Breaking the monolith: scalable native apps,” by giving examples of how large projects can be decomposed to allow faster iterations. I […]

    Like

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s