Blog Infos
Author
Published
Topics
, , , ,
Published
Unsplash@chuklanov

 

Designing an effective architecture for your Android project is crucial, especially when you aim to maintain it long-term. The strategy you choose depends on various factors, including the project’s scale, resources, goals, and tech stack.

When adopting a multi-module feature architecture, you can benefit from improved reusability, parallel development, and decentralized focus. However, it’s essential to carefully consider how to divide your modules — whether by feature, domain, or other criteria aligned with the specific needs of your project.

This article delves into an intriguing discussion about structuring a multi-module architecture, a topic recently raised on Dove Letter. Dove Letter is a subscription repository where you can learn, discuss, and share new insights about Android and Kotlin. If you’re interested in joining, be sure to check out “Learn Kotlin and Android With Dove Letter.”

How to Structure Your Modules in a Multi-Module Architecture

This is likely one of the first ideas you consider when you start configuring your project. An interesting question was recently raised on Dove Letter by a subscriber:

The subscriber has presented four different modularization patterns for consideration:

Pattern 1

Start with a feature module (folder) named onboarding at the root level. Within this folder, create two separate Android library modules: one for domain and another for presentation.

It is structured in a way where the primary module is distinct, and within it, there are separate submodules for the domain and presentation layers.

Pros

This approach offers a separation of concerns by feature but also isolates domain and presentation layers, which promotes a clean architecture. It supports modularization, encouraging the reuse of domain logic and facilitating independent testing by feature and its domain/presentation. Additionally, it is highly scalable, making it well-suited for large projects with complex features. So, if your team is very large, each team should work on very different features, and each concern should be separated; this pattern might be a great choice.

Cons

However, it can increase project complexity with multiple modules. Managing dependencies between these modules can also be challenging, potentially leading to interdependencies that need careful handling. It’s especially crucial to be cautious about potential circular dependencies in this architecture. If dependency cycles occur, they can make the project difficult to manage. Additionally, maintaining this structure requires strict adherence from all team members, which can be challenging and resource-intensive, which sounds very expensive 💸

Pattern 2

Create a single features Android library at the root level. Then, add all individual features as separate Android libraries inside the features module.

This pattern involves consolidating everything into a single feature module; it sounds very simple!

Pros

This is very simple. Easier to manage and less complex. If you believe you will build just a pet project or something more than 1~2 developers will not be involved, this pattern might be a good choice. Sometimes, simple is the best!

Cons

This pattern offers simplicity and easier management due to its less complex structure. While it allows for some degree of modularization, with features isolated within a single module, it has limitations in scalability as the project grows. Additionally, the domain and presentation layers are not isolated, which can lead to challenges in maintaining a clean architecture as the project becomes more complex.

Pattern 3

Begin with a feature module (Android library) named onboarding. Inside this module, create two additional Android library modules: one for domain and another for presentation.

This one sounds like feature modules are highly nested than the Pattern 1 and my answer is same as the Pattern 1.

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

No results found.

Jobs

Pattern 4

Create a feature folder at the root level and then create a single Android library module for each feature. For example, if you have an auth library module inside the feature folder, then organize it by creating subfolders for DI, Domain, and Presentation within the auth library module.

This pattern is well-suited for most projects, especially when your team is medium-sized (10~30 engineers) and doesn’t require the high scalability needed for teams of 50–100 engineers. Alternatively, you could opt to create separate domain and presentation modules at the root level, which allows for a clear separation of responsibilities in your codebase. This approach aligns well with the principles of “clean architecture”, which is popular for maintaining a structured and maintainable codebase.

Pros

The pattern simplifies structure by combining simplicity with modularity, where each feature is encapsulated in a single module with internal separation. It’s manageable and easy to navigate, making it ideal for medium-sized projects.

Cons

However, the pattern has limited isolation since domain and presentation layers are not physically separated into distinct modules, which could reduce flexibility. Additionally, it is less scalable compared to architectures that use completely separate modules for each layer. So if you separate the domain and presentation layers into an independent module, it must be better choice than this pattern.

Summarize
  • Pattern 1 and Pattern 3 are best for large, complex projects needing clear separation and scalability.
  • Pattern 4 is suitable for medium-sized projects where simplicity is key, but some modularity is still desired.
  • Pattern 2 is best for small projects where simplicity and speed are more critical than strict adherence to architectural principles. If you’re working in a team to quickly build a project to validate the feasibility of your business MVP, opt for this one rather than spending a lot of time building hundreds of unnecessary modules.
Conclusion

We’ve explored four distinct modularization patterns for configuring your multi-module architecture project, along with the pros and cons of each approach. As you’ve likely realized, the best way to structure your project’s architecture depends heavily on its complexity and scalability needs — there’s no one-size-fits-all solution. Each project has unique demands, and understanding those requirements is crucial for selecting the most appropriate architectural pattern.

If you have any questions or feedback on this article, you can find the author on Twitter @github_skydoves or GitHub. If you’d like to stay updated with the latest information through articles and references, tips with code samples that demonstrate best practices, and news about the overall Android/Kotlin ecosystem, check out ‘Learn Kotlin and Android With Dove Letter’.

As always, happy coding!

— Jaewoong

This article is previously published on proandroiddev.com

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
Hi, today I come to you with a quick tip on how to update…
READ MORE
blog
Automation is a key point of Software Testing once it make possible to reproduce…
READ MORE
blog
Drag and Drop reordering in Recyclerview can be achieved with ItemTouchHelper (checkout implementation reference).…
READ MORE
Menu