Kotlin property delegation in Android
Every pattern for software development is designed with code reusability in mind. Kotlin has no difference in this. One of the patterns used in Kotlin is property delegation. If you ever have used val value by lazy { getTheValue() }
, then you have already used the property delegation pattern.
What is Property Delegation?
When a property has passed on the authority of its getter/setter into a third class.
A property by default has a getter and a setter depending if it is val
or var
. We can create another class which overrides the operators (get
, set
) and then make our custom getter and setter to work as getter and setter of this property.
It seems difficult in theory, but keep reading because the examples are much more clean!
What we have
Let’s say that we have already implemented a project with a lot of RecyclerView.Adapter
classes here and there. An example of one of these Adapters could be the following:
The example above takes a List
of User
s and shows the names into a vertical list. Imagine that in your project you have a lot of these!
What we want
A new requirement arrived and they want to print the list which is put into every adapter. Obviously, searching for every submitList()
function and copy-paste Log.v(“Items”, “$item”)
is not a solution!
What we can do
One of the first things that comes to my mind is a solution with inheritance. A BaseAdapter
class which does the logging and every child of this is going to call its super
function before proceeding.
With this solution we have a decent object oriented solution and we also know that the jungle is about to be implemented. This BaseAdapter
in a couple of months is not going to be as Base
as it sounds!
What we should do
As you may have heard a lot “Composition should be preferred over inheritance” and property delegation knows that really well. This pattern is going to rescue us.
The getValue
is going to be called instead of the getter of the property and obviously the setValue
is going to called instead of the setter of the property. Take a closer look at the setValue
and notice that we have put the logging there, we have assigned the new value and trigger the submitList
of our AsyncListDiffer
.
Imagine using this with the legacy Adapter and never worried about calling
notifyDatasetChanged
at every list change! You are not going to see this “Fatal Exception: java.lang.IndexOutOfBoundsException
Inconsistency detected. Invalid item position…” in your crashlytics anymore!
Notice that your list users
has been delegated to AdapterUpdaterDelegate
. The only thing that you have to do right now is to set a new list (adapter.users = usersList
) and you are ready to go!
The end
You can find the whole application here but unfortunately it belongs in a bigger repository, so if you want to clone/download this application you shall clone the whole repo.
More
Do you want to see more refactoring/design ideas? Here is the table of contents.