The current structure of my app is as follows:

  • One activity and multiple fragments (about 25 fragments)
  • One huge monolithic repository
  • One huge monolithic viewmodel
  • Databinding is being used but with one huge monolithic handler class
  • Navigation Component with one nav graph for the entire application

I've been learning as I go and I now realize my architecture is very poor. I want to achieve proper MVVM and also to modularize the project. My end goal is to have an architecture that is more maintainable and testable. I'm aiming for the following:

  • Separate viewmodels for each fragment
  • Separate repositories for each entity (or roughly each data access object)
  • Separate data binding handlers for each fragment
  • The entire project split into different library modules, with each module being specific to a feature or core function

In order to achieve the above outcome, is the following a reasonable plan?

  1. Create separate viewmodels for each fragment
  2. Create separate repositories for each entity
  3. Create separate handler classes for each fragment
  4. Divide the entire project into separate modules

Some of the sources I have come across while researching are:

Please could you advise whether the above rough plan is a good one and any pitfalls I should be on the look out for?


1 Answer 1


In broad strokes yes, but I would hardly call that a plan. Its a painting of scenic vista you wish to see.

The plan would be the concrete steps/strategies you are going to use to get there from your already working monolith.

Push and Pull

Perhaps the easiest way to start getting there is to pick one function. That function is probably a jumble of concerns that should exist at different levels. such as high level business concerns mixed up with the specifics of how to get data from the repository.

This is where push and pull comes in. The goal is to separate these concerns out so that a function is talking at the same level of abstraction throughout. Perfection is hard to achieve, but you can probably improve on what you have.

The benefit of pushing details down, pulling abstractions up is that it will make each function easier to read. But the downside is that you will have many many more functions.

Sprout and Split

Now that we have a clearer picture of what the code is doing, we can start organising the functions into particular services. These functions are all about display, these about data storage, these are to do with this business concern, etc...

You can Sprout those related concerns into an object hidden as an implementation detail of the larger object. If they are truly generic and could be used elsewhere then we split them off and make them a true collaborator.


Now you have a plan of how to go from what you have toward something better.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.