The Top 3 Clean Architecture Mistakes in Android

  Переглядів 19,612

Philipp Lackner

Philipp Lackner

День тому

In this video I'll show you the 3 most common mistakes I see people do in clean architecture.
⭐ Get certificates for your future job
⭐ Save countless hours of time
⭐ 100% money back guarantee for 30 days
⭐ Become a professional Android developer now:
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...

КОМЕНТАРІ: 99
@keepgoingman5829
@keepgoingman5829 Рік тому
These mistakes are definitely what developers who study CleanArchitecture at first could do. Thank you so much. this is very useful! Keep going bro!
@PhilippLackner
@PhilippLackner Рік тому
Glad it was helpful!
@youtubethoughts4273
@youtubethoughts4273 Рік тому
Make a Job scheduler video, How to create jobs and how to control the Jobs
@kyeiiih4422
@kyeiiih4422 Рік тому
Awesome knowledge Philipp ❤
@yansarorodriguezpaez8799
@yansarorodriguezpaez8799 Рік тому
Separating project into features is not a mistake, it's a decision, and has nothing to do with Clean Architecture. Actually, uncle Bob never spoke about that in the book, and this is applied to any architecture you use. I used to always take the feature oriented approach, but in the last project I've been working on, we decided to go with "layer-oriented" because of how coupled the data was. The thing with the feature oriented is that you are splitting your app in mini parts. Ideally, these parts must be independent, so if two features share some logic, where you should put that logic? This absolutely should not go to core/common folder, since this is not something to be shared with the entire app, it's only meant to be shared with these two features. You either go to "mirroring" the data on the other feature, or importing from one feature to another. The price to pay for either of these, in some projects, can be bigger than having these centralized.
@okunevdmitrii
@okunevdmitrii Рік тому
I very like separate project into features-modules, and i think that it is the best way for clear, convenient and easily expandable architecture of Android App) yeap, i have read your comment, and understand that we can use it in any project, not only Android, but i have experience only in Android and KMP) For your problem sharing of data between 2/3/4 (as u want) modules u can use next way: in my project i use 2 modules - api and impl inside feature-modules, all private logic i put in impl module (repositories and usecases implementations, screens, viewModels, uiModels and etc.. Also i put here DI and retrofit Api Interfaces, but it depends on situation and di libraries for example). In Api module i put only data for sharing. For example: UseCases and Repository Interfaces if i need to share it, maybe data layers mappers if need(more often not), maybe sharing constants, domain models for sharing usecases and screen parameters, which i need to get for screen start (for example id of user). In this case any your feature module has dependencies only for api modules of other feature-modules and knows nothing about feature-impl modules. And your Api module is really small and light. And in this way you can implement your feature-api module only in those modules what u need. Also this way help your improve building time, cause u have dependencies only for abstractions or rarely changeble classes as ScreenParams, and it means that u feature-module2 with dependency feature-module2-api will not rebuild after each changes in feature-module2-impl architecture scheme looks like: --feature-module ----api ------data ------domain ------presentation(here presentation layer needs me only for sharing of screen parameters if it's neccesary) ----impl ------data ------di ------domain ------presentation
@Drackmord92
@Drackmord92 Рік тому
@@okunevdmitrii Your approach surely works, but to me it looks hell of a complication! Having all modules having a separate part declaring all their shared classes as interfaces so that they can be injected by DI into sibling modules makes quite hard to figure out how the whole project is structured as it scales. I'm sure most projects can be organised fully in feature modules like Phillip described but in the ones I happened to work, backed provided those very large APIs that returned very interconnected data, and that kind of approach never worked. What I found is best in those situations is just to consider your "app" just the presentation layer, and divide it in feature modules accordingly, with just one module providing shared UI resources. Domain and Data can be while modules that behave like libraries for your UI, data providing repositories that internally manage data sources and domain exposing use cases and models. This also allows me to organise the three layers differently: for example, the division in features that makes sense on the UI level might not be very relevant to the domain layer that could instead group use cases by area of influence, and the data layer could group repositories and data sources around the actual Apis provided by the backend. Forcing a singular organisation vertically for the whole app rarely comes natural.
@yansarorodriguezpaez8799
@yansarorodriguezpaez8799 Рік тому
​@@Drackmord92 that last approach is just what we've been doing in our last project. But that doesn't mean that if you want to have domain/repositories/all-your-repositories it's a mistake. At the end of the day, it would be exactly the same code (same clean Architecture guidelines), with a very subjective way of organizing how your team edit and visualize it. You can think this as a flatten version of feature oriented, which can be easier to read depending on the team or the project. Don't take me wrong, I will always prefer the feature oriented version, but is not a mistake by any means doing it the other way. Also ​Philipp, keep going with your videos mate, you are doing awesome!
@rickbo5858
@rickbo5858 Рік тому
Tbh, if a 'feature' can operate independently from the other 'feature' u should probably put it in its own module/package. I've never made a native android app but worked with other frameworks (Flutter). Feature is something to figure out for later, because it forces you to think about what will work with what en where. You could say: plan better, but in my experience plans will always change in development because of unforeseen problems. The argument: "it's better because all the related files are grouped together" is non-sense, because with most IDE's you can just click on the import to jump to the source.
@TheMikkelet
@TheMikkelet Рік тому
I tried the feature-approach as well, and I "solved" your problem by having a 'shared' package with data, doman, and presentation. Problem was though, I ended up puttin so much into the shared-package, that it sort of negated the feature-approach lol
@pedrolemoz
@pedrolemoz Рік тому
Nice video! Just one thing to note: in the first mistake, I would rather use a custom Regular Expression to validate the email instead of relying on the given implementation. Why? I want to know exactly what's going on. Furthermore, since Regular Expressions are usually part of any programming language, it's safe to use it in the domain layer, as it won't be dependent of anything other than the language itself. About the last mistake, I don't consider it a mistake. It depends of the project size, and the chosen approach. If you are dealing with mono-repo, then it will be an issue. But if you are using multi-repo, micro-frontends, or something like that, you probably will make this mistake, but since everything is very separated, it's not a problem
@TheMikkelet
@TheMikkelet Рік тому
PROPER Regex is incredibly difficult to write and maintain lol (most codebases that do this just go with a contains([@.]]-approach. There's absolutely no shame in using a validator library
@MrSorenstar
@MrSorenstar Рік тому
Thank you so much. I learn something new from you every time
@denisoluka
@denisoluka Рік тому
Thank you Philip. This was helpful
@mircodev
@mircodev Рік тому
Many thanks for sharing your experiences from your code reviews. I appreciate it very much.
@chauchau0825
@chauchau0825 7 місяців тому
Not a android developer, but this guy's view on Clean Architecture™, unlike many other random UKposts videos, is correct
@go_better
@go_better Рік тому
Thank you, Philipp. I like your take on clean architecture. I just want to know best practices beforehand to not stumble upon scaling difficulties later on.
@amirhosseinghafoorian5256
@amirhosseinghafoorian5256 Рік тому
Amazing video, and as I noticed, nowinandroid is also a feature-based modular project and it kind of matches the example 3.
@denisgithuku8563
@denisgithuku8563 Рік тому
Finna waiting for this.
@Leon-un2ii
@Leon-un2ii Рік тому
Great video as always. I take security very serious so, I would be thankful, if you could do a lock screen app. Maybe with a pin/password/fingerprint? Would be awesome!
@FemiOkedey
@FemiOkedey Рік тому
I like concept explainer videos like these Thank you 😊
@ntikomathaba2662
@ntikomathaba2662 Рік тому
Hey Phillip. I just implemented a list-detail view in compose for large screens. Would love to see how you would implement it. There aren't many examples out there
@Akshaykumar-xr9yj
@Akshaykumar-xr9yj 8 місяців тому
Where do i put alarm manager in clean architecture. I have to perform some business logic in broadcast receiver (where should i put broadcast receiver in clean archotecture). can I access usecase in data layer.
@Ben-wx1ln
@Ben-wx1ln Рік тому
just amazing as usual
@rahul_spawar
@rahul_spawar Рік тому
More videos like this please❤
@schnitzel_crumbs
@schnitzel_crumbs 8 місяців тому
If you have only one database within your app, you would put the database in the core directory right?
@riyupapa39
@riyupapa39 8 місяців тому
I already did watch this video about 3~4 times. And I forget 3 mistakes again. I watch this video now again.
@baharudinmaulana78
@baharudinmaulana78 Рік тому
Yeayyy that good, i learn about clean architecture. But I do that mistake 😢, thank for the knowledge, i hope you always good, i open for feedback ☺️
@RudyStrom
@RudyStrom Рік тому
I also
@adamibraham
@adamibraham Рік тому
Please I need a tutorial about firebase firestore and clean architiecture and retrofit, caching with jetpack compose
@Zeeshan-Syed
@Zeeshan-Syed 9 місяців тому
I just had to use other feature's dependency. Seems like I need to put them in core then.
@johndominicjasmin
@johndominicjasmin Рік тому
Thanks Philipp
@harshpratapsingh1638
@harshpratapsingh1638 Рік тому
please make a basic video on how to use camerax in compose i am little bit confused
@dhruvreyansh1338
@dhruvreyansh1338 Рік тому
Any example of unit test in MVVM clean architecture with kotlin flow & channels
@alonshlider4881
@alonshlider4881 Рік тому
7:57 Can you please elaborate on that - what is the difference of testing the usecase layer than for example testing a repository or a viewmodel?
@vasiliychernov2123
@vasiliychernov2123 Рік тому
They exist for different purposes. Repository works with data and that's it. Use-cases contain valuable business logic. As an abstract example, it may get data from one repository, then pass its output to another repository and in the end aggregate it with another data. If use-cases just proxy repository calls, you should reconsider their necessity. View-model maps data from use-cases to UI-friendly structures and receives UI events. These all are different cases for testing. In repository you test correctness of data logic. In use-case you test correctness of business logic. And in view-model you test correctness of presentation logic.
@alonshlider4881
@alonshlider4881 Рік тому
​@@vasiliychernov2123 "In use-case you test correctness of business logic" - so by what you say I see that use-case testing is indeed necessary, which goes against what Philip said in the video
@vasiliychernov2123
@vasiliychernov2123 Рік тому
@@alonshlider4881 Uhm, Philip literally said that use-cases are being tested.
@dayakarpuli2307
@dayakarpuli2307 Рік тому
Hi Philipp, Please do full video related to SOLID principles with examples.
@Mogswamp-
@Mogswamp- Рік тому
🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝 *Thanks for watching you have been selected among the lucky winners, inbox* MOGSWAMP 🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝🔝
@genctasbasi
@genctasbasi Рік тому
Moral of the first 'mistake': "You don't eliminate the complexity, you just push it around" ☺ (I don't mean Philipp obviously, just the saying goes...)
@khapp7821
@khapp7821 Рік тому
Hi, would you like to make a tutorial about the state holder class and how can we take benefit from the class!
@Mogswamp-
@Mogswamp- Рік тому
🔝🔝🔝🔝🔝🔝🔝🔝 *Thanks for watching you have been selected among the lucky winners, inbox* MOGSWAMP 🔝🔝🔝🔝🔝🔝🔝🔝
@khapp7821
@khapp7821 Рік тому
@@Mogswamp- 🤣🤣
@khapp7821
@khapp7821 Рік тому
@@Mogswamp- @PhilipLackner just see this haha
@karthikgaddam4
@karthikgaddam4 Рік тому
Hey, just curious why you had to implement the validator in data layer. If I understand correctly, the data layer should only focus on things that deal with raw data. But in this case, validator just takes a string and returns a boolean, which doesn't really deal with data.
@PhilippLackner
@PhilippLackner Рік тому
Data layer deals with SDKs and APIs. The Android SDK is therefore partly data related
@karthikgaddam4
@karthikgaddam4 Рік тому
@@PhilippLackner alright, gotcha!
@VishnuHaridas
@VishnuHaridas Рік тому
In (1) the interface `EmailPatternValidator` is in the domain layer and the implementation is in the data layer. Doesn't that make the data layer depend on the domain layer which creates a circular dependency now? I would keep both the interface and implementation in the data layer itself, under `data/util`. Any other options?
@anegine
@anegine Рік тому
data layer depends on domain layer - it's ok. domain layer doesn't depend on any module (except any other domain layers)
@VishnuHaridas
@VishnuHaridas Рік тому
@@anegine The use-cases in the domain layer can access the repositories in the data layer and now both the domain and data layers are depending both ways right?
@anegine
@anegine Рік тому
@@VishnuHaridas Domain layer MUST NOT depend on data layer. Domain layer contains Repository interface. Data layer contains Repository implementation, which is injected to domain UseCase (with DI / ServiceLocator or any other way).
@VishnuHaridas
@VishnuHaridas Рік тому
@@anegine Oh deja-vu! I have seen similar conversations before when Google introduced the "layered" architecture where domain depends on data layer and not the other way around. I think it will be good to clearly specify that this is not the official "layered" architecture recommendation when making videos on Clean architecture on Android, otherwise new developers can get it mixed up.
@breakeract796
@breakeract796 Рік тому
For the second point. I guess you do not know/use MapStruct library. I'm always declare the mapper as an interface and the library gonna generate mapper implementation code for me. interface DtoMapper { fun toDomain(dto: DTO): DOMAIN } @Mapper interface BookMapper: DtoMapper Declare mapper as interface is really effective because the implementation of mapper can be change by business logic/rule anytime. When combination with Dagger we will @provide mapper, it can be injected to many class, I just need to re-provide the mapper implementation.
@samdroid37
@samdroid37 Рік тому
nice
@PhilippLackner
@PhilippLackner Рік тому
Why inject it if you can just make it an extension function to not need to inject it anywhere 😅 you don't gain anything with that interface
@katou9145
@katou9145 Рік тому
thx :3
@mymobile550
@mymobile550 Рік тому
Why do we even have to create a book mapper class ? Just open the body of the data class and write all the related functions in there. Or just simply make an extension function below that class.
@PhilippLackner
@PhilippLackner Рік тому
Extension function is better to keep responsibilities separately
@lglf77
@lglf77 6 місяців тому
Can anyone give a tip on how to do 10,000 mathematical calculations without freezing the Android activity screen? I have no idea what to use as a clean architecture if the numeric data comes from a static json.
@paulsoja2732
@paulsoja2732 Рік тому
About mistake #3 - if I have use case which I use in many features? Where I should hold this use case?
@kriisEU
@kriisEU Рік тому
in the core package
@thecoderui
@thecoderui Рік тому
I love you man
@mustafaammar551
@mustafaammar551 Рік тому
very cool video
@kamanchomorgan9655
@kamanchomorgan9655 Рік тому
According second mistake it is not a mistake. For example if you need to write fake mapper for unit test you need this abstraction. And you have 2 implementation.
@PhilippLackner
@PhilippLackner Рік тому
Why would you need a fake mapper?
@kamanchomorgan9655
@kamanchomorgan9655 Рік тому
to test something
@Shakesbeer1
@Shakesbeer1 Рік тому
Great video whatsoever. Claim about "if there is no second implementation - throw abstraction away" is to strong. You, probably won't have second implementation for that pattern validator. So next to multiple implementations one should always remember about testing and how abstraction make it easier. Second thing I don't agree is that data-domain-presentation does not scale. Just use feature packages inside those layer packages. I have seen both approaches and in wrong hands both could lead to a disaster.
@PhilippLackner
@PhilippLackner Рік тому
Regarding the second thing, that's similar to what I suggested in the video. I was referring to people who use presentation, domain and data packages and then don't use features in these. That's quite common
@Shakesbeer1
@Shakesbeer1 Рік тому
@@PhilippLackner To be absolutely honest your approach kinda better. For me having data-domain-presentation in this order from top to bottom in package manager is more menthal thing, carried from times before clean architecture and even Android development.
@boukarradhmoez99
@boukarradhmoez99 Рік тому
Ok that's a good approach but what about the cause when I need Dagger Hilt to inject my repos in my use cases ?
@wetfloo
@wetfloo Рік тому
if you're going to test your use cases, inject repos as interfaces and mock those interfaces in tests
@boukarradhmoez99
@boukarradhmoez99 Рік тому
@@wetfloo First thank you for your answer , Yes that's what im using (interfaces) but i was asking about to add Hilt dependency in the domain Module.
@boukarradhmoez99
@boukarradhmoez99 Рік тому
@PhilippLackner 🤔
@wetfloo
@wetfloo Рік тому
@@boukarradhmoez99 I didn't understand your question. Rephrase it, please?
@thousandcranes3045
@thousandcranes3045 Рік тому
@@boukarradhmoez99 Repositories are defined as an abstraction so you can have 2 different implementations - 1) the entity, which is the real implementation (which is most likely done in data layer) and 2) usually mocks for your test cases. On Philips' example, he didn't need to create 2 different implementations of a use case, because the the actual implementation of the use case, the business logic itself is what he wants to test. If you're wondering why don't we test the entity of repositories - it's simply because it has direct correlation with data (retrofit responses, rpc calls, room, cache, online configs, whatever) and you don't really care about that in your tests. Another reason is you obviously don't want to actually hit an API on your test cases
@masmmaw
@masmmaw Рік тому
Thank you
@Mogswamp-
@Mogswamp- Рік тому
🔝🔝🔝🔝🔝🔝🔝🔝 *Thanks for watching you have been selected among the lucky winners, inbox* MOGSWAMP 🔝🔝🔝🔝🔝🔝🔝🔝
@sheikhchilli7560
@sheikhchilli7560 Рік тому
You said don't abstract usecase. If we want to test the usecase we can use fake repository and test it. Now we will use viewmodel which have usecase as parameter now when we want to test the viewmodel how can I send the usecase Instance. If we make usecase as abstraction we can pass fake usecase. Correct me if I am wrong?
@PhilippLackner
@PhilippLackner Рік тому
Why would you want to pass fake business logic? What's the point? Use cases are always isolated logic, there's zero reasons to abstract that
@sheikhchilli7560
@sheikhchilli7560 Рік тому
​@Philipp Lackner If we didn't abstract usecase then all usecase will be tightly coupled in view model right doesn't it break the DIP principle. Also if we want to test the viewmodel which contains the actual implementation of usecase how you will test it. My suggestion would be to upload a separate video describing this will be helpful for us. Thank-you
@sheikhchilli7560
@sheikhchilli7560 Рік тому
​@@PhilippLacknerIn the context of use cases, it may be necessary to create a mock implementation of a use case in order to test the code that calls it. By creating an interface for the use case and passing in a mock implementation during testing, you can test the code that calls the use case in isolation, without having to worry about the implementation details of the use case itself.
@sheikhchilli7560
@sheikhchilli7560 Рік тому
Any update regarding my query?
@user-fc7dd1tn3b
@user-fc7dd1tn3b 6 місяців тому
Why ```interface Mapper { fun toDomain(data: Data): DOMAIN fun toData(domain: DOMAIN): DATA }``` is bad solution? If u need to cover 100% unit tests for example.
@rma1563
@rma1563 Рік тому
is clean architecture absolute necessary? I don't work as an android developer as a job, rather I only develop apps on my spare time. So should I be extra careful with these things? because for me some of these "clean architecture" looks like a lot of extra code for the simplest of things. Is there any performace boast with these methods?
@jarkow
@jarkow Рік тому
It's not necessary, but it's easier to maintain your app and add new features. You won't gain any performance boost though or might be an overkill if your app is very simple.
@rma1563
@rma1563 Рік тому
@@jarkow Thank you
@thousandcranes3045
@thousandcranes3045 Рік тому
It is not. I'm pretty sure even Google says domain layer is optional. If the only thing your use cases do is call 1 method from your repository, then you should throw them away. If you don't even plan to write unit tests, you probably don't even need to abstract your repositories. Clean Architecture is not really a concept from Android, it's used across all domains (iOS, Web, Backend, etc) and it only matters when you have scalability in mind. That said, IMO even on small apps, it's probably still not too good of an idea to put everything in your activities tho...
@PhilippLackner
@PhilippLackner Рік тому
It's definitely not necessary
@muhammadyaseen7022
@muhammadyaseen7022 Рік тому
👍
@oxitroy
@oxitroy Рік тому
6:10 "An abstraction only make sense if you actually have multiple implementation ... if you only have one implementation you can simply throw it away" I'm really surprised with this clear and direct statement as it goes against DIP principle and as uncle bob and others have said : "Somehow developers think that you should have an interface “only in the case of multiple implementations”. This couldn’t be more wrong. " Interface in clean architecture are aimed to control flow of dependency and they help us in isolating changes, and avoiding to propagate them everywhere. Their only purpose is not to have multiple implementations and even more when working with clean arch. Would love to hear your pov if i misunderstood your statement.
@PhilippLackner
@PhilippLackner Рік тому
In my experience, it very quickly leads to over engineering if you abstract everything while it comes with pretty much no benefit. You either want multiple implementations or really need to abstract stuff to use it in domain
@RRRazzzaRRR
@RRRazzzaRRR Рік тому
top
@ewomer100
@ewomer100 Рік тому
Isn't #3 the mistake you use in almost all of your long play video tutorials of Clean Architecture?
@koncinar
@koncinar Рік тому
Let's be honest, mistake #1 is only a mistake because Android is designed badly. Ideally you should be able to unit test the original code and shouldn't need to abstract it (like the whole mistake #2 states). In Java days, Pair was super useful class, very generic, but nope, no testability. 👎
@emrahc9558
@emrahc9558 Рік тому
Hey Phillip, I agree with you on the first two points but as for your package structure, I personally disagree. Because your package structure can be just as quickly confusing and above all, you should clearly separate the logic from the UI, even within the package. But in the end, it's a personal feeling how you want something to be better organized. I can send you our package structure as a picture on Instagram if you like. It is a mixture of your first and second variant.
Hilt - лёгкий старт в Dagger
32:26
Android Broadcast. Все об Андроид разработке
Переглядів 14 тис.
НЕОБЫЧНЫЙ ЛЕДЕНЕЦ
00:49
Sveta Sollar
Переглядів 6 млн
Эта Мама Испортила Гендер-Пати 😂
00:40
Глеб Рандалайнен
Переглядів 9 млн
skibidi toilet 73 (full episode)
09:41
DaFuq!?Boom!
Переглядів 22 млн
Common Mistakes and Advanced Typescript Techniques
10:49
Ljupche Vasilev
Переглядів 5 тис.
5 Android Dev Mistakes I've Done in the Past (PLEASE AVOID!)
12:45
Philipp Lackner
Переглядів 22 тис.
"Clean Architecture" and indirection. No thanks.
25:06
CodeOpinion
Переглядів 41 тис.
THIS Is the #1 Clean Code Mistake
14:47
Philipp Lackner
Переглядів 16 тис.
You might not need useEffect() ...
21:45
Academind
Переглядів 132 тис.
Which Software Architecture Should You Use: MVC, MVP, or MVVM?
24:27
ArjanCodes
Переглядів 104 тис.