Adding Some Architecture
MVC. MVP. MVVM. MVI. These abbreviations get tossed around a lot in app development discussions, and increasingly in Android app development discussions. Those using these abbreviations often think that:
- Everybody knows what they mean, and
- There is a single universal definition for each of those abbreviations, one that everybody holds
In reality, these MV* abbreviations are well-known in some circles and unknown in others. And, even among people who think they know these abbreviations, there is a fair bit of disagreement about what the abbreviations mean, particularly when it comes time to writing actual code.
This book is not a book on GUI architectures. However, in this chapter, we will explore some facets of Google’s architecture recommendations.
Repositories
One key to Google’s recommended architecture pattern is the repository. Rather than the GUI code dealing with things like disk and network I/O, we delegate that to a repository, which handles those details. The GUI code just works with the repository, one typically implemented as a singleton object (a global instance that all pieces of the app can use).
Objective: Isolation
We really want our GUI code to be separate from our I/O code.
Mostly, that is for testing purposes. When we want to test our GUI code, we may or may not want to actually go through that I/O:
- I/O is slow, and being able to use some sort of mock repository that is purely memory-backed would allow tests to run faster
- Server I/O can be a problem, as there may not be a server that you can use for automated testing
- We often need to test specific scenarios, and it is much easier to do that if we can have a mock repository that we can control, rather than have to set up files (or, worse, server entries) to get the real repository to respond the way our scenario requires
Repository Structures
Simple repositories — like the ones that will be shown in this book — work directly with files, databases, servers, and the like.
Some projects will add another layer of indirection, where repositories work with “data sources”. A data source would be responsible for the direct I/O with one particular set of files, or a particular database, or a particular Web service. The repository would interact with the data source.
Mostly, the data source abstraction is there for complex repositories:
- You want to add in-memory caching at the repository level, and therefore you want to separate out the I/O logic into another class
- You need to support both local I/O (for a persistent cache) and network I/O (the source of shared or updated data), and putting all of that in a single repository results in a huge class
- The actual data source itself is user-configurable, both in terms of details (e.g., email account information) and protocol (e.g., IMAP4, JMAP, POP3), where the repository does not know at compile-time what data source implementation will be needed
So, while the apps in this book largely will skip the repository/data source separation of concerns, that is just because the sample apps are pretty tiny.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.