3 Clean Code Hacks I Bet You Didn't Know (Kotlin & Android)

Sdílet
Vložit
  • čas přidán 19. 05. 2024
  • In this video, you'll learn about 3 clean code hacks that make your code easier, more readable and understandable.
    💻 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
    00:00 - Hack 1
    01:40 - Hack 2
    04:22 - Hack 3

Komentáře • 88

  • @nymexe
    @nymexe Před 6 měsíci +57

    Typealiases are great, but I think using inline value classes would be a better approach

    • @Marcix456
      @Marcix456 Před 6 měsíci +2

      Could You elaborate on that?

    • @johanramaroson
      @johanramaroson Před 6 měsíci

      I agree

    • @GrahamFirst
      @GrahamFirst Před 6 měsíci +6

      I think one advantage there would be typechecking, which I don't believe you would get with a typealias.
      What I mean by this is that IIUC using a typealias, a parameter of type "PhotoAlias" would actually accept any String (or whatever the primitive type is). With an inline value class, it's actually a new type, rather than an alias.
      Inline value classes also offer constructors/initializers for additional semantics, validation etc.
      In most cases, this is achieved without any overhead, meaning as with a typealias, at runtime you really just have a String (in this example, or whatever primitive type).
      So tl;dr it's a more robust, powerful and flexible option, and there shouldn't be any performance penalty, so I don't really see any reason NOT to use an Inline Value Class over a typealias, unless I'm missing something (which is quite possible 😅).
      Happy to learn by being corrected if I'm wrong or missing something. Inline value classes are new and TBH I haven't actually used them yet, but I think they're a great feature and I'm looking forward to using them shortly in a personal project where they are quite applicable.
      kotlinlang.org/docs/inline-classes.html

    • @vibovitold
      @vibovitold Před 6 měsíci

      @@GrahamFirst typealiases, to me, should only be used locally (so i wouldn't rely on them for the scenario Philipp shows, i tend to agree with you in that sense).
      i find them great mostly for resolving occasional naming conflicts - eg. you are using kotlin.Result and some custom Result type alongside, and you don't want to always write the fully qualified kotlin.Result or com.myapplication.utils.Result to distinguish between them.
      creating an inline value class just for that purpose would be an overkill.
      so - to me - they're not interchangeable. it's apples and oranges. they serve different purposes and aren't meant as replacements for eachother.
      speaking of kotlin.Result, Result.success is actually an inline value class. so if you've got a failure, it's a specific class, but if you've got Result.success(true) (for example), it's actually just "true" coated with syntax sugar. there are some edge cases where it can lead to surprising results, eg. if you're using Mockito, you're not mocking some kotlin.Result property (so it stays null), but the compiler actually "thinks" it's a success, because it will treat it as Result.success(null).

  • @ernestguevara5968
    @ernestguevara5968 Před 6 měsíci +14

    The hack 2 was really helpful! I'm really relying most on Pairs, than creating another data class for it. Now it will be more readable

    • @GrahamFirst
      @GrahamFirst Před 6 měsíci

      Agreed! And keep in mind you could use even more specific names than key/value for even greater readability.

    • @vibovitold
      @vibovitold Před 6 měsíci

      destructuring declarations are nice, but relying on Pairs a lot is probably an anti-pattern in its own right.
      eg. if you have two values like (name, id), and if you implement it as a class, then you can always look for all the usages of "ThisClass.name" in the codebase.
      but if you're using a Pair, you cannot, because it will only find you the occurrences of Pair.first or Pair.second, and that might include lots of unrelated results from irrelevant contexts.
      or if you've got a Pair to represent name and id, and both are Strings, but then you realize you actually need to revert the order of name and id (id should be "first", name should be "second", because of some Map conversion), you've got no type safety when refactoring. you may forget about some place where it should be reversed, because both are of String type.
      so the code that will mistakenly use id as a name and vice versa is going to run and compile without any issues. this wouldn't happen if you had a normal class with expliitly named properties.

    • @arjun1194
      @arjun1194 Před 6 měsíci

      i dont like the 2nd hack. it can be achieved in a better way with a simple if else

  • @_zantetsuken_
    @_zantetsuken_ Před 6 měsíci +15

    Especially the third hack is really useful! Thanks M8!

    • @PhilippLackner
      @PhilippLackner  Před 6 měsíci +2

      Glad it helps!

    • @rogercolque
      @rogercolque Před 6 měsíci

      now im seeing the video
      in the fist hack
      thanks for not spoiler me

  • @TiagoDvl
    @TiagoDvl Před 6 měsíci

    Loved this one. Thanks again Philipp!

  • @armandoavila4615
    @armandoavila4615 Před 6 měsíci +5

    Didn't know about the partition function, pretty cool, thank you!

  • @dzjxn1988
    @dzjxn1988 Před 5 měsíci

    It really blown my mind. I thought I've known everything. Thank you! 🎉

  • @swaminathbera6407
    @swaminathbera6407 Před 2 měsíci

    You are amazing, loved the hack3

  • @calixtoandrade996
    @calixtoandrade996 Před 6 měsíci

    nice video
    the third is a great one
    thanks for sharing!

  • @mehrzweck_mandala
    @mehrzweck_mandala Před 5 měsíci

    Bitte, bitte - mehr davon. Diese Art von Content ist großartig! (Please, please - more of the same. This kind of content is great)!

  • @vladislavmelnikov5452
    @vladislavmelnikov5452 Před 6 měsíci

    Thank you! Would like to see more!

  • @safionweb
    @safionweb Před 6 měsíci

    Amazing background, Phillip.

  • @mohamadrezamehrjou9553
    @mohamadrezamehrjou9553 Před 5 měsíci

    Thank you Philipp 🤩

  • @andrewairman7658
    @andrewairman7658 Před 6 měsíci

    Wow, thanks a lot for these tips

  • @prasannadeshpande4435
    @prasannadeshpande4435 Před 6 měsíci

    Another great video. Thanks.

  • @davrukin
    @davrukin Před 3 měsíci

    In Hack 3, I would remove the "val" from context so you don't hold onto it and bring in a memory leak, since context is only used to create the SharedPreferences object. Also, I would maybe put the Context extension function in a companion object of the delegate, but that is probably stylistic.

  • @thkorkem
    @thkorkem Před 6 měsíci

    Delegate example is so useful 👌

  • @21Kikoshi
    @21Kikoshi Před 2 měsíci +1

    1. Typealias
    2. Destructing
    3. Delegates

  • @gilsonjuniorpro
    @gilsonjuniorpro Před 6 měsíci +1

    Lol, this hacks exploded my mind, excellent video, thank you!

  • @mateusbauer7299
    @mateusbauer7299 Před 6 měsíci

    Excellent. Greetings from Brazil.

  • @amzpakistani3186
    @amzpakistani3186 Před 6 měsíci +5

    Hey Philipp, excellent work. I've been learning a lot from your videos, the explanation and implementation is great. I am relatively a beginner and now I am gonna learn network, APis and stuff. I came across your tutorials about Retrofit and Rest API but they are 2 years old now. So are they still relevant?

    • @_zantetsuken_
      @_zantetsuken_ Před 6 měsíci +1

      Retrofit wont be further developed. I switched to ktor due to its Multiplatform feature

    • @amzpakistani3186
      @amzpakistani3186 Před 6 měsíci +1

      @@_zantetsuken_ Ohh alright, I was actually confused which one to learn, thanks for help.

    • @_zantetsuken_
      @_zantetsuken_ Před 6 měsíci

      @@amzpakistani3186 No problem! Both are fine but ktor is more powerful and i asked myself the same question like you.

    • @ChrisAthanas
      @ChrisAthanas Před 6 měsíci

      @@_zantetsuken_yes ktor for multi platform, and retrofit for classic android

  • @SyncImpl
    @SyncImpl Před 3 měsíci

    good tips, thanks

  • @wazzzupmissionz
    @wazzzupmissionz Před 6 měsíci

    Don't forget to mention: when you use "by" keyword, compose compiler will recognize state as written, thus function will recompose, even if it just pass state to inner compose function

  • @jimpauloovejera2599
    @jimpauloovejera2599 Před 6 měsíci

    great stuff!

  • @mkc0321
    @mkc0321 Před 5 měsíci

    awesome tips

  • @mitulsheth
    @mitulsheth Před 6 měsíci

    It's very helpful

  • @Sagar0-0
    @Sagar0-0 Před 6 měsíci

    Third one was helpful

  • @arielapp9469
    @arielapp9469 Před 6 měsíci

    are you spying on me or something?
    your videos always point to the exact problems I keep facing in my work.
    that's awesome.

  • @TenthMeli
    @TenthMeli Před 3 měsíci

    what theme are you using for android studio? looks super clean and that logcat cat is cuteeee

  • @UnrealTubeShorts
    @UnrealTubeShorts Před 6 měsíci

    Love from INDIA ❤

  • @omerokumus1
    @omerokumus1 Před 6 měsíci

    Typealiases are cool, however, the reader may think PhotoUrl is another class and get confused. Another approach using typealias that I'd prefer is explicitly making PhotoUrl is a typealias of string by PhotoUrl to PhotoUrlStr or better off, write a wrapper class that;
    data class PhotoUrl(value: String) // You can use another naming for value property tho
    Of course, those are my opinions

    • @vibovitold
      @vibovitold Před 6 měsíci

      Inline classes fall somewhere in between those two
      btw it should be val value: String actually ; ) (i know you're just illustrating the idea)

  • @517Amit
    @517Amit Před 6 měsíci

    All of them were good hacks. I liked the Getter and Setter idea.

  • @Otabek001uz
    @Otabek001uz Před 6 měsíci

    very good, it's very amazing!!!!!!!!!

  • @rrrdriguez_
    @rrrdriguez_ Před 6 měsíci +1

    Hey man! Great suggestions, but I got one question regarding the third hack.
    Following your example, if I used this property delegate for a shared preference inside a view model for example, how would we test this view model? How could we mock the property delegate so the test is unit and we can avoid using roboelectric or something similar?

    • @PhilippLackner
      @PhilippLackner  Před 6 měsíci +1

      Either way, you'd have a separate class which implements your preferences. That class is injected in your VM and can be replaced for testing there

    • @vibovitold
      @vibovitold Před 6 měsíci

      a ViewModel shouldn't deal with shared preferences directly AT ALL, because they are an Android concept, tied to the platform.
      they require access to Context.
      ideally a ViewModel should be unaware and independent of Android SDK.

  • @John-qt6qk
    @John-qt6qk Před 6 měsíci

    Thanks

  • @TheBlackManMythLegend
    @TheBlackManMythLegend Před 6 měsíci

    not bad not bad cool tricks. improved readibility

  • @riyupapa39
    @riyupapa39 Před 6 měsíci

    Wow!!! typealias is very useful!!!!!

  • @germenwong
    @germenwong Před 6 měsíci

    I liked it bro!!!

  • @verofero
    @verofero Před 4 měsíci

    amazing

  • @micortes89
    @micortes89 Před 3 měsíci

    How about if return type of first example is an uri?

  • @parashyadav9721
    @parashyadav9721 Před 6 měsíci

    Hello bro, I used to watch your video from very early. I did a lot of research but still i am not able to find a solution to my query.
    I found a strechable ui in some of the professional app. For example consider the new playconsole app , it includes q strchable ui which make user feel that this is end of the screen. I saw this behaviour as defult after android 12 but in android 9 or 8 it does not.
    But still the app shows that strechable ui in android 9. Can you help me how to get so .
    Is this happening because playconsole is made using flutter ???
    Hope you answer my question 😊

  • @nicholasferrara8028
    @nicholasferrara8028 Před 6 měsíci

    Can we get a video about uploading a photo to the back end and returning a url?

  • @David-zb8br
    @David-zb8br Před 6 měsíci

    hey philipp what happened to your newsletter? i suddenly stopped getting emails from you

  • @hammadnaseem8852
    @hammadnaseem8852 Před 6 měsíci

    Can we get data from firebase synchronizely in kotlin.can you make videos on it

  • @danielbojcobos4015
    @danielbojcobos4015 Před 4 měsíci

    Hello, this video is really instructive. Would you mind to do one video going deeper abaout the 'delegates'?
    Your channel is awesome, thank you!

  • @alex_aleluia
    @alex_aleluia Před 27 dny

    Muito bom !

  • @nischalshrestha2611
    @nischalshrestha2611 Před 6 měsíci

    Sir, Could you please tell me, how long it takes to build an app by learning from scratch using Kotlin and Jetpack compose
    ?.........Just tell me the time please!....

  • @buslovskiy
    @buslovskiy Před 6 měsíci

    Great hacks!

  • @tuvirusfury
    @tuvirusfury Před 6 měsíci

    Hello Philipp, i got something that i find weird with Unit Tests and Jacoco, using the Result API does not cover me the 100% for some reason (a path o branch to test, but unclear) anyone or you could have an idea why, and maybe explain this?

    • @vibovitold
      @vibovitold Před 6 měsíci

      Doctor, my tummy is aching for some reason, do you have any idea why?

  • @Nick-cx4rs
    @Nick-cx4rs Před 6 měsíci

    only use typealias for long java class names like : class ProjectContractChargingPeriodAccountReferenceVM :D :D

    • @vibovitold
      @vibovitold Před 6 měsíci

      or naming conflicts, like if you have to use two classes which happen to have the same name, but come from different packages, in the same file/class.
      typealias is a nicer alternative to using a fully qualified name (including a possibly lengthy package path).

  • @karomatullo_apk
    @karomatullo_apk Před 6 měsíci +1

    What about datastore ? Can we do like this with datastore?

    • @PhilippLackner
      @PhilippLackner  Před 6 měsíci +1

      I don't think the setter and getter can be a suspend function which would be needed for that. You could keep a runBlocking in that property delegate, but it's not ideal IMO since that would not make it clear that it's a blocking call and should be executed on a thread

  • @GrahamFirst
    @GrahamFirst Před 6 měsíci

    Why return a Result rather than just a String (in the first example)?

    • @vibovitold
      @vibovitold Před 6 měsíci

      Because Result allows you to return an error if the operation fails.

    • @GrahamFirst
      @GrahamFirst Před 6 měsíci

      @@vibovitold Why not just throw an exception?

    • @sgstudioofficial
      @sgstudioofficial Před 6 měsíci

      @@GrahamFirstbecause exceptions are for exceptional circumstances. Inability to upload a photo is not an exceptional occurrence. Failure is just an alternative success.

  • @icodethis
    @icodethis Před 6 měsíci

    goat

  • @robchr
    @robchr Před 6 měsíci

    Humble brag, I knew all of these hacks.

  • @andriiyakubenko148
    @andriiyakubenko148 Před 6 měsíci

    nice hack3

  • @asshinichi
    @asshinichi Před 6 měsíci +1

    code push in git

  • @saeedmoradi6858
    @saeedmoradi6858 Před 6 měsíci

    Philipp plz build music player with content resolver and clean arch. If anyone think that will be so cool then like my comment 😄😄😄

  • @scottbiggs8894
    @scottbiggs8894 Před 5 dny

    Hack #1 & #2 : Some programmers will do ANYTHING to avoid properly documenting their code. Sigh.
    Hack #3: Is this *really* easier than using the standard sharedPreferences? Perhaps it IS if you're doing lots and lots of sharedPrefs reading and writing. But wait--why are you doing lots of sharedPrefs reading and writing? That alone is quite inefficient--code that should be re-thought.
    This has all the code smell of someone showing off all their esoteric knowledge of hidden details of kotlin instead of someone who truly wants their code to be understood by the next batch of programmers to look at it (and as usual, they are almost always the people with the least experience and the least ability to follow such subtle code tricks).

  • @warTag68
    @warTag68 Před 6 měsíci

    Hack 1 is useless, better to use a separate data class

  • @DanielJohnGay
    @DanielJohnGay Před 2 měsíci

    Cool!