Maximizing the Leverage of Architecture in Android

John Li
The Startup
Published in
5 min readAug 15, 2020

Picking the right architecture pattern can be a debated topic. There are plenty of popular options like MVP, MVVM, Clean Architecture, etc.

The general role of architecture is to do several things

  • Establish a common & reusable structure
  • Establish flow of data & control
  • Encourage separation of concern

Let’s assume we make the bold claim that architecture doesn’t matter. Okay, what are we left with then to talk about? Architecture Components

Architecture Components

These are the building blocks and patterns that compliment the codebase. Architecture components are the real heroes that deserve a lot of attention that architecture is hogging.

Architecture components are also the implementation of the promises made by the architecture.

MVVM is composed of 3 architecture components

Repository Component Example

Let’s look at an example of a repository that retrieves app details and how it highlights the importance of design and implementation.

This implementation has the following qualities

  • AppRepository holds a reference to the consumer
  • The repository handles threading internally.
  • The repository result is communicated through ResultCallback

The code works but could we do better? Yes, yes we can.

The new implementation has the following qualities

  • AppRepository is a contract which helps make the actions reusable, extensible, and more testable
  • We use coroutines instead of a callback to deliver results
  • The consumer of the repository can pick the threading policy

The design and implementation of the components are important and will have far-reaching implications, more than we will ever initially foresee.

We can do a thought experiment and think about the factors we haven’t considered with the repository component.

  • Does the repository allow for easy integration with caching?
  • How can I integrate app-performance monitoring with the repository?
  • What should be the scope of repositories and how does that fit into a multi-module project?
  • ????

We can only do our best.

Can’t design or plan for everything

Qualities of Good Architecture Components

There are so many things that can be attributed to good code. The very same qualities can be used to describe good architecture components.

Reusability

My entire understanding of object-oriented programming is for code to be more reusable. Some components are more reusable than others. We can use Uncle Bob’s definitions of policy and detail to guide us here. Code lives on the spectrum of detail to policy.

Detail & policy with regards to common Android architecture patterns

The policy represents the core business concepts and actions. The code on the policy side is less likely to change because business rules rarely change. The code representing policy is platform-agnostic. These classes are also great candidates to include in a multi-platform module.

The detail is the implementation of the policy. For example, views are the interface implementation that allows a user to interact with the business.

The code closer to the detail side of the spectrum is more volatile and likely to change over time. We can see an example of this if you update the target Android SDK to a higher number. You’ll likely have to add code to handle version differences.

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) ... else ...

Notice that you’re more likely to update code in the Activity/Fragment rather than your presenters or interactors.

Here’s a look at the spectrum with common Android architecture patterns

Detail & policy with regards to common design patterns

We dived pretty far into policy and detail. Here’s what we need to know about how this affects reusability. Components representing policy are more reusable. The code should reflect that.

This isn’t to say you can’t have reusable fragments, activities, or Android SDK classes. There is a larger amount of effort to make Android SDK classes reusable.

Modularity

The bane of tightly-coupled code! Modularity enables your components to be more plug and play. This quality requires decoupled components.

Coupling should generally exist when there is good code cohesion. Code cohesion is the likeliness that changes in one class will break the expectations of another class. Classes that change together should be closer to each other.

Here are a few signals that your code is modular

  • Strong cohesion between encapsulated classes
  • Clear contracts with hidden internals
  • Ready to support versioned releases (JAR or AAR)

Extensibility

This is a quality that gauges how easy it is to reuse your existing code/components/patterns. Inheritance and composition are the vehicles used to extend code.

If you’re following the Open-closed Principle, you nailed down this quality.

Testability (Unit Tests)

The ease of writing tests for your code is a sign of its quality.

Are you spending a lot of time mocking dependencies for a 20-line method? You’re breaking the Single Responsibility Principle.

Does your class FooBar have only 1 public method and 10 private methods? You’ll notice that writing tests for FooBar will be harder than it should be. It is also a sign that other classes will have a hard time collaborating with FooBar.

Final Thoughts

The list isn’t that long and it is reasonable for your components to hit every one of those checkboxes.

Choose the qualities that align best with your team and product. Build the best architecture components that will compliment your architecture.

Bonus Super-opinionated Thoughts

  • I dislike the VIPER architecture pattern. It is a set of highly-coupled components that need a lot of effort to achieve reusability.
  • The Usecase pattern is a great pattern that embodies SRP, minimal coupling, easy to test, and high reusability.
  • Consider making your architecture support composing multiple Controller/Presenter/ViewModel in a single screen. It’s really helpful in avoiding god classes(500+ lines of code) when you run into a scenario where you have a view with a lot of features.

--

--