Today I will talk about the inside, the code, of an app and how it should be organized to achieve higher quality and to make it easier to maintain. There’s nothing revolutionary about this approach, on the contrary, it builds on the same ideas that has been used for many years when building solutions on the server side.
For the same reasons that many systems on the server-side have applied a three-tiered architecture, an app should also separate the concerns when handling presentation, logic, and information (as suggested by popular patterns like MVC, MVP, MVVM, etc).
Here is an overview of an app connecting to a server, and this is a simplification in two main tiers (client and server), but note that the same separation of concerns (responsibility) is present in both the app and on the server.
Starting from the top on the device, we have the user interface that consists of the actual layout with visual element such as controls as well as the interaction and navigation logic. It uses the app-dependent or independent logic (business/domain rules) and the data tier handle the app’s information in the form of entities, network operations to access remote services, and maybe even local storage. Spanning all tiers are the common services such as security, utilities, etc.
On the server side, the service interface publish the functionality in the form of clearly defined contracts, and the others tiers has a similar responsibility as on the device. Of course, the server can in turn call other services, and that is exactly what usually happens in Omnichannel Services.
The role of the user interface components is to provide the best user experience possible. This is a huge subject, and not within the scope of this video, but it’s not only about something that looks nice, but also feels good (something that performs well). The user interface components should know about each other, they should know about data in the form of entities, and they should know about logic components (domains). But the user interface should never know about networks, URLs, protocols like JSON, or even key-value pairs derived directly from JSON. They shouldn’t have to worry about how data is persistently stored or cached, or any other lower-level logic.
The entities are the representation of data in a form that makes sense to the app. It may have the exact same structure as the data retrieved from the server (when Omnichannel Services are in play one can come really close), but may have a different structure that better suits the app. For example the app’s entities may add attributes that are only valid for the app (e.g. a flag that something is a favorite, if favorites are only stored on the device). The entities also know how to parse the raw data (JSON) from the server to populate its attributes, and that also includes any related entities (e.g. an order entity will probably use order row entities to parse their data). The entities will probably not implement much logic, with the exception of derived attributes and any entity-related rules, and should not know anything about either the user interface or what the operations knows (URLs, network requests, etc).
Operations make network calls to (web) services on the server (preferably Omnichannel Services). They handle all the logic that is involved in network request, like HTTP return codes, authentication, exceptions, response caching, etc. They also initiate the parsing of data (JSON) to entities. Just as the user interface should not know anything about what operations know, the operations should not know anything about the user interface or entity internals.
The idea behind the domain components is to implement the logic of a specific business domain. It could be an order, and then the domain would know about a number of operations and entities, e.g. order details, order rows, customer, delivery address, etc. Domains will manage both the data and logic related to the cluster of entities and operations that form the (business) domain. This also includes the caching and refresh of that data, using any kind of storage (database, file system, etc). The user interface use domains to get the data and the logic they implement, but domains doesn’t know anything about the user interface.
So there you have the basic anatomy of an app and how it can be organized to get higher quality and to make it easier to maintain.