Architecture: The Domain Layer - MAD Skills

Поділитися
Вставка
  • Опубліковано 30 вер 2024

КОМЕНТАРІ • 77

  • @MikeJohnston355
    @MikeJohnston355 2 роки тому +52

    2:39 - "If you're not using Kotlin, I'm deeply sorry for you"
    Love it! 😅

  • @pvarela
    @pvarela Рік тому +6

    Deeply sorry for not using Kotlin, guys!! forget about Java, Kotlin is great!

    • @k4ba
      @k4ba Рік тому

      Java is... Ew

  • @MoritzPost
    @MoritzPost 2 роки тому +20

    This series is really great and the description of the domain layer is spot on. Going down from ui -> domain (UseCase) -> data layer is really the right approach. Not enforcing it on the way up is also correct. These pass trough UseCases are not really necessary.
    Btw, the example of the date formatting UseCase is not really the strongest as it does not have any other injectable dependencies. A novice user might not see the point in this first example. The second one is better though. Keep up the good work!

  • @renascienza.bazarclub
    @renascienza.bazarclub 2 роки тому +19

    I love the approach of this chapter, because it draw attention to code that we aren't normally understand like business logic, but actually is.

  • @daniyar2718
    @daniyar2718 2 роки тому +7

    Still confused, shouldn't that arrow go from data layer to domain layer?
    Why domain layer have dependency on data layer? Isn't domain layer get access to data layer via repository interfaces?

    • @georgeellickson4727
      @georgeellickson4727 2 роки тому +1

      It's a dependency tree, so arrows point to what each depends on, so domain depends on the data layer, UI depends on domain, etc. Remember that the data layer doesn't care how it's used or who uses it, so it never knows about domain or UI. The domain layer needs to know about the data because it chooses how to apply that data. If the arrows were to refer to data flow, then it'd be reversed.

    • @groh
      @groh 2 роки тому +12

      @@georgeellickson4727 Don't agree. Data layer should know about domain layer because data layer repositories have to implement domain layer interfaces as Daniyar noticed above. Domain layer should know nothing about platform, hardware, data sources etc. It must be pure business logic. Therefore, data layer depends on the domain layer. Presentation layer depends on the domain layer too.

    • @georgeellickson4727
      @georgeellickson4727 2 роки тому +7

      @@groh He was not saying that a data layer implements a domain layer interface though. He created "UseCase" classes that use repositories, but said repositories do their own things and just give back data. When we say "depends on", we mean that if you say made a class call "Repository" (which is Google's definition of data layer), it's dependencies are other classes you injected into it, not that classes that use that Repository. You'd never inject a domain layer UseCase into a Repository. Data layer never depends on UI or domain use cases like he is mentioning. Maybe your version of what "domain layer" meaning is differing from Google's definition, as some architectures can define layers a bit differently.

    • @XavierHerreraAudio
      @XavierHerreraAudio 2 роки тому +2

      I can understand where the confusion comes from if you're thinking specifically of the Clean Architecture, where data layers have dependency on use cases, but the example in the video is not that.

    • @ОлегСкидан-ш1т
      @ОлегСкидан-ш1т Рік тому +1

      That's true. Google brings confuse for those developers who are working with Clean Architecture. Google's approach has the same layers with changed rules. If we are look at the Now In Android repo we can find more detailed things that do not follow Clean Arch.

  • @Lpapadop
    @Lpapadop 2 роки тому +7

    what about domain models? api/dto models? should we do transformations? who is responsible for the transformation from dto to domain? the repo or the interactor?

    • @GakisStylianos
      @GakisStylianos 2 роки тому +4

      6:46 there is shown an example where the usecase isn't the one doing this mapping. It comes ready from the repository.
      I guess in general you want to do that asap, so the repository would be a natural choice. If for example the repository has a dto and a database model that it's dealing with, it should be the place to map it to a domain model before handing it off to the other layers

    • @Lpapadop
      @Lpapadop 2 роки тому +1

      @Stylianos Gakis hey! thanks for the answer. Well it is that, or he didnt do any transformation on the repo. What i see is a creation of a domain model AuthorWithArticle. I see the value of doing it in the repo when it comes to api and database, but i am used to do it at least in the usecase cause the domain knows/has the logic of how a server/data base model should be exposed in a business perspective. So we could have a repo transofmation(api/percistance abstraction), Domain transformation(businesses transfornation), and later or a ui one. It would be nice to see an official opinion on this though

    • @GakisStylianos
      @GakisStylianos 2 роки тому +2

      @@Lpapadop Yeah some official opinions on this would be great. Maybe this could be worth making a question on the official Kotlin slack channel? A bunch of googlers hang out there and answer such questions.

  • @oleksee
    @oleksee 2 роки тому +5

    Awesome! I have been using this approach for quite some time and still loved the video. It's simple, it touches debatable topics (e.g. ui directly acessing data, usecase to usecase dependency) and it's just simply nice

    • @freedomchuks
      @freedomchuks 2 роки тому

      Do you have an open source project where you used it ?

  • @RonnyBubke
    @RonnyBubke Рік тому +1

    A UseCase in general is a Feature. This starts at the View/ViewModel and ends at an external Dependency (Db, Retrofit, etc). Suffixing a class 'UseCase' brings you nothing, just more complexity. formatDate("2023") vs formatDateUseCase("2023"). Thinking should much go more functional and in direction of features instead of noun the Architecture.

  • @jessescott689
    @jessescott689 2 роки тому +1

    Mr Scruff sighting!

  • @erfansn869
    @erfansn869 2 роки тому +3

    We enjoyed a great explanation of the domain layer

  • @steel-r_ua
    @steel-r_ua 2 роки тому +3

    VERY good explanation. Thank you, Don!

    • @AndroidDevelopers
      @AndroidDevelopers  Рік тому

      We can't help it. We'll go MAD if we can't share this magnificent resource with you😁 Check it out here 👍: goo.gle/MAD-Intro

  • @star-warsien
    @star-warsien 2 роки тому +2

    This was great! Currently I don't use a domain layout outside of what you would call "Utils" classes. I like this approach though. I will definitely use in future projects.

  • @Slai47
    @Slai47 2 роки тому +3

    Imo, UI shouldn't know the data layer exists. It makes testing easier, allows for consistent patterns and also allows for an abstraction layer for the data layer objects adding the ability to having API versioning support, API changes not effecting UI layer and more.

    • @GakisStylianos
      @GakisStylianos 2 роки тому +1

      The data layer may already be the one doing the mapping to a domain layer so that reason isn't necessarily true. Adding a layer that *only* defers to the data layer without any other reason why it exists in the cases where you only do it to conform to this rule sounds a bit redundant. What other reasons might one have for doing so that I'm missing? I'd love to hear them.

    • @Slai47
      @Slai47 2 роки тому

      @@GakisStylianos domain should have domain objects that the UI uses and can convert to data layer when sending items to the data layer and convert them back to domain objects when receiving it. You are right this isn't always needed but if you are building a project that might live through dozens of API changes and more, having data objects only represent the objects you are receiving and sending, then having domain objects be used by the app, allows for less domain and UI changes when handling versioning. If you are building a simple app, yeah use the data objects, it's not necessary to have basically duplicate classes in different layers. But for larger apps that could live for a decade, it's an insanely nice addition our team has been building out. It's a lot of work and right now, it's duplicate classes, but our APIs change drastically due to the job so building this protection now will save us loads of time later.

    • @GakisStylianos
      @GakisStylianos 2 роки тому

      @@Slai47 yeah I'm not arguing for using data models in the UI layer, I can definitely see the benefits of that. What I was thinking was that the repositories could also be the ones who map to the local model instead of having the middle-man domain layer doing this job. Wouldn't that also be reasonable, what do you think?

    • @Slai47
      @Slai47 2 роки тому

      @@GakisStylianos not wrong. We separated them as domain objects could have some business logic in turning variables into enums and such that the data doesn't need to know about. That was our choice but sorry for misunderstanding you.

    • @GakisStylianos
      @GakisStylianos 2 роки тому +2

      @@Slai47 awesome yeah thanks for sharing your opinion on this. We in particular are using apollo-kotlin and GraphQL on our app so we've definitely have had our fair share of model changes. But due to this, we don't quite have a data layer, the ssot is the query results, which may be cached locally due to how that lib works by itself. So we've reached this point where we may have use cases to do stuff but without a repository at all, just the usecases being injected with the apolloClient and so we do the entire business logic and mapping to a domain model (as we've learned our lesson of letting those models trickle down to the UI layer) inside the usecase itself.
      Being used to this approach makes it a bit harder to relate with all these discussions I guess, but still always interesting to talk about it

  • @phamhung2263
    @phamhung2263 2 роки тому +1

    Could you guys give me a simple project which has been using Usecase with Flows in best practice

  • @mondoshigua
    @mondoshigua Рік тому +1

    🇨🇴🙋🏻‍♂️👍🏼🤝🏼 Saludos desde Colombia.

  • @alinababenko985
    @alinababenko985 Рік тому +1

    I like your doc about Android Architecture. And videos about it. It's interesting, has some new details and explanations for me, I also found some my mistakes. Well-done. Thanks!

    • @AndroidDevelopers
      @AndroidDevelopers  Рік тому

      We're glad that the video was helpful, Alina. If you'd like to view even more MAD Skills videos, check out this amazing playlist: goo.gle/MAD-Playlist 😁

  • @rasheedlewis1
    @rasheedlewis1 8 місяців тому

    In the Data Layer docs, the paper mentions that Managers are another term for repositories that are dependent on other repositories. What is the difference between a Manager and a use case?
    I'm having trouble understanding what exactly is business logic. What would a GetLatestNewsUseCase do that a LatestNewsManager would not?

  • @zachyang1041
    @zachyang1041 8 місяців тому

    This video is great to explain the domain layer. It makes sense to me, but I don't see a big advantage of using use cases.
    I think the biggest concern I have for having use cases is that with large project and codebase and teams, there will be a lot of use cases, how do we track them is kind of challenging. it will end up with having the same use cases with different names under the different packages. I guess you can have the same arguments with using utils.
    But making viewmodels slimmer is pretty good.

  • @bro_chenzox
    @bro_chenzox Рік тому

    What does it mean "Stops domain logic being bypassed"? Who stops? Data access restrictions or who? 🤷‍♂

  • @carsonbath6345
    @carsonbath6345 10 місяців тому

    so we're just supposed to create a ton of extra files with functions in them to represent user actions, idk man

  • @praveens6832
    @praveens6832 2 роки тому +2

    Much needed series.Thank you

  • @arindomghosh3144
    @arindomghosh3144 2 роки тому +1

    One question: The use-cases only have functions and most of the times only one as shown in above example but no state, then shouldn’t creating a single instance of use-case suffice like we do for repo classes or is there a reason we need to create a new instance of a use-case every time we inject it?

    • @udaysharma5228
      @udaysharma5228 Рік тому

      You have a point! I need to know the same.

  • @3bdoelnaggar
    @3bdoelnaggar 2 роки тому

    Domain Layer
    Business logic
    Sets between data layer and presentation layer
    Set of rules and action that makes your app valuable
    What to do with events and data changes
    Only holds business logic
    Made up of class called (interactors or usecasess)
    UseCases depends on Data layer or other useCases
    UseCases is Reusable logic

  • @Shakesbeer1
    @Shakesbeer1 2 роки тому

    "If you are not using kotlin - deeply sorry for you". Nice way to promote kotlin, man, really nice way. Deeply sorry for you.

  • @brainy3429
    @brainy3429 2 роки тому

    If there are people like me who understand just a little or nothing, keep watching n you will get things better. I understood about 50% of what he explained in this vd and this is by far the best.

  • @VirgilioSolano
    @VirgilioSolano Рік тому +1

    thank you :)

  • @mohammadcs5708
    @mohammadcs5708 2 роки тому

    Awesome episode, brilliant idea to take business logic out of viewmodel

  • @mijaelviricocheaparra7474
    @mijaelviricocheaparra7474 Рік тому

    It would be interesting to do videos like this with a Flutter implementation.

  • @newbiegameplayy
    @newbiegameplayy 2 роки тому

    Do you have some resources, like the implementatiom of this video?

  • @YairCarreno
    @YairCarreno 2 роки тому

    I love all these series of articles and guideline designs. Thanks a lot, Android Teams; excellent work.🚀🥳

  • @rizwansayyed7893
    @rizwansayyed7893 Рік тому

    Can anybody think of any example for domain layer?

  • @sunnyhong2651
    @sunnyhong2651 2 роки тому

    Google tutorials are so bad that I can't understand

  • @loboplateadostacker
    @loboplateadostacker Рік тому

    This explanation makes it crystal clear.

  • @yogourta
    @yogourta 2 роки тому

    How about when you have to cache data but the first time you have to pull data from the backend do you give the responsability to the usecase?

    • @kolboch
      @kolboch 2 роки тому +1

      You can provide optional usecase as dependency to fetchData use case, like: fetchFromBackendUseCase(val storeDataUseCase: xyzUseCase?) or do the work in the use case itself with some logic. If getting data as live data from database might be the case for skipping domain layer and exposing it directly in ViewModel, or make a use case for that as well. Experiment, just giving some ideas :)

  • @Elidangerfield1111
    @Elidangerfield1111 2 роки тому

    Question... The speake said to make the Use Case main safe but then made the invoke funciton suspended. ??

    • @HoussamElbadissi
      @HoussamElbadissi 18 днів тому

      I know it's been 2 years, but a suspend function basically screams "run me concurrently/off the main thread!", so it makes sense. The ViewModel will then likely call this in a viewModelScope, which doesn't block the main thread.
      However, if a use-case's function is _not_ suspend, it'll block whatever thread it is called on (usually main thread), so you should keep the code very lightweight. Delegate any heavy work to the background (preferably by marking the function as a suspend fun and using withContext to make sure it's run in the proper dispatcher).

  • @BurgerParty
    @BurgerParty 2 роки тому

    Add screen resolution changer

  • @minhnguyen_8732
    @minhnguyen_8732 Рік тому

    This video is very useful to me

  • @smreha
    @smreha 2 роки тому

    Was waiting for this vid :)

  • @myrmecii578
    @myrmecii578 2 роки тому

    I wonder if flow there can be replaced by livedata for the domain to UI communication

    • @HoussamElbadissi
      @HoussamElbadissi 18 днів тому

      2 years late, but yes; You can use any observable container really, Flow/LiveData/etc are just implementation details.
      However, I don't see why would you use LiveData over Flows when using Kotlin. They're better integrated with Coroutines and the rest of the language, and provide a lot of benefits.

  • @n.unuchek
    @n.unuchek 2 роки тому

    What about DDD at Android?

  • @udaysharma5228
    @udaysharma5228 Рік тому

    Very well explained sir!

  • @lfernandofa
    @lfernandofa 2 роки тому

    Finally a great one Google!

  • @adrianjoachim5819
    @adrianjoachim5819 2 роки тому

    Deeply sorry, indeed! 😭

  • @sulzleserranochannel2447
    @sulzleserranochannel2447 2 роки тому

    MAD skills, right😅

  • @SHURA_RC
    @SHURA_RC Рік тому

    Great video

  • @ТамараСтепанова-ч7т

    good video

  • @cularu1
    @cularu1 2 роки тому

    thumbs up

  • @heshansandeepa9471
    @heshansandeepa9471 2 роки тому

    Very nice

    • @AndroidDevelopers
      @AndroidDevelopers  2 роки тому +1

      Thanks, Heshan! We hope you have a great weekend 😎

  • @RafaelPerez-ni5nj
    @RafaelPerez-ni5nj 2 роки тому

    I've been waiting for this series for a long time. I really like the simplicity of explanations and the way these approaches help us to write better code.

  • @SnoopyDoofie
    @SnoopyDoofie Рік тому

    In software engineering, it's called "Business Layer". Obviously, someone at Google decided to come up with the useless name "Domain Layer".

  • @saniksun
    @saniksun 2 роки тому

    At UseCases use return kotlin.Result, instead of throw Exception