If You're Making These 5 Use Case Mistakes, You Haven't Understood Clean Architecture

แชร์
ฝัง
  • เผยแพร่เมื่อ 1 มิ.ย. 2024
  • In this video, you will learn that if you are making these 5 use case mistakes, then you have not understood Clean Architecture!
    💻 Let me be your mentor and become an industry-ready Android developer in 10 weeks:
    pl-coding.com/drop-table-ment...
    ⭐ Courses with real-life practices
    ⭐ Save countless hours of time
    ⭐ 100% money back guarantee for 30 days
    ⭐ Become a professional Android developer now:
    pl-coding.com/premium-courses/
    Get my FREE PDF about 20 things you should never do in Jetpack Compose:
    pl-coding.com/jetpack-compose...
    Regular programming advice on my Instagram page: / _philipplackner_
    Join my Discord server:
    / discord
  • วิทยาศาสตร์และเทคโนโลยี

ความคิดเห็น • 74

  • @virajbenade5572
    @virajbenade5572 2 หลายเดือนก่อน +58

    Tomorrow I have interview on kotlin android and today I am spent 8 hours onyour channel ❤❤😂😂

  • @kacetal
    @kacetal 2 หลายเดือนก่อน +16

    For password verification, it is better to send a list of errors to show all the errors at once, rather than one after another.

  • @karolkulbaka8577
    @karolkulbaka8577 2 หลายเดือนก่อน +2

    Great overview of why do not use the google clean architecture

  • @BitMavrick
    @BitMavrick 2 หลายเดือนก่อน +5

    Not gonna lie. Properly structured android app is quite hard. As a beginner, I am going through a lot of complexity. Thanks, Philipp, for making videos about such a topic.

  • @idrios
    @idrios 2 หลายเดือนก่อน +2

    Man I appreciate your channel so much. It feels like Android development changes so much, so quickly but your tutorials are my go-to resource for keeping up with it, above even Google's own Android tutorials

  • @foivosstamopoulos9709
    @foivosstamopoulos9709 หลายเดือนก่อน

    Another great video. Thank you so much Philipp!!!

  • @calixtoandrade996
    @calixtoandrade996 2 หลายเดือนก่อน

    excellent video Mr. Lackner
    Im totally agree with your point!

  • @ojo_lali_ngaji
    @ojo_lali_ngaji 2 หลายเดือนก่อน +4

    recently i searching about usecase and you upload this video

  • @mohannadyoussef8683
    @mohannadyoussef8683 2 หลายเดือนก่อน

    Amazing video as always

  • @geko1098
    @geko1098 2 หลายเดือนก่อน

    This was my first introduction to use cases as code, and I think I got the concept from this video

  • @safionweb
    @safionweb 2 หลายเดือนก่อน

    Well explained.

  • @ilpacolo
    @ilpacolo 2 หลายเดือนก่อน

    Amazing video !! i am working as Android dev and this is very helpful

  • @niknar266
    @niknar266 2 หลายเดือนก่อน

    One thing we're doing at my current project to get a little bit more out of usecases is let them be responsible for wrapping in kotlin Result like the last example to make sure errors are caught in the onFailure and appropriate error event are sent to the presentation later from the viewmodel
    I have a live template to save me the trouble of writing boilerplate for usecases too :)

  • @Ayor88
    @Ayor88 2 หลายเดือนก่อน

    I guess you're a good teacher beacause I've watch many (if not all) of your previous videos and I made none of those 5 Use Case mistakes

  • @germenwong
    @germenwong 2 หลายเดือนก่อน

    Hi Philip, thank you for bringing us how to use biometric technology in Android in the last video. I have really learned a lot, and if possible, I would like to see you introduce how to use speech recognition technology in Android

  • @kolyakalyzhny
    @kolyakalyzhny 2 หลายเดือนก่อน

    Hi, Philipp! Have you ever considered an idea of creating a video on using static types more extensively for enforcing business rules? For example, instead of using a validator use case which returns a boolean, we might, indeed, parse some input into a more structured data: like string to a valid email. Of course, parsing implies errors which should be enumerated by your type system, too. Consider algebraic data types like `Either`, `Validated` etc which are used in Haskell, Scala, Arrow.kt. The approach prevents many bugs at the compile time. I think popularizing such concepts would be of great benefit to the community. Here are some good resources: arrow-kt docs, Scott Wlaschin's talks, blog posts and his book "Domain Modeling made Functional", basic Scala, Haskell design patterns.

  • @Alchemist10241
    @Alchemist10241 2 หลายเดือนก่อน

    Please make a quick video about how to architect our platform related classes like work manager and services in the clean architecture approach.

  • @chitye-aung
    @chitye-aung 2 หลายเดือนก่อน

    Awesome 🎉❤

  • @DiegoNovati1
    @DiegoNovati1 2 หลายเดือนก่อน +1

    To avoid the scenario number 3 I make the Domain module a Java library: there is no way to pass Android stuff or use Android libraries in the Domain layer, so it can just be only business logic.
    For the scenario number 4: all my use cases use loggers and analytics libraries (not directly but by repositories) so that for each use case I collect execution time and, in case of unexpected error, the parameters that created the error.
    For the scenario number 5: each use case returns an Either monad as result, the left value is the error (implemented as sealed interface) including the UnexpectedError when the data layer raised an unmanaged exception, and the right value is the successful result (NoResult or a Result class, it depends by the use case)

  • @bitwisedevs469
    @bitwisedevs469 2 หลายเดือนก่อน +2

    I think the formatting part can still be considered business logic as long as it is part of the business requirements? Usually such formatter can be function extension or inside utils. However I also put them in domain model since what I noticed usually is people not adding any logic in the domain model which makes it the so called anemic domain model as well as despite it is more like a UI logic I don’t want to do that formatting again for example in SwiftUI or UIKit with KMM. I think as long as that logic can also be done in platform independent approach then it is safe in the domain layer.

    • @PhilippLackner
      @PhilippLackner  2 หลายเดือนก่อน

      Is something really domain logic if the only place where it makes sense to use it is presentation?

    • @bitwisedevs469
      @bitwisedevs469 2 หลายเดือนก่อน

      @@PhilippLackner it is still part of business requirements thus I think it is still okay to be in domain layer but no need to create use case for that as it will be too overkill. What I want from a domain model is having both formatted version and raw/original value of properties and as of now I see no problem or violation when doing that.

  • @Mackovitch
    @Mackovitch 2 หลายเดือนก่อน

    For usecase #2, one would argue that the formatting of number of followers could be business logic as it pertains to the core of the business features of the app. Also, heavy formatting (almost unlike here) could make the presentation logic convulated (so what would be the best place: in the view model (via a mapper) ? in the UI component directly?) but I do agree that this is for the purpose of the UI and the resulting formatting would find its place in a UI model.

  • @MrMindfullness
    @MrMindfullness 14 วันที่ผ่านมา

    I am really excited to watch course material that I have enrolled for. But not sure where to find course I bought. Please help!

  • @martinseal1987
    @martinseal1987 2 หลายเดือนก่อน +4

    I think with your first example this is when you take clean code too far, there is no need for these to be in separate classes just making busy work

    • @PhilippLackner
      @PhilippLackner  2 หลายเดือนก่อน +4

      Not necessarily, but then don't call it use case if you ask me :)

    • @martinseal1987
      @martinseal1987 2 หลายเดือนก่อน +1

      @@PhilippLackner yh fair enough, I've never called anything a use case I don't like the concept

    • @lewi.steven
      @lewi.steven 2 หลายเดือนก่อน +6

      ValidateUserDataUseCase is not even use-case at the first place because use-case is system wide functionality of the application/software (just like when we define use-case in use-case diagram in UML). Do "ValidateUserData" is something that customer can do in the system ? "Login" and "Register" are. With that thought then Login and Register are the use-case class that can call Validator class to validate the request, or or you can have validation logic inside domain entity if you prefer rich domain model.

    • @martinseal1987
      @martinseal1987 2 หลายเดือนก่อน +1

      So it seems "use case" is just a way to make programmers argue about nothing 🤔

  • @lindaporsius
    @lindaporsius 2 หลายเดือนก่อน

    Guilty, on all of the mistakes. But since I actually entered a mentorship-program with Philipp, I can at least recognize them and try to improve.

  • @jaidynbelbin4863
    @jaidynbelbin4863 2 หลายเดือนก่อน

    All good points, but for the last one, how would you recommend handling error messages that come directly from an API response? Sometimes I want to display that exact error message in a dialog, or below a text field or something, as it gives a specific reason why a user action failed, so propagating the message from the Data layer all the way up to the presentation layer, intact. A possible solution could be coordinating with the backend developer to send an error code instead, but sometimes that isn't possible, ie. if the backend is shared with a web application that doesn't use that system. Thanks!

    • @PhilippLackner
      @PhilippLackner  2 หลายเดือนก่อน

      You can extend the error message wrapper with an optional String field for that, it just wouldn't support localization in that case (or at least make it less flexible)

  • @PedroBarbosaRoman
    @PedroBarbosaRoman 2 หลายเดือนก่อน

    I think there is also a space for using use cases containing platform specific libraries. I'm not a big fan of restricting use cases to only pure business logic, because sometimes a use case can do multiple things which depend on platform specific APIs, and so the use case should illustrate that intention through its name and parameters. If in a Multiplatform project we need a different use case from each platform we can then have an "expect" generic named use case (to use in common code) with "actual" implementation use cases that have their own dependencies on each platform.

  • @solokiller5883
    @solokiller5883 2 หลายเดือนก่อน

    I watched the previous video about the best way to handle errors, and I then touched on the topic of the use case and how to make the view model responsible for displaying the message type to the user. When I glanced at the thumbnail of the clip, I thought there was another bug. 😂

  • @weslleycampos
    @weslleycampos 2 หลายเดือนก่อน +1

    I prefer use the operator fun invoke in the use cases.

  • @george_sigalas
    @george_sigalas 2 หลายเดือนก่อน +1

    6:40 "The domain layer shouldn't contain any references to the data layer" that's where I get confused. Google says that the domain layer is responsible for encapsulating "business logic that is reused by multiple ViewModels" and in the docs it has examples where they use Repositories, which is clearly a data layer component. To me it feels like the domain layer exists solely for bridging the data layer with the rest of the app.

    • @calixtoandrade996
      @calixtoandrade996 2 หลายเดือนก่อน

      a repository is not from the data layer, is from the domain.
      The implementation of that repository is the data layer

    • @george_sigalas
      @george_sigalas 2 หลายเดือนก่อน

      @@calixtoandrade996 that clears up a lot actually. But why would the graph point to the data layer in the docs? That's so confusing.

    • @PhilippLackner
      @PhilippLackner  2 หลายเดือนก่อน +1

      The android docs are indeed confusing regarding that. They're not really talking of domain in the sense of DDD (Domain driven design)
      The idea of this inwards pointing communication is that changes in the data layer don't cause changes in domain and presentation as everything just depends on domain and never data directly

    • @calixtoandrade996
      @calixtoandrade996 2 หลายเดือนก่อน

      What is intended to illustrate is that the domain layer is decoupled from the data layer (since they are two separate layers) and that it is from the Data layer where it obtains the information, so that, if in the future it is decided to change Retrofit for Ktor or some SDK for another, the only one harmed is the Data layer and not the domain, because the domain uses its own entities, abstractions of its repositories and other use cases. Therefore, the Data layer is responsible for mapping/providing the domain entities to the domain, so everything keeps working the same.
      I think part of the confusion is not differentiating the Data layer from the Data modules/libraries. They are two completely different things, a layer and a library or module.
      The domain will NEVER implement a data module/library, much less a UI module/library, because those modules depend on the framework. However, the Data and UI MODULES always consume the DOMAIN MODULES (again, the MODULES, not necessarily the LAYER). Of course, how else is Data modules supposed to map the remote/local models to the entities? or how is the viewModel supposed to work with the useCases?
      So, the architecture is one way because UI calls on domain to get the information (the use cases, not the data sources and much less the repositories implementations), and domain calls on data to get it, but the responsible for implementing the Data modules/libraries is the feature or the app itself. That way, the domain receives the implementation of its abstractions.

  • @abada-s
    @abada-s 2 หลายเดือนก่อน

    12:28 sometimes creating this abstraction makes all user cases code style be the same but I think it is not the right way to unify the code style

  • @shadowpenguin3482
    @shadowpenguin3482 2 หลายเดือนก่อน

    2:20 the formatting implementation is also really strange. It would be much easier to have a single when expression here with some slight duplication, eg I found this one for file sizes (needs to be slightly adjusted from 1024 to 1000 though)
    fun fileSizeString(bytes: Double) =
    when {
    bytes >= 1 shl 30 -> "%.1f GiB".format(bytes / (1 shl 30))
    bytes >= 1 shl 20 -> "%.1f MiB".format(bytes / (1 shl 20))
    bytes >= 1 shl 10 -> "%.1f KiB".format(bytes / (1 shl 10))
    else -> "$bytes B"
    }

  • @thelegend8990
    @thelegend8990 2 หลายเดือนก่อน +1

    I trust you more than official Android docs.
    We wish to see more videos like you used to do where you apply all of architectural best practices in a mini project
    Thank you!

  • @jimpauloovejera2599
    @jimpauloovejera2599 2 หลายเดือนก่อน

    Question: Can we use try-catch inside a use case?

    • @SensesVI
      @SensesVI 2 หลายเดือนก่อน

      I'd think you always should. This way you can catch exceptions and ensure you throw a domain exception instead

    • @calixtoandrade996
      @calixtoandrade996 2 หลายเดือนก่อน

      I do not recommend it, because a single use case would be doing two things: executing its function and also handling the error.
      Let the error arrive to your viewModel. The error is a UI problem, not a domain problem.
      What I do is simply add the @Trowhs tag to my use cases so that whoever is going to use it knows in advance that this exception can be thrown.
      It is the problem of the viewModel or whoever is going to use it how to handle the exception.

    • @calixtoandrade996
      @calixtoandrade996 2 หลายเดือนก่อน

      if you want to throw a domain exception because your service returned something null when it really didn't have to be, then throw your domain exception from there. For example, in remote response the user may be null. Your domain requires that it cannot be null, therefore, if it arrives null from the service, throw your domain exception, for example: return remoteUser ?: throw User.NotFoundException. This way you avoid working with the null user in your datasources, respository and in your use cases, and again, let your viewModel be responsible for handling that error

  • @wcman007
    @wcman007 2 หลายเดือนก่อน

    Lmao this is like the teacher snitching on common mistakes in the test 😭😭😭

  • @mesutemrecelenk5447
    @mesutemrecelenk5447 2 หลายเดือนก่อน

    Thanks phlipp. Can you subscribe a video about unit test.

  • @L4szcZ
    @L4szcZ 2 หลายเดือนก่อน

    In example 5 there is easier solution you can change class name from useCase to validator ;)

    • @mackomako
      @mackomako 2 หลายเดือนก่อน

      If you leave it in domain layer it's still wrong. Either you move it to presentation layer or you return Error without string and map it in presentation layer.

    • @L4szcZ
      @L4szcZ 2 หลายเดือนก่อน

      @@mackomako it wasn't in domain as far as I remember and validator shouldnt be in domain btw.

  • @saeedmoradi6858
    @saeedmoradi6858 2 หลายเดือนก่อน +1

    Okay but what you use instead usecase???

    • @Mike-er2ih
      @Mike-er2ih 2 หลายเดือนก่อน +1

      Common sense.

  • @mikec4220
    @mikec4220 2 หลายเดือนก่อน

    15:13 "ViewModel should take this enum and map it to the corresponding string resources".
    I'm not sure this is a good idea, you make your view model dependable on android resources which makes it harder to unit test in isolation.

    • @karol-lisiewicz
      @karol-lisiewicz 2 หลายเดือนก่อน

      Actually, it doesn't affect the testability of a ViewModel. The generated R.string contains only a numeric constant for each resource that you can refer to in your project. This does NOT mean that you need to use Robolectric to test your ViewModels - you still can just unit test them.

    • @mikec4220
      @mikec4220 2 หลายเดือนก่อน

      ​@@karol-lisiewicz thanks a lot for your reply, I tried in the past but the solution I came up with was not the most compelling. On another hand this is what the best view model practices on the official android developer site tell us:
      As they can potentially live longer than the ViewModelStoreOwner, ViewModels shouldn't hold any references of lifecycle-related APIs such as the Context or Resources to prevent memory leaks.

  • @mohamadshqeer8864
    @mohamadshqeer8864 2 หลายเดือนก่อน

    Bro speak about devin

  • @fpetrovski
    @fpetrovski 2 หลายเดือนก่อน

    Easiest solution, just don't use "use cases".

  • @maximooze3196
    @maximooze3196 2 หลายเดือนก่อน +5

    I only smell religion in this topic here lol

    • @Elian-Fabian
      @Elian-Fabian 2 หลายเดือนก่อน +1

      If you do not provide an explanation on why you think so it's not possible to debate about it.

    • @maximooze3196
      @maximooze3196 2 หลายเดือนก่อน +1

      @@Elian-Fabian ok I wont. 🫠

  • @cbnewham5633
    @cbnewham5633 2 หลายเดือนก่อน

    well, a mistake in the first one is requiring a mix of upper, lower and a number and yet having a password min length of 9. There should be no restrictions other than a password length of 10 or 11 - preferably more (i.e.: a pass-phrase). Unmemorable passwords (must have an uppercase letter, a lowercase letter, a number, a special character, and only to be created when there is a full moon) with silly short lengths are far less secure than, say, a lowercase phrase of appropriately long length (which is easily remembered too). Anyway, I'll unpause and see what the mistake is that your are actually pointing out - but these kinds of stupid password requirements really get my goat and I wish developers would quit doing this.

    • @PhilippLackner
      @PhilippLackner  2 หลายเดือนก่อน +1

      But it's simply not secure to have only a length requirement. If the hashed password db gets leaked, it's super easy to Crack them by just trying every word in the dictionary