Don't Do These Fatal Mistakes With a Multi-Module Architecture

preview_player
Показать описание
If you build an app with a multi-module architecture, there are many things you can do wrong. In this video I'll tell you about the 2 biggest mistake you can do.

Get 25% discount on all my courses till Sep 4th with the code CICD:

💻 Let me be your mentor and become an industry-ready Android developer in 10 weeks:

🎓 Become an industry-ready developer in the Mobile Dev Campus:

🎁 Get my FREE 4.5h course "The Best Practice Guide to Android Architecture":

Read our weekly Android blog:

Join this channel to get access to perks:

Join my Discord server:

You like my free content? Here you can buy me a coffee:
Рекомендации по теме
Комментарии
Автор

I understand that Philipp has its own opinions on this subject, but calling these approaches "fatal" is wrong. They are not even mistakes. Whether you choose data modules, common modules, feature modules or hybrid depends on the project, period! e.g MVP, AB-Testing, hardening, libs, integrations, sdks may have different requirements and modularization patterns are changing along with development. Generally, you should to aim for low coupling and high cohesion, with some trade-offs.
Anyone working on modularization of a large App module architecture with Dagger2 or Hilt knows how hard it can be. Cyclic dependency errors, missing bindings, moving assets, dependencies, sub-module to App communication problems are common. It is true, that modularization from day one takes more time, but this is nothing comparing to modularization of a monolithic application. Deciding when is the best time to start modularizing and explaining why you need to add this refactors to sprint planning are not easy as well. If you use mediator modules, common modules and feature modules wisely, right from the beginning, it will pay off.

pitoszud
Автор

Surely modularisation requires some work and may not always be worth the hassle. However, extracting a platform-independent business logic SDK into a separate module so that it is isolated from the application's platform-specific code somehow still sounds like a good idea to me for very many projects.

ArthurKhazbs
Автор

Thanks for such a comprehensive answer to multi-module approach, cause in most of articles I've faced, modularization by layers everywhere is positioned as a just alternative to modularization by features, and I have the same concerns about modularization by layers, that you just described in video. Very cool!

romangolub
Автор

it would be great if you could make a tutorial to use kotlin DLS, set up ... kts like in the video above.

aichoai
Автор

I wouldn't say that dividing application into data, domain, presentation etc. is wrong. For example one person can work on data, domain and another on presentation module. The only place where the modules meet is interface. Modules are good for dividing the work in team and avoiding merge conflicts. How often did you reused module any way ?

misiu
Автор

once I modularize the app, how can i have a team work on one module while not exposing the rest of the app using a VCS (ie:git)?

lepro
Автор

TBH I am not a big fan of having the core modules, because, in the end, this will become a kinda god module. All the features modules will be dependent on this module. And change any change in the core module would frequently happen because everyone will put all commons methods utility functions will lead to recompilation of this core module and because of the dependency graph of modules with core can't achieve the parallelism until this god module gets compiled.

QumberAbbas
Автор

How about sharing some useCases or dataSources between features, should we duplicate them?? 🧐

Mindfulness
Автор

Thanks for the great content!
I didn't use modularization yet, but i will definitively be looking for or even creating CLI tools to help me build the modules if it takes that much time. I understand that early modularization can be bad, but "costing a lot of time" to setup the modules shouldn't be the reason, and if it is then we need a tool to fix this situation, the best way to handle wasted time to do "setup stuff" is investing even MORE time to build tools to automate the boring parts, because you only write it once and it helps in every other project. In the end it is just boilerplate code for Gradle to be happy and the modules work properly. Other technology stacks already have the tools necessary so that the developers don't need to manipulate code to create/attach a module as a dependency. But as I said, i didn't work with modularization yet, maybe such tools are not trivial to create in the Android&Gradle ecosystem (for such a mature tool like Gradle it shouldn't be a challenge though).

tiagosutter
Автор

one must have to deal with the layer-based modularization when it comes to Kotlin multiplatform. otherwise yes i totally agree with you on the drawbacks of such strategy :) good video

khiariyoussef
Автор

I think you have missed a thing, if we don't create modules based on layers, how can we expose only domain layer?

abhisheks
Автор

Hey, Philipp, thank you for the video.
It’s always fun and useful to look at some ideas from your perspective. Keep it up.

SAS
Автор

Thank you for such a useful video bro! You made my day as usual✊🏻😊😉

abuiman
Автор

Only question I have is that in which case we would require to have layer based modularization?

asinggsingh
Автор

When you have many feature based modules, to setup a CI\CD process for this would be a hell I guess ?

andriisolomonov
Автор

I wonder how teams work in most cases. Do you have a team (or developer) per screen? Or do you have a data specialist and a ui specialist. I would think that's an important consideration in setting up modules.
Another question is: what is likely to be stand-alone. Obviously everything in an app is linked to each other in some way. But I would think that a screen, from ui to (local!) data, may be relatively stand-alone. On the other hand, if the data is a large enterprise db, then the DB isn't even owned by the android developers - they may have to request db changes to the db-administrator. Even the public interface to the db (a REST server, cloud service, ...) may be a team that 'serves' not only android but other 'clients' as well.
As for compile time in a one-dev project, I would think that a screen (feature) is more stand-alone than a layer, and I'd be inclined to make modules vertical (module per feature) rather than horizontal (module per layer). Having a full grid-split (vertical as well as horizontal) seems overkill for a one-man project.
Anyway, it's a classification problem (Lego blocks per size or per color?) and therefor no solution is perfect.
For a specific (beginner) project, I've decided to keep the data in one module, as the DB structure is pretty much fixed and won't change often. I may split the screens in separate 'features' modules, as I won't be tinkering in one screen while working in another one. But maybe that creates too much gradle overhead.

ErikBongers
Автор

Great video Philipp. Thank u. But what about the common use cases or data classes?

mesutemrecelenk
Автор

I would instead recommend having a top level "domain" container module that contains various submodules parts of your domain("domain:a", "domain:b"), and a top level "data" container module that contains various types of data modules associated with your domain ("data:a1", "data:a2", "data:b1", etc.). And finally a third presentation or feature module container that contains your various features modules.

The feature based structure here assumes that your domain is tied to a specific feature, which is not always correct. For example, think about a "user" domain (and associated object / use cases) containing information about your "user" account. You would want to reuse that "user" domain object (and underlying data layer) across multiple features, perhaps in the user account page (where you display the full user details and where they can edit them) or in some home page where you welcome the "user" by their first / last name and wish them a happy birthday once a year (using their DoB). In all likelihood this would be coming from a single user domain object (cached).

Your domain and the associated use cases is potentially going to be reused across multiple features / screens (as it should be), and so shouldn't be tied to a specific screen or feature. The package structure presented here (although it works) would suggest to other developers working on the project that presentation / domain / data are one and the same.

If you reverse that package structure (domain at the top) then you will start seeing your screens / features as just ways to display and assemble multiple domain objects together via a view model or similar (almost like architectural composition).

flamfloz
Автор

Slow builds alert: move all kapt to separate leaf-module. It will make your builds much faster as they won't compile if you do not change them

evgeniivorobei
Автор

Hello Philipp, interesting video ! I have been using for years a layer-base multi-module architecture and I'm happy with it. This feature-base management sounds interesting. I will give it a try. One question though. As said in your video, you structure each module by layer. Does it mean you create a dedicated retrofit instance for each data layer ? What about Room instance and di directory ? Thanks in advance;

xavierrispal