In this article I will share my opinion about Kotlin’s feature that I find absolutely amazing: Data Classes. The reason I like data classes so much is because they have the potential to “fix” a long-standing misconception about Object-Oriented Design that came from the Java ecosystem.
Data Classes:
Data Class is a special type of class in Kotlin. Unsurprisingly, these entities are intended to hold data. An outstanding example of good naming, isn’t it? You might think that I’m being sarcastic praising the name of this construct, but, in fact, I’m being absolutely serious. Will explain why in a moment.
Before we get to the main discussion, however, I would like to note that the syntax and the way Data Classes are used are completely irrelevant in the context of this article. Yes, I’m perfectly aware of the fact that Data Classes can eliminate considerable amount of boilerplate code. That’s just a bonus, not the core feature. Even if Data Classes would increase the amount of code, I’d still write this post.
Now, back to naming. Why do I find the name of Data Classes so exciting? First of all, it contains the term “data” which suggests that it should be used for data exclusively. More importantly, this construct is called “Data Class” and not “Data Object”. To understand why I find these aspects so important, let’s discuss the meaning of the term “object” in Object-Oriented Design.
Data/Object Anti-Symmetry:
Robert “Uncle Bob” Martin stated the following in his Clean Code book :
Mature programmers know that the idea that everything is an object is a myth.
Martin, Robert. Clean Code.
If something is not an object, then what?
In object-oriented design there are objects and there are data structures. Each has its own use cases, advantages and limitations. The general rule of thumb is that objects expose behavior, while data structures expose data.
It is very important to tailor objects and data structures to specific use cases, but it’s even more important to avoid mixing these two responsibilities in a single class. A class that is an object and a data structure at the same time violates Single Responsibility Principle by definition.
Let’s demonstrate the data/object anti-symmetry with a code example.
This interface represents an object because it exposes behavior:
public interface User { void logout(); void sendMessage(String message); }
This interface, despite having the same name, represents a data structure because it exposes data:
public interface User { String getName(); int getAge(); Address getAddress(); }
Both interfaces can be valid representations for “user” entity in the source code. The choice between them should be made according to the role of this class in the larger architectural context.
However, this is a bad representation of a “user” entity because this interface exposes both behavior and data:
public interface User { void logout(); void sendMessage(String message); String getName(); int getAge(); Address getAddress(); }
I do not intend to discuss object and data structures in detail here, so the above description is by no means exhaustive. You can read a much deeper explanation in Clean Code or in this outstanding post by Matt Carroll, which is one of my all time favorites. There is also another great article on this subject titled Data, objects, and how we’re railroaded into poor design.
Objects in Java:
All classes in Java inherit from the base Object
class, even if they don’t extend Object
explicitly. On the first sight, this suggests that all classes are “objects”. However, according to data/object anti-symmetry paradigm, part of the classes in a well-designed Java codebase must be data structures, not objects. Nevertheless, these data structures will also inherit from Object class, creating a confusion.
Unfortunately, the authors of Java hardcoded the misconception of “everything is an object” into the core of Java programming language by naming the implicit parent of all classes Object
. This naming misled generations of Java developers to believe that everything is indeed an object, and you can see the consequences of this erroneous belief in almost all Java codebases.
Data Classes are the Best Kotlin’s Feature:
Now I can get back to Kotlin Data Classes and explain why I think that this is the best feature of Kotlin.
Since this language construct explicitly geared towards data, it becomes a natural candidate for implementation of data structures. This is not bullet-proof solution because developers can still put both object and data structure responsibilities entangled in a single Data Class, but the sole fact that the language “guides” developers towards clear separation is a huge benefit in my opinion.
In addition, Kotlin doesn’t have Object
as an implicit base class for all other classes. Kotlin’s base class is called Any
. This means that Kotlin, in contrast to Java, doesn’t mislead developers into thinking that “everything is an object”.
Said all that, I think that Kotlin still made a mistake with “object” term by designating as “objects” anonymous classes and Singletons. Frankly, I can’t understand what line of thinking led Kotlin’s authors into adopting this terminology.
Still, even with the odd choice of “object” keyword, Kotlin is much better in context of data/object anti-symmetry because it has explicit Data Classes and doesn’t promote “everything is an object” mentality.
Conclusion:
As you might know, I’m not in Kotlin fan club. I’m not excited about writing less lines of code, I don’t believe that functional programming will become widespread, I don’t see much benefit to coroutines and I can achieve a reasonable null-safety in Java. I also hate the idea of not having checked exceptions.
That said, here are many features in Kotlin that I find very good and useful. Of all these features, Data Classes is the best one in my opinion. I like Data Classes because this language construct has the potential to fix a long-standing misconception that “everything is an object” which I blame on a poor choice of terminology in the Java ecosystem.
Time will tell.
As always, you are welcome to leave your comments and questions below, and consider subscribing to my mailing list if you liked this post.