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.
@MikeJohnston3552 жыл бұрын
2:39 - "If you're not using Kotlin, I'm deeply sorry for you" Love it! 😅
@mohammadcs57082 жыл бұрын
Me too
@NikNewNik6 ай бұрын
😄👍
@MoritzPost2 жыл бұрын
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!
@brainy34292 жыл бұрын
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.
@oleksee2 жыл бұрын
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
@freedomchuks2 жыл бұрын
Do you have an open source project where you used it ?
@loboplateadostacker Жыл бұрын
This explanation makes it crystal clear.
@erfansn8692 жыл бұрын
We enjoyed a great explanation of the domain layer
@steel-r_ua2 жыл бұрын
VERY good explanation. Thank you, Don!
@AndroidDevelopers2 жыл бұрын
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
@alinababenko985 Жыл бұрын
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 Жыл бұрын
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 😁
@praveens68322 жыл бұрын
Much needed series.Thank you
@Lpapadop2 жыл бұрын
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?
@GakisStylianos2 жыл бұрын
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
@Lpapadop2 жыл бұрын
@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
@GakisStylianos2 жыл бұрын
@@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.
@star-warsien2 жыл бұрын
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.
@YairCarreno2 жыл бұрын
I love all these series of articles and guideline designs. Thanks a lot, Android Teams; excellent work.🚀🥳
@pvarela2 жыл бұрын
Deeply sorry for not using Kotlin, guys!! forget about Java, Kotlin is great!
@k4ba Жыл бұрын
Java is... Ew
@daniyar27182 жыл бұрын
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?
@georgeellickson47272 жыл бұрын
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.
@groh2 жыл бұрын
@@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.
@georgeellickson47272 жыл бұрын
@@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.
@XavierHerreraAudio2 жыл бұрын
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т2 жыл бұрын
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.
@zachyang10419 ай бұрын
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.
@smreha2 жыл бұрын
Was waiting for this vid :)
@RafaelPerez-ni5nj2 жыл бұрын
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.
@rasheedlewis110 ай бұрын
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?
@udaysharma5228 Жыл бұрын
Very well explained sir!
@arindomghosh31442 жыл бұрын
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 Жыл бұрын
You have a point! I need to know the same.
@mohammadcs57082 жыл бұрын
Awesome episode, brilliant idea to take business logic out of viewmodel
@mondoshigua Жыл бұрын
🇨🇴🙋🏻♂️👍🏼🤝🏼 Saludos desde Colombia.
@gima1231235 күн бұрын
Maybe I'm missing something, but why are UseCases defined as classes with 1 function? Why even have class ( seems like overhead and confusion)? Why not have function instead? Use cases in this video seem to defined exactly what a function does in functional programming and Kotlin does treat functions as first class citizens. Am I missing something?
@RonnyBubke Жыл бұрын
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.
@minhnguyen_8732 Жыл бұрын
This video is very useful to me
@lfernandofa2 жыл бұрын
Finally a great one Google!
@3bdoelnaggar2 жыл бұрын
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
@SHURA_RC Жыл бұрын
Great video
@phamhung22632 жыл бұрын
Could you guys give me a simple project which has been using Usecase with Flows in best practice
@Slai472 жыл бұрын
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.
@GakisStylianos2 жыл бұрын
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.
@Slai472 жыл бұрын
@@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.
@GakisStylianos2 жыл бұрын
@@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?
@Slai472 жыл бұрын
@@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.
@GakisStylianos2 жыл бұрын
@@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
@VirgilioSolano Жыл бұрын
thank you :)
@mijaelviricocheaparra7474 Жыл бұрын
It would be interesting to do videos like this with a Flutter implementation.
@newbiegameplayy2 жыл бұрын
Do you have some resources, like the implementatiom of this video?
@yogourta2 жыл бұрын
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?
@kolboch2 жыл бұрын
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 :)
@Elidangerfield11112 жыл бұрын
Question... The speake said to make the Use Case main safe but then made the invoke funciton suspended. ??
@HoussamElbadissiАй бұрын
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).
@myrmecii5782 жыл бұрын
I wonder if flow there can be replaced by livedata for the domain to UI communication
@HoussamElbadissiАй бұрын
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.
@bro_chenzox Жыл бұрын
What does it mean "Stops domain logic being bypassed"? Who stops? Data access restrictions or who? 🤷♂
@jessescott6892 жыл бұрын
Mr Scruff sighting!
@carsonbath634511 ай бұрын
so we're just supposed to create a ton of extra files with functions in them to represent user actions, idk man
@rizwansayyed7893 Жыл бұрын
Can anybody think of any example for domain layer?
@heshansandeepa94712 жыл бұрын
Very nice
@AndroidDevelopers2 жыл бұрын
Thanks, Heshan! We hope you have a great weekend 😎
@ТамараСтепанова-ч7т2 жыл бұрын
good video
@n.unuchek2 жыл бұрын
What about DDD at Android?
@BurgerParty2 жыл бұрын
Add screen resolution changer
@cularu12 жыл бұрын
thumbs up
@Shakenbeer2 жыл бұрын
"If you are not using kotlin - deeply sorry for you". Nice way to promote kotlin, man, really nice way. Deeply sorry for you.
@sulzleserranochannel24472 жыл бұрын
MAD skills, right😅
@adrianjoachim58192 жыл бұрын
Deeply sorry, indeed! 😭
@hamzaabbas23544 күн бұрын
All of this seems like an overkill.
@sunnyhong26512 жыл бұрын
Google tutorials are so bad that I can't understand
@saniksun2 жыл бұрын
At UseCases use return kotlin.Result, instead of throw Exception