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

แชร์
ฝัง
  • เผยแพร่เมื่อ 29 ก.ย. 2024

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

  • @nymexe
    @nymexe 11 หลายเดือนก่อน +59

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

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

      Could You elaborate on that?

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

      I agree

    • @GrahamFirst
      @GrahamFirst 11 หลายเดือนก่อน +7

      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 11 หลายเดือนก่อน

      @@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).

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

      @@GrahamFirstgreat explanation!

  • @amzpakistani3186
    @amzpakistani3186 11 หลายเดือนก่อน +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?

    • @amzpakistani3186
      @amzpakistani3186 11 หลายเดือนก่อน +1

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

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

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

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

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

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

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

  • @scottbiggs8894
    @scottbiggs8894 4 หลายเดือนก่อน +1

    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).

  • @ernestguevara5968
    @ernestguevara5968 11 หลายเดือนก่อน +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 11 หลายเดือนก่อน

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

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

      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 10 หลายเดือนก่อน

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

  • @armandoavila4615
    @armandoavila4615 11 หลายเดือนก่อน +8

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

  • @21Kikoshi
    @21Kikoshi 6 หลายเดือนก่อน +1

    1. Typealias
    2. Destructing
    3. Delegates

  • @AkhmadjonAkbarov-hi6wn
    @AkhmadjonAkbarov-hi6wn 2 หลายเดือนก่อน

    thank you for useful video. I have reduced a bunch of code in my project by only change sharedpreference

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

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

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

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

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

    Humble brag, I knew all of these hacks.

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

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

  • @gilsonjuniorpro
    @gilsonjuniorpro 11 หลายเดือนก่อน +1

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

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

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

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

    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.

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

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

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

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

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

    good tips, thanks

  • @rrrdriguez_
    @rrrdriguez_ 11 หลายเดือนก่อน +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  11 หลายเดือนก่อน +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 11 หลายเดือนก่อน

      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.

  • @karomatullo_apk
    @karomatullo_apk 11 หลายเดือนก่อน +1

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

    • @PhilippLackner
      @PhilippLackner  11 หลายเดือนก่อน +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

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

    I liked it bro!!!

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

    awesome tips

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

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

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

    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 😊

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

    amazing

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

    Cool!

  • @John-qt6qk
    @John-qt6qk 11 หลายเดือนก่อน

    Thanks

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

    Muito bom !

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

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

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

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

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

    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

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

    Amazing background, Phillip.

  • @Nick-cx4rs
    @Nick-cx4rs 11 หลายเดือนก่อน

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

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

      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).

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

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

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

    Excellent. Greetings from Brazil.

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

    not bad not bad cool tricks. improved readibility

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

    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!....

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

      it takes 64 days.

  • @David-zb8br
    @David-zb8br 11 หลายเดือนก่อน

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

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

    You are amazing, loved the hack3

  • @517Amit
    @517Amit 11 หลายเดือนก่อน

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

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

    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 11 หลายเดือนก่อน

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

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

    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 11 หลายเดือนก่อน

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

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

    Another great video. Thanks.

  • @asshinichi
    @asshinichi 11 หลายเดือนก่อน +1

    code push in git

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

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

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

    Thank you! Would like to see more!

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

    Loved this one. Thanks again Philipp!

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

    Wow, thanks a lot for these tips

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

    Third one was helpful

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

    Thank you Philipp 🤩

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

    It's very helpful

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

    Delegate example is so useful 👌

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

    Great hacks!

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

    Love from INDIA ❤

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

    great stuff!

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

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

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

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

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

      @@vibovitold Why not just throw an exception?

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

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

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

    nice hack3

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

    goat