How to Make Your Code Clean With Kotlin Sealed Classes

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome back to a new video in this video i'm going to teach you how you can make your code cleaner with sealed classes in android i will tell you what a c class is how it compares to enum classes and then specifically two ways how you can use these to make your code really clean and readable let's start with what is actually a cl class a c class is a kind of a language construct of kotlin that i haven't seen in any other languages and it's basically it's basically enum classes on steroids so that's what i call it some people may argue no it's not really on steroids it's just a different type of enum with other strengths and some weaknesses but i just like classes much more and i call c classes enums on steroids so if you don't know any of these two these are basically both classes that represent a set of arbitrary values so we can use these to define our own values our own set of values for example like here we have our own car class and this car class has different types of options we can assign to such a car so we have bmw audi and mercedes and whenever we have a place in our code where we need to distinguish between different cars we can just use such an enum class or such a steel class to assign an instance of of that class any of these three values now you can already see these these two classes kind of look similar but they also look a little bit different so enum classes basically just define a set of of fixed values so the way this works behind the scenes is that each of these values just gets assigned a number so bmw would be 0 or it would be 1 and mercedes would be 2. but for the sake of readability we just see these as these names here in our code however with shield classes that's not the case in classes we actually we actually have classes in that class or object which are singletons in kotlin and those define our different options here and they actually inherit from the parent shield class and that is the main difference or the main characteristic of c classes that only the classes or the objects that we define in that c class are allowed to inherit from that c class or classes that are defined in the same file so if i would have another class here um for yeah let's make it another object for example lamborghini and that would be inheriting from c class that would also work because it's in the same font but if i would put this lamborghini class inside of another file it couldn't inherit from c class because that's how a c class works so let's start with a little comparison between these two ways of defining a set of values because of course they are very similar let's start with the single advantage i see in enum classes compared to c classes and that is that they are they are numerized out of the box and that makes them easily serializable and deserializable so what that means is as i said behind the scenes each of these values is assigned to a number so zero one and two and if we now want to send such a car via the network for example to a remote server or we get such a car from a remote server then it's of course much easier because we can send numbers over the network but we can't send um such such arbitrary values here over the network so there are only a set of basic data types like integers floats strings and stuff like that that we can put into a json file but we can't put such a class here such an object into a json file unless we serialize it correspondingly so as long as we have the same inum class client and server side we can easily just um pass the value of the current entry to to our request and on the server side we can easily just deserialize that so server side we also have these values that are much more readable than just some kind of number however let's now get to the advantages of a steel class and why i always use sealed classes and number one is that c-classes can actually have generic type parameters so if we want to use a generic type parameter for enum classes you see that doesn't work in the class cannot have type parameters for c classes that does work of course we need to pass one for this these single single classes and objects in here as well but that does work i will show you in this video how this can be helpful this would be too overwhelming right now so just keep watching and you will find out about that that is one advantage but the even bigger advantage i see in c classes is that sealed classes can hold instance specific data so what the heck does that mean let's imagine we kind of want to extend this class and we want to assign or we want to be able to to also pass a model to these car classes here so of course if you if you look on the street you won't just find a mercedes you will find a specific model of a mercedes and if we if we want to have if we want to be able to to pass that model to make each mercedes individual to distinguish between different mercedes we need to pass a model so what we can do is we can have a constructor here a val model which is let's say a string here and well now we of course need to pass that in these constructors as well but if we do it like this let's say for the bmw we pass i don't know let's say an m5 then this would now hard code every bmw to be an m5 and that's of course not what we want we want to be able to have different bmws with different models and by the way this is also possible with enum classes so if we have the model in here in the constructor we can also just pass that here like for the bmw for example and this would again just hard code the model for each bmw to m5 however what we can now do with sealed classes is we don't have to make these singletons we can also make these data classes and then we can assign an individual constructor for each data class so we can again just pass the model here let's make that a normal class and then instead of passing or rather hard coding the model here we pass the model we passed individually for that bmw so now what we accomplished is that each bmw can have its own model so it's not like that we just have these fixed values we have bmw audio mercedes no we can now have different types of bmws and that is what i mean with instant specific data so these don't need to be singletons instead we can also just use normal classes that have a normal body here as you can see you can put functions in these and that just allows a little bit more flexibility than with enum classes i mean here we can also have bodies and functions in here but it doesn't really behave like a normal class so that is why i always use sealed classes they are just much cleaner in my opinion so far for the more theoretical part about the differences here let's think about how we can make use of these classes to actually make our code cleaner and take a look at some practical examples so i will delete this car class again here and you can see i have a main activity and just a very very small example project here which basically just displays a list of persons which i also hardcoded here but that could theoretically be a response from an api and then you can see this list is displayed here so uistate.items is that list of persons and each person has a name that is displayed here then we also have a loading status and we have an error status so let's start with the first scenario in which i use c classes and that is actually to expose state in a view model so you're already seeing that i have ui state here that contains the whole state for our whole screen but let's first of all take a look in our repository to understand where this actually comes from so here we have a repository and that has a function to get data as i said this just simulates getting data it delays the curitin so it simulates that delay and then in one of two cases it just throws an exception here so we can also see how the error would be or how the error would look like and if that random number was not zero then it will just respond with a list of success it responds with a list of some persons here that are then handled in the in the view model and if an exception happens it will respond with an error resource so now you might wonder what is that resource class here and that is a cl class ladies and gentlemen so let's take a look here that might now look very complicated if you know my project-based playlists or tutorials then you know this class but you can see it's a c-class resource and that has a generic type parameter t because what this now allows us is to define a success and an error case because we need some way to forward the the success or the error state of our repository because we want to be able to catch exceptions in our repository here and if no exception happened we want to be able to pass the data to our viewmodel but our viewmodel needs to know okay was there an issue in the repository was there an exception maybe no internet or so or was it successful and if it if it was successful give me the data that is what the view model really needs to know and that is all this resource class does so we define two options that both inherit from this resource class because it's a c class that works if we define the classes in here the success case contains the data so if we have a successful case we of course want to attach the data the list of persons in our case here and if there is an error then we want to attach an error message so the viewmodel knows what actually went wrong and optionally if we really want we could also attach some kind of data but we usually don't have data in error case so that is one way of using c classes just to of course distinguish between different types that is what you already learned when i am talking about the differences here but what i rather want to show you is i said exposing state in the view model so let's take a look at our main view model here we just access our repository um we have our ui state and how that does this ui still look like well it looks like this it's a data class that contains if we're loading if there's an error and our actual data or our list of items and then it contains a shield class error so now we actually have an error class that that we can use to forward the specific error that that happened to the actual activity to the actual composable so to our ui layer so if there was a network error we can simply emit this this specific error if there was if the input was too short this error input was empty this error and we can just extend this as we like the reason why we don't just attach an error message here because that of course is something we could also do is just attaching a string that we display in our ui but we often want to use string resources for error messages and if we want to use string resources then we have to emit these errors because we can't get these in our view model unless we have the context in our viewmodel which we want to avoid so that is why we rather emit such error singletons in this case that describe the exact error that happened and then uh which is not that one let's do it like this and then in our activity as you can see down here we can simply have one expression that handles this specific errors so that's very readable now we just see okay when the ui state error is network error we display this text with this string resource if it's input empty just a different string resource and so on so we can very cleanly handle all these different error cases now one more question you might ask yourself is why is this actually a data class and not a c class because what we could also do is we could have a sealed class let's call it cli set here don't call your classes like that i just don't want the name conflict and in here we could have for example a state loading and that is a cl2i state then we could have a state error let's make that a data class for example and that would contain the actual error which is of type error here which we have in our which we have in our ui state and the other one this one here and then we could also have a class for success which contains the actual data so the actual items which is a list of person here so why don't we do it like that because that way we can also easily distinguish between the different states so if we're loading we simply show the progress bar if there's an error we show the error message and so on the reason is with with this data class if we use data class instead of a c class as a parent element these elements are not mutually exclusive so what that means is if we have such a class we can have two or even three of these active at the same time so let's say we have a caching layer in our app and we can actually load the cache data from our database but we don't have internet connection so that means we do have a list of items that comes from the cache but we also have a network error so we want to show items and an error at the same time and that doesn't work with the c class because it's it's either or we can either have a loading state either an error state or a success state and with this ui state class we can have all of these theoretically at the same time or just two of these or just one of these so that's why i just use the single error seal class here that defines the different types of errors and then we can pass these here that's why i don't do it like this so far so good there is one more use case for clear classes that makes your code clean and that is a much easier one much easier to understand than what i taught you here before and that is using it to make some parameters more readable so you might have seen this person class in my repository each person just has a name and a variable if it's a male or not and that's a boolean so if that's true it's a male if it's false it's a female of course this works and we can distinguish between male and female with a boolean but the problem is it's not really readable so if a new person joins your project and sees this and sees okay is male as actually false what does it mean does that not mean it's a female does it mean it's any other kind of gender we don't know maybe we only have male and female in our app and this would technically be fine but a new person wouldn't know that and nowadays it of course makes fully sense to to think that there are multiple genders here in this app so the way we could fix this is with us here class so we could for example do this in here we could also do this c-class outside of this person class if we re-use it at different places but let's do it in here we can define a sealed class gender we can just define different genders here so object male which is a gender and object female which is also gender so even if we just have these two options in our app we can now rename this to gender and assign a gender here and this is of course much more readable if we then see something like a gender that male or gender.female and if we then also decide to extend this in future if we want to support multiple genders i don't know there are so many nowadays then we can just do this in this gender class here and we can simply add more and then also automatically assign more to this gender variable so in most cases using a boolean is fine if you just have two options for example is visible if that's false then you know it's not visible because there are those clear two options but let's say you'd also decide if if an element should be displayed on the left or on the right then you don't really want to use a boolean is left because if is left is false you don't really know okay is it now at the top is it not the bottom the right no then you would create a c class for that so maybe alignment.left alignment.right and even if you only have these two options it makes your code a lot more readable so that is it for this video a little bit longer than i actually expected but it's a very important video to make your code cleaner and i hope you liked it if so then you definitely will also like my free email newsletter so you can check down below and subscribe to that for free so you will get regular android content kotlin advice clean architecture advice right into your inbox so you also see some text written content by me apart from that i wish you an excellent day and i see you back in the next video bye bye
Info
Channel: Philipp Lackner
Views: 18,365
Rating: undefined out of 5
Keywords: android, tutorial, philip, philipp, filipp, filip, fillip, fillipp, phillipp, phillip, lackener, leckener, leckner, lackner, kotlin, mobile
Id: qzzkui-Z6CM
Channel Id: undefined
Length: 18min 9sec (1089 seconds)
Published: Mon Sep 13 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.