If You Think THIS Is a Best Practice, You're WRONG in 99% of the Cases...

Поділитися
Вставка
  • Опубліковано 9 бер 2024
  • This video will show you new possibilities and why you have been wrong 99% of the time!
    Get my super extensive Android testing course here:
    pl-coding.com/testing
    💻 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
  • Наука та технологія

КОМЕНТАРІ • 86

  • @rudemption
    @rudemption 3 місяці тому +61

    You will not misuse use-cases, if you're not using them😂

  • @sevarbg83
    @sevarbg83 2 місяці тому +16

    The mistake is the assumption that every mapping operation can be performed as a simple 1-to-1 conversion. Very often it's not the case. Sometimes you need to merge data from 3 objects to create one or a pair of two. Layer to layer mapping is not bad. The bad thing is the 1-to-1 generic mapper interface. It's too inflexible. Just use concrete mappers not implementing mapper interfaces.

    • @lankyboy90
      @lankyboy90 2 місяці тому +1

      Using the Mapper interface can be very good for the 1:1 layer mapping classes, but I agree that in some cases it just isn't that simple. I've just had to implement a horrible mapper because I needed to merge data from 3 different objects in to one.

    • @bitwisedevs469
      @bitwisedevs469 2 місяці тому +1

      This is also the limit of using this approach, it is inflexible

    • @alexandrpershin
      @alexandrpershin 2 місяці тому +3

      If mapper accepts more than 1 parameter - that's not mapper, that's factory

    • @bitwisedevs469
      @bitwisedevs469 2 місяці тому

      @@alexandrpershin we are not talking about parameters here but use of generic type, mapper usually doesn’t need any parameter to begin with and if it does then that is probably a parser not mapper.

  • @RajSharma-lt3fw
    @RajSharma-lt3fw 3 місяці тому +8

    Thanks a lot for the explanation by showing an actual app and walking through step by step about the complexity. A lot of other content providers would just go through the Google documentation and explain the redundant topic. These videos helps to relate with the actual usecases developers face daily especially with large scale applications. Many a times new joiners would just get lost in the abstractions and navigating through so many classes. Please continue sharing such awesome content ❤

  • @RatneshNavlakhe
    @RatneshNavlakhe 3 місяці тому

    Similar question I had when I started working on a big android project I wasn’t able to understand, now it’s crystal clear thanks philipp for such an informative video keep doing the great work you inspire lots of engineers ❤

  • @arielapp9469
    @arielapp9469 2 місяці тому +2

    it is probably a good idea to have a usecase (especially in large projects)
    but it's important to understand why you want them.
    if you only use it to transfer data from repo to viewmodel, then it's not really useful,
    but if you're using it to create a buffer between the viewmodel and the repo, and save data to local repo, then it's useful.
    also, it's probably a better practice to use high order functions for the mapper, instead of an interface.

  • @BrayanBedritchuk
    @BrayanBedritchuk 3 місяці тому +5

    Great video Philipp!
    I agree with you that creating abstractions that will have no more than one implementation can be overwhelming when we try to navigate from one end to another.
    As a counterpoint, the main advantage that I see in my projects in implementing structures this way is the possibility of isolating contracts from concrete implementations in different modules, resulting in a reduction in the project build time when the other modules in my application reference only the modules with these contracts and not the robust modules that contain all the concrete implementations. There's a very interesting talk at Droidcon called Android at Scale @Square that exemplifies this approach.

    • @PhilippLackner
      @PhilippLackner  3 місяці тому +6

      Absolutely and if you stick to such a multi-module architecture, these abstractions have a value as you described :)
      I should've added here that isolating layers is also a purpose of them, yet abstractions within one layer are rarely useful (like for use cases or mappers). My feeling is more that people blindly abstract everything they find because it's a "best practice". This video was meant as a push to those people to not only start learning what should be done, but also why and when something should be done :)

    • @Drackmord92
      @Drackmord92 2 місяці тому +3

      I wanted to comment exactly this but you beat me to it :)
      My most common situation is to have the domain in a kotlin module and abstracting repositories so they can be implemented in the various data modules

  • @damirkrancpiler2246
    @damirkrancpiler2246 3 місяці тому +12

    Exactly what I've been arguing in all the architecture talks, nice!

  • @GakisStylianos
    @GakisStylianos 2 місяці тому +1

    We all need to go through the process of doing too little such abstractions, then we do too much, and then we go back to doing just as much as we actually need to. This video is great in describing this. I am sure people who disagree will be able to come back to this in 2 years and find themselves agreeing instead. Great work on this one Philipp.

  • @mohancena8970
    @mohancena8970 2 місяці тому

    Great video ❤

  • @rakshitsoni851
    @rakshitsoni851 2 місяці тому

    i agree about over usage of abstraction, i'd only have usecase for common API exposed to other modules in project with mapping logic

  • @vinaykumarpatel649
    @vinaykumarpatel649 3 місяці тому

    Great detailed explanation as always!. Instead of having test doubles can't we use mock libraries for testing purpose? Such as Mockito and Mockk?. Is there any advantage of using test double over these libraries?

    • @triton6771
      @triton6771 2 місяці тому

      We use test doubles when we want to control the working implementation of that class we're faking. Mocks are more for quick behavioural control where we dont really care much about implementations or large computations during tests

  • @nicoloagnoletti3275
    @nicoloagnoletti3275 2 місяці тому +2

    Hi Philipp, clear explanation as always, but I wish you would bring some examples here, as if you're using a complete Clean Architecture, every layer of any feature has strong directional dependency towards the center, towards the domain logic layer.
    I understand this could seem like an unnecessary complication, but without it no one would be stopped when trying to inject a retrofit interface to a viewmodel or even worse a view.
    I don't want to check your course to understand what you meant in the video, or if you're thinking of every scenario or most scenarios, we can all agree it shouldn't be necessary right?
    Other than that, keep the good job as always!

    • @PhilippLackner
      @PhilippLackner  2 місяці тому +1

      The isolation of domain enforces what you mentioned, but if your abstractions lie in the same layer as their implementations (e.g. for use case or mappers), it has nothing to do anymore with making use of the "dependency towards center" paradigm.
      For abstractions that lie in a different layer as their implementation (e.g. a repository), that point is valid which is why I also didn't talk about avoiding repository abstractions (at least when using a domain layer in the app)

  • @bhargav6995
    @bhargav6995 2 місяці тому +1

    make videos on the alarm manager in android 14.in android can not direct set exact alarm.if i set then the wake up after some second

  • @jackeblan
    @jackeblan 2 місяці тому +2

    Use the use case when your function needs more than one repositories and these needs to return a result. In the video, It just delegate the calls to the repository which doesn't make sense. Also, Do not put all the UI logic to the use case... Let the UI do that. For business logic, let the data layer do it too. So your use case is like a bridge to many repositories.

  • @user-se9xd6mx9f
    @user-se9xd6mx9f 3 місяці тому

    Thank you for the good video today too

  • @VivartPandey
    @VivartPandey Місяць тому

    You can also inject implementations directly which will solve the ctrl+ click navigation problem and use abstraction as architecture style enforcers.

    • @PhilippLackner
      @PhilippLackner  Місяць тому

      And you successfully violate one of the most fundamental architectural principles to depend on abstractions and not concretions 😅

    • @VivartPandey
      @VivartPandey Місяць тому

      Which one actually make sense , LoginViewModel depends on SuspendUseCase or LoginViewModel depends on LoginUseCase :-)

  • @SahilNagi
    @SahilNagi 2 місяці тому +4

    Hello Philipp, I am a senior manager of JetBrains and I was in the role of developing Kotlin language, so will kotlin kmm surpass Flutter in next 2 years ?

  • @vitorvigano
    @vitorvigano 2 місяці тому +1

    What is your AS theme? It looks great!

    • @josua_htp
      @josua_htp 2 місяці тому +1

      it looks like xcode default theme

  • @ilatough2314
    @ilatough2314 2 місяці тому +1

    What font does he use?

  • @dayona2513
    @dayona2513 2 місяці тому

    btw i'm using reflection, its that wrong?

  • @mariospiritof
    @mariospiritof Місяць тому

    Thank you! I think you missed an other abstraction benefit: it allows to keep the real implementation as an internal class. If you modularise an app, it could be very helpful:
    Let's say you have a UseCase that needs a mapper. This mapper is used only by UseCases. You want to keep this mapper internal in the "domain" gradle module. If you expose your real UseCase implementation to your UI module, and if the mapper is given to the UseCase constructor via DI, you will need to expose your mapper too. If you use an abstraction in front of your UseCase, you can expose the abstraction only, and keep the UseCase implementation and the mapper as internal.
    This way, you can avoid that the UI layer knows the data layer too.
    WDYT ?

  • @nnamdiwilliams1498
    @nnamdiwilliams1498 2 місяці тому

    This video makes sense. I would imagine on a project, everyone has their own philosophy on when to use Abstraction. I don' think there is a clear answer.

  • @brytonmassie
    @brytonmassie 2 місяці тому

    2:52 This is why I *used to* despise Java when trying to understand someone else's Minecraft mod or plugin, more often than not they'd have functions sending variables to a slew of other classes to an unnecessary degree, it was like three dimensional spaghetti-code, the function was abstracted across multiple classes and was more passing variables than logic making it a nightmare to debug because it could've been done with potentially a few extra lines of code but kept said code inside 1 class and therefore keeping things simple.

  • @sergeykharuk5614
    @sergeykharuk5614 2 місяці тому

    Probably you forgot to say that we should always have interfaces (abstractions) for repositories (if we write multimodule project) because for example AuthRepository (interface) is usually placed in DOMAIN layer and AuthRepositoryImpl is placed in DATA layer, which are in the sepatere modules.
    So, having only AuthRepositoryImpl we can not follow clean architecrute (correct if I am wrong)

    • @PhilippLackner
      @PhilippLackner  2 місяці тому +1

      If you have a domain layer yes, but this is not the only valid type of architecture

  • @bhuvneshvarma7843
    @bhuvneshvarma7843 2 місяці тому +1

    Nice video! In your experience, abstracting use cases might not be the most effective for testing. Since they often encapsulate business logic, testing with real implementations can be more valuable. This means using mocks or fakes for the repository layer when testing view models in the presentation layer?
    Here's why: Use cases typically depend on repositories. If we don't mock the use case itself, we'd need to mock the repository to avoid hitting the real server during tests.
    My question is: Considering this approach, would you prefer mocking the repository directly in the presentation layer tests?

  • @keepgoingman5829
    @keepgoingman5829 3 місяці тому +2

    totally agreed

  • @ahmed_guedmioui
    @ahmed_guedmioui 3 місяці тому +1

    The best video i watched this week 🤠

  • @handhikanichidaiprasetya67
    @handhikanichidaiprasetya67 3 місяці тому

    Nice video

  • @gekylafas
    @gekylafas 2 місяці тому +1

    I used to think like that. Then the reality of actual production enterprise applications used by hundreds of thousands of users that were using ever changing backend services but had backend code tightly coupled with UI code hit me hard. There is a good reason for these abstractions and personally I would use them even for toy/hobby projects.

    • @PhilippLackner
      @PhilippLackner  2 місяці тому +1

      How does abstracting a use case or mapper help with easily swapping out libraries?

    • @gekylafas
      @gekylafas 2 місяці тому +1

      @@PhilippLackner Suppose you have backend service A which you want to replace with backend service B (or A v2). A use case interface would have different implementations for each case, i.e. each implementation would use a different repository, and it would map the potentially different models of A and B to the same model consumed by the UI.

  • @user-pw1kh6ts4h
    @user-pw1kh6ts4h 2 місяці тому

    Good video explaining a great topic. But the presentation is very fast and difficult to understand without independent, in-depth analysis. It would be much better to show the structure of the example on the diagram. What should be done and how not to do it.

  • @marianpazdzioch5437
    @marianpazdzioch5437 2 місяці тому

    Philipp! I'd love to be a member of a team that you lead.
    Unfortunately life does not work that way. You end up with a team lead that was here for years and is a team leader "just because".

  • @Benverge
    @Benverge 2 місяці тому

    Its true that we should find the balance between absctraction and simplicity, But in your example, I tend to disagree, since we see a repository, useCase, well mappers im not sure but it does make sense after all. Even if the only thing you need right now in the use-case of login is the login-execution method to implement, since all the functions in the applications are working that way its not that complex for the developer.
    If you are working with a massive application, with dozens of use cases, it making the developer to know exactly what to expect to find when he is looking for the implementation of some function in the UI layer..

  • @WilliRittmann-iq5bu
    @WilliRittmann-iq5bu 2 місяці тому

    Abstraction, thats usually is the problem 😅 just use a concrete map and be happy

  • @sakthikumar_official
    @sakthikumar_official 2 місяці тому

    ❤I am sakthi from India Tamilnadu,
    I am biggest fan of you Bro, 😊I decided to learn native Android development jetpack Campos🌵 and teach my tamil people using UA-cam channel like you bro,🥴 but I not have much more money to spend for any courses including your courses now I am learning using free online 💸resources including your UA-cam video's I completed your kotlin playlist it is very useful for me, 🤔now I have a one big doubt, is flutter killing native Android development?🎦 Please make video for this doubt bro more new learning students have this doubt bro.

  • @user-oc7py1vy6s
    @user-oc7py1vy6s 2 місяці тому

    Братан, хорош, давай, давай, вперёд! Контент в кайф, можно ещё? Вообще красавчик! Можно вот этого вот почаще?

  • @pelealexandru
    @pelealexandru 3 місяці тому +3

    Also having an interface for the purpose of using fakes in tests is also not needed since you can just use a mocking library to replace the real implementation with a mock. I feel like people use abstraction just for the sake of it but it's almost never needed.

    • @PhilippLackner
      @PhilippLackner  3 місяці тому +1

      Uhh, I've rarely seen people use mocks correctly. Fakes have always been way more reliable in my experience, unless you need to test legacy code or code you don't own

    • @pelealexandru
      @pelealexandru 3 місяці тому +5

      You can get the same fake implementation with a mock where you do "when this do that", right?. Unless this is what you mean by not using mocks correctly. A good idea for a next video maybe? @@PhilippLackner

    • @gekylafas
      @gekylafas 2 місяці тому

      And how can you verify a call was made to a fake, with specific parameters and specific times? You can't. Only mocks can do that.

    • @triton6771
      @triton6771 2 місяці тому

      ​​@@gekylafasum you can verify if a call was made to a fake

    • @thanosfisherman
      @thanosfisherman 2 місяці тому

      How do you mock a final (by default) concrete kotlin class if not by an interface?

  • @rsdosev
    @rsdosev 3 місяці тому

    Finally someone to share my point of view. Unfortunately this realisation comes after 10+ years of experience, and for some it doesn't come at all. Sorry for you btw, because you will most likely receive a lot of hate for this video from the inexperienced developers who have read single clean architecture article snd think themselves of the next Jake Wharton.

  • @jimpauloovejera2599
    @jimpauloovejera2599 3 місяці тому

    this is my pet peeve

  • @user-sn3ie3te6w
    @user-sn3ie3te6w 2 місяці тому

    Base

  • @bitwisedevs469
    @bitwisedevs469 3 місяці тому

    The purpose of using interface when implementing mapper is for me to have a blueprint that I can follow which also act like a standard pattern for others so that the order of functions, its name and returned data type will always look the same in every implementation. The only problem I see here is the use of interface for use case since usually it doesn't even do anything other than calling the repository. I also do not like having mapper to Entity or from DTO inside my domain classes as I want it to be plain Kotlin as always. Android devs love complexity to the bone for real, but yeah too much abstraction can hurt everyone I think 1-2 level of abstraction is enough and above that makes everything complicated.

    • @PhilippLackner
      @PhilippLackner  3 місяці тому

      But for every blueprint you have, there's no value if people don't use it. And in order to use it, you need to communicate it to the team. And if you have to communicate something in either way, you can also just communicate that you're using simple extension functions for mapping. I get your point, however I still think the gained value of that blueprint is higher than the lost value due to the extra complexity.
      Same argument would go for a use case, these also have a blueprint - they take a set of input params and generate an output. So why not there? You mentioned it doesn't do anything other than calling the repository, but doesn't the same count for mappers? All they do is map something to and from and object

    • @bitwisedevs469
      @bitwisedevs469 3 місяці тому

      @@PhilippLackner Good point. I still think for a project that handles very huge response data and many properties, using the above approach of implementing mapper is more readable and cleaner as there is a better separation of concern but that is not the case for use case where the usual recommended number of parameters is 7. Above that you will get lint warning if you use one. What I mean is compare to mapper that can be really huge and bit complex, use cases on the other hand are usually simple since most of business logic can be put in the domain itself. Communication is a must and setting standard pattern in a project I think will lead to a better quality and consistent code style so that should be the least problem I would bother. As for mapper being the constructor's parameter, I use the concrete implementation there to improve readability and lessen the complexity effect of abstraction even if it means of violating the D in SOLID principle. I will consider doing the mapping in the models too in the future since there are now plain Kotlin solution for caching and networking which makes it feel more comfortable to put it in domain for mapping.

    • @PhilippLackner
      @PhilippLackner  2 місяці тому

      @@bitwisedevs469 mapping in domain doesn't work as the mapper has a dependency on data

    • @bitwisedevs469
      @bitwisedevs469 2 місяці тому

      @@PhilippLackner thanks so it should be entity that holds the mapper function is that what you mean?

  • @Mike-er2ih
    @Mike-er2ih 3 місяці тому +5

    Phillip I love your channel but I thought it is supposed to be an educational channel.
    Meaning I want to know what the video is about from the title instead of some clickbait that leaves me clueless...

    • @PhilippLackner
      @PhilippLackner  3 місяці тому +2

      Thanks for the feedback :)
      If you find these videos not educational, it's of course fully up to you to not click on them. Furthermore, clickbait means that the title and thumbnail suggests something you won't find in the video. That's not the case here, as watching the video proves the title and thumbnail.
      If you want pure "educational videos" (as per your definition), check my premium courses. They're independent of an algorithm :)

    • @Mike-er2ih
      @Mike-er2ih 3 місяці тому +4

      @@PhilippLacknerI still believe this is clickbait - just a different type :) All I am saying is that if in 2-3 months time I'll want to revise this again I will be forced to search for the video manually because typing "lackner mappers" will not yield any result most likely.

    • @PhilippLackner
      @PhilippLackner  3 місяці тому

      For SEO, it actually doesn't matter too much, UA-cam indexes every word that was said in the video :)

  • @gorudonu
    @gorudonu 2 місяці тому +3

    what?! you're saying that clean architecture with use cases are boilerplate and not useful in 99% of projects? You're right ;)

  • @ragingFlameCreations
    @ragingFlameCreations 2 місяці тому +2

    I laughed my ass hard on this video 😅😅
    I hope I'll not encounter something like this

  • @ragingFlameCreations
    @ragingFlameCreations 2 місяці тому

    Something definitely triggered Philip to make this video 😂

  • @kamanchomorgan9655
    @kamanchomorgan9655 3 місяці тому +2

    You a wrong, abstract things look weird when it is small app, but in big projects abstractions help to reuse code a lot and don't rewrite same code million times. Another case, when you have abstraction over library for example and you use that in 100 files, then when you want to migrate to other library in that field you don't need to touch 100 files, just write 1 file with new implementation. In general in big progrects big amount of abstractions helps a lot, but you need know how to work with that properly.

  • @j2shoes288
    @j2shoes288 2 місяці тому +3

    iOS apps aren't over-engineered like Android apps. I don't know why that is? Whether it;s a bravado thing.

    • @jonnataslennonlc
      @jonnataslennonlc 2 місяці тому +1

      It is because a lot of bad projects, that we had a few years ago..

  • @ragingFlameCreations
    @ragingFlameCreations 2 місяці тому

    I laughed my ass hard on this video 😅😅
    I hope I'll not encounter something like this

  • @ragingFlameCreations
    @ragingFlameCreations 2 місяці тому

    I laughed my ass hard on this video 😅😅
    I hope I'll not encounter something like this