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

Sdílet
Vložit
  • čas přidán 31. 08. 2022
  • 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:
    pl-coding.com/premium-courses...
    💻 Let me be your mentor and become an industry-ready Android developer in 10 weeks:
    pl-coding.com/drop-table-ment...
    Subscribe to my FREE newsletter for regular Android, Kotlin & Architecture advice!
    pl-coding.com/newsletter
    Join this channel to get access to perks:
    / @philipplackner
    Join my Discord server:
    / discord
    Regular programming advice on my Instagram page: / _philipplackner_
    Checkout my GitHub: github.com/philipplackner
    You like my free content? Here you can buy me a coffee:
    www.buymeacoffee.com/philippl...

Komentáře • 56

  • @pitoszud
    @pitoszud Před rokem +74

    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.

    • @sergiucodes
      @sergiucodes Před rokem

      He's an youtuber, he has to bring viewers, can't you make the difference? he knows this already, but he is also trying to create content and attract people so yeah, redundant comment imo

    • @misiu9049
      @misiu9049 Před 3 měsíci

      Application life cycle needs to be taken into account. Monolithic application will take less time to finish and that might be what bussines side is expecting. Proof of concept before company allocates more money into specific application idea. Instead of allocating a lot of resources into something that they are not sure about.

  • @romangolub2720
    @romangolub2720 Před rokem

    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!

  • @tiagosutter8821
    @tiagosutter8821 Před rokem

    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).

  • @abuiman5251
    @abuiman5251 Před rokem

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

  • @196SAS
    @196SAS Před rokem +1

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

  • @lepro0
    @lepro0 Před 7 měsíci +1

    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)?

  • @mesutemrecelenk5447
    @mesutemrecelenk5447 Před rokem

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

  • @ArthurKhazbs
    @ArthurKhazbs Před rokem +2

    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.

  • @fliamachado
    @fliamachado Před 3 měsíci

    Hi @Phillip, one Question...
    Looks like "Onboarding" module was created as "New Module" (Phone & Tablet), but the inner "modules" were created as "Android Libaries" , is that correct ?, if it so, why "core" is created as library ? Thanks!

  • @wilsonahanmisi1187
    @wilsonahanmisi1187 Před rokem

    Hi Philipp, nice course btw. In your course only the tracker module uses room and I'm curious to know how you handle singletons like Room database and retrofit which are expensive to create with this approach

  • @misiu9049
    @misiu9049 Před 3 měsíci +1

    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 ?

  • @josefm7265
    @josefm7265 Před rokem +1

    Great video, and very informative as always! You explain very well so I have a video request/ a topic that does not have a lot of information available. Would you consider doing a video about firebase authentication and firebase registration of users using jetpack compose ? Would be awesome if you could! Anyway, keep those videos coming :D

  • @khiariyoussef3226
    @khiariyoussef3226 Před rokem +2

    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

  • @Akshaykumar-xr9yj
    @Akshaykumar-xr9yj Před rokem

    Please make a video on how to implement stripe payment in the app.

  • @aichoai
    @aichoai Před rokem +8

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

    • @imashnake_7151
      @imashnake_7151 Před rokem

      Gradle has great documentation that essentially walks you through migrating stuff, a video seems unnecessary.

    • @philipalveo
      @philipalveo Před 11 měsíci

      @@imashnake_7151 there are people who prefer videos in learning some stuffs, so for your perspective it's not necessary but for others who have a different learning curve, it's better

  • @xthmath
    @xthmath Před rokem

    Phillip, do we need a domain layer .. if I have sdk style library modules.
    I went to droidcon .. 2018 .. when they said it's useless to create Domain abstraction in a multi modular architecture..

    • @PhilippLackner
      @PhilippLackner  Před rokem

      It's an optional layer and there's no general rule how you have to structure your apps

  • @lumen5579
    @lumen5579 Před rokem

    Hey Philip, how would you do top level navigation then with this feature based modularization?
    Eg moving from onboarding to home screen.
    Keep in mind the onboarding screen shouldn't know what activity it opens after it's done.

    • @anujmukul4306
      @anujmukul4306 Před rokem

      You should have a separate module, call it as "navigation module" this should be implemented in the Master App (the main app that handles all the other features or modules).
      Just keep informing the implementation in the master app about activation by different modules (or moving to and from another module).

  • @Basirafeef
    @Basirafeef Před rokem

    thanks for sharing great knowledge sir.
    sir i created an app for multiple people from the same source with different name, themes, server and google's .json configuration file. the problem is when i update one i need to update others too.
    is there a why to create multiple apps from the same source with different name, themes, server and google's .json configuration file from one project with different source sets.
    thanks.

  • @Mindfulness978
    @Mindfulness978 Před rokem +3

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

    • @andrewdobosh2153
      @andrewdobosh2153 Před 8 měsíci

      You can make multiple features to depend on one domain or data module

  • @abhisheks2135
    @abhisheks2135 Před 5 měsíci

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

  • @nazmulhoque106
    @nazmulhoque106 Před rokem

    great video brother. please make a video on a simple API call with multi-module. please, please...

  • @QumberAbbas
    @QumberAbbas Před rokem +2

    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.

  • @andriisolomonov7302
    @andriisolomonov7302 Před rokem

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

  • @xavierrispal9605
    @xavierrispal9605 Před rokem +1

    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;

    • @PhilippLackner
      @PhilippLackner  Před rokem +5

      If a Retrofit instance is only needed for one feature it goes in that feature module, if not you can use a core module for all shared code :) Same for DI

    • @da_to
      @da_to Před rokem +1

      @@PhilippLackner But if you create a Retrofit instance in core module, then it will be accessible from everywhere because core module is a dependency in all other modules (e.g. :app module, :tracker:tracker_presentation, etc). This will brake the separation of concerns.

    • @PhilippLackner
      @PhilippLackner  Před rokem

      @@da_to why will that break separation of concerns? That just means that the layers are divided. At some point you'll have to accept trade offs

    • @dmytromarchuk3023
      @dmytromarchuk3023 Před rokem

      I did not understand the statement regarding layer-based packaging like "if something is changed in data layer - the whole module is rebuilt and that's not what we want". Really? Is there the other way around it? If we follow the Clean Architecture and dependency rule, presentation will depend on data and data will depend on domain (presentation -> data -> domain) so if some module uses only data layer of the other module, that module will not be rebuilt if presentation module is changed. That's the benefit.
      Example: 1) moduleA depends on moduleB:data. 2) moduleB:presentation is changed 3) when building moduleA moduleB:data won't be rebuilt;
      (please correct me if I am wrong and the building process works differently)

    • @misiu9049
      @misiu9049 Před 3 měsíci

      @@dmytromarchuk3023 think it is presentation -> bussines logic -> data

  • @flamfloz
    @flamfloz Před rokem +2

    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).

    • @PhilippLackner
      @PhilippLackner  Před rokem

      Sure, some dependencies are shared and put in a core module (in my sample here)

  • @evgeniivorobei69
    @evgeniivorobei69 Před rokem

    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

  • @mustafaammar551
    @mustafaammar551 Před rokem

    very cool video

  • @baadrqaaba9529
    @baadrqaaba9529 Před 10 měsíci

    Your approche makes sens to me a-lot .

  • @JujareVinayak
    @JujareVinayak Před rokem +1

    Hello

  • @romanpavliuk2301
    @romanpavliuk2301 Před rokem

    Yeah, modulatization helps to build projects faster. But if your project has 300+ modules, it won't work. Because the configuration will take more time. The Gradle team seems aware of this issue, but I don't know if they are working on it

    • @kurczaken
      @kurczaken Před rokem +1

      if the project has 300+ modules, then it's modularized in a wrong way

    • @romanpavliuk2301
      @romanpavliuk2301 Před rokem +2

      @@kurczaken tell this to the lyft 🙂

  • @yuriyvl1
    @yuriyvl1 Před rokem

    Would be interesting to know how this contrasts with Google-recommended approach to modularize by both, layer and feature.. (czcams.com/video/16SwTvzDO0A/video.html)

  • @skullkrum20
    @skullkrum20 Před rokem +1

    I agree that these are good generic advices but I don’t think it’s the best for all cases. At work we knowingly (as in, we knew the its drawbacks) chose a “pres domain data like” (not exactly) module structure because it achieved what we wanted without complicating the project with one module per feature which in our case had no benefits.
    So in the end, nothing is wrong.. in a given context, something can be correct which would be wrong in other contexts.
    Just wanted to add my thoughts 😁
    But it’s a good video as always 👌

    • @PhilippLackner
      @PhilippLackner  Před rokem

      And for what did you need a multi module architecture in that case? 😄

    • @PhilippLackner
      @PhilippLackner  Před rokem +1

      And for sure, you'll find a use case for everything that's justified, but there's still a more or less likely factor to it. In the end everything I share on my channel is a result of my experience and opinion 😄

    • @skullkrum20
      @skullkrum20 Před rokem +1

      @@PhilippLackner multiple reasons: enforcing separation of concerns between app layers, being able to move to a very possible KMM future easily, having different members of the team work in a lower level layer(one we have specific to our case - yes sometimes splitting work by layer is the preferred way).
      Having a multi module app allowed us this and the chosen layered module structure avoided the complexity of managing 50 modules each with inner modules that for us wouldn’t achieve anything of interest.

  • @SiamakAshrafi
    @SiamakAshrafi Před rokem

    WRONG! We always start all our projects with multi-module and we benefit from it everyday going forward. YES ... by feature is correct but have never seen anyone do it any other way.

  • @ezragolombek
    @ezragolombek Před rokem

    I'm sorry I don't have time to write a better comment but honestly very mediocre video. Allot of the information in the video is lacking and some things is just not fully correct.

  • @deviantstudio
    @deviantstudio Před rokem +3

    multimodule is overrated. if you can replace module with kotlin package - you don't need module.

  • @whatsinaname1305
    @whatsinaname1305 Před rokem

    Oh dear. This is garbage. 1) His advice is wrong. period. 2) He doesn't understand the need for separation of concerns. To quote one of the founders of UML , "It is to localize change" - think about it Philipp.

  • @user-jl9xg4um3r
    @user-jl9xg4um3r Před rokem

    Hi Philipp, thanks for the video. In my case I have in my personal application also modularized the project, but a friend when trying to clone the project one of the modules fails to compile, the module remains with the blue square icon, instead of the 3 colored bars, when trying to run the project returns this error:
    Could not resolve project :common.
    Required by:
    project :app
    project :app > project :football
    project :app > project :adobeclippers
    > No matching configuration of project :common was found. The consumer was configured to find an API of a component, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:environment' with value 'footballApp', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.4.0', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but:
    - None of the consumable configurations have attributes.
    If you could give me a hand in case something like this has ever happened to you? In the settings.gradle all the modules appear correctly.
    include ':app'
    include ':common'
    include ':styles'
    include ':repositories'
    include ':player'
    include ':football'
    include ':analytics'
    include ':adobeclippers'

  • @writerchris2j1984
    @writerchris2j1984 Před rokem

    Ich dachte build Tools mit generate *.iml würde meine build Zeit beschleunigen 😜