We have all enjoyed some freebies at some point in our lives. Be it a coupon or discount code for shopping or having your IDE generate getters and setters for you free of charge.
Free Sugar
Such little things can make your already wonderful programmer’s life even more wonderful considering no one likes to write boilerplate code. But you also need to be wary of some of these “freebies”. One of the reasons why I love Kotlin is because of it's idiomatic features and for good reason. It can make your code look nice and sweet with all its syntactic sugar. However, just like any other sugar, it could have some adverse effects. It could be on performance or memory for example. Sometimes, you need to know what goes on under the hood. Try leaving sugar all around and what happens?
Data Class
One of such freebies is Kotlin’s data
class. The data class is used for holding data - that's all. If you’re handling any form of logic whatsoever or using it beyond this single purpose, chances are you’re doing it wrong. And oh, it’s pronounced data, not data.
Creating a data class in Kotlin comes with so many freebies you can easily be tempted to use it throughout your code. With data classes, the compiler gives you free equals()
, hashCode()
, toString()
, copy()
, getters and setters, … I can’t imagine I used to create most of these for every DTO when I used to take this coffee:
The DTO headache
I use data classes for my DTOs. A DTO(Data Transfer Object) is an object for transferring data between services. So as a good OOP guy, I once used them for storing and retrieving data from Firebase for an Android app I was working on. Everything worked great until they didn’t. What happened? Well, the objects were saved with the expected properties alright, but on retrieving them, there was a problem. It had to do with a Boolean value; a value so critical for telling how the app behaved - yes, just that one property was that important!
It wasn’t necessarily because it was a Boolean value, but that as a good namer for properties, I’d named this one is_group_chat
. That’s the way 10x programmers name stuff like this, so certainly the problem wasn't in the name per se. The problem was in the setter function Kotlin’s compiler generated for this property.
Here's a sample data class:
data class BookDto(
var id: String = "",
var is_digital_copy: Boolean = false,
var borrower_phone_number: String = ""
)
The getters and setters generated for each of them(in Java) will look like:
public void setId(String id){}
public void getId(){}
public void set_digital_copy(boolean is_digital_copy){}
public void is_digital_copy(){}
public void setBorrower_phone_number(String borrower_phone_number){}
public void getBorrower_phone_number(){}
This is how I was deserializing the Firebase snapshot:
val bookDto = snapshot.getValue<BookDto>()
If you'd pay attention to the Logcat at this point, you may see something similar to:
No setter/field for is_digital_copy found on class com.package.app.BookDto
A closer look at the method names reveals something interesting. Methods generated for property names beginning with is
are different from the rest. This is fine except that when deserializing the object back into BookDto
, Firebase's serializer looks for method names having the format similar to what the compiler generated for id
and borrower_phone_number
. To set is_digital_copy
, it will look for a method named setIs_digital_copy
.
The Pill
The solution I went with was to make is_digital_copy
private to prevent the compiler from generating its getter and setter methods. I then provided them manually naming them to match what the deserializer was expecting:
fun setIs_digital_copy(value: Boolean){}
And that's how I got rid of this headache.
Hopefully this can save someone from cursing Firebase, their IDE, laptop or banging the desk so hard the paint peels off from their walls!
Conclusion
It may appear that I presented Kotlin's syntactic sugar in a bad light in the beginning but that's not the point. The point is, you really need to understand your tools very well. Most "sugars" just tend to hide much for convenience sake and at sometimes they come at a hidden cost too.
That’s all folks. Do well to comment, like and share it all over. No, seriously, show some love 😁. I’d like to say happy coding but that may be giving you some false sense of hope, especially if you're using JavaScript. So instead, let me leave you with some advice. Next time you find something as good as sugar:
I use Twitter for Android just in case you want to hang out.