---
title: Kotlin is Dope And So Are Its Custom Property Delegates
teaser: An introduction to Kotlin's delegate properties and some real life examples.
tags: kotlin,android,mobile
author: Amanda Hill
published_on: 2017-10-23
---

In case you haven’t heard yet, Kotlin is dope 👌🏼. Like, really, seriously,
super dope. Don’t believe me? Well allow me to try and convince you. Today I
want to share with you one of my favorite features of the language - Delegated
Properties - and some of the ways I’ve used them in REAL apps that I’ve REALLY
shipped. And if by the end of the post you are not convinced, well that would be
a shame, but on the bright side at least I got you to read a post that used the
word “dope” in the first sentence.

## What Are Delegated Properties?

Delegated Properties are regular ol’ properties who delegate how they are either
written or read (think getters or setters) to some other function. For example,
let’s say we have the following class.

```kotlin
class Dog {
  var isAGoodDoggo: Boolean = true
}
```

Now we all know that ALL dogs are good dogs 🐶, so let’s say we want
`isAGoodDoggo` to always return `true`. Now you’re probably thinking, “Amanda,
we can just make the property an immutable `val` and then it can’t be changed.”
And you’d be totally right, but that wouldn't make for a very fun example. So
let’s assume we have some requirement that this must be a mutable `var`. As you
might have guessed, another way to ensure that the value for `isAGoodDoggo` will
always return `true` is by creating a custom property delegate. In this case,
since it’s a `var` we’ll need a to implement a `ReadWriteProperty`. 

Let’s look at the definition for a `ReadWriteProperty`:

```kotlin
public interface ReadWriteProperty<in R, T> {
    /**
     * Returns the value of the property for the given object.
     * @param thisRef the object for which the value is requested.
     * @param property the metadata for the property.
     * @return the property value.
     */
    public operator fun getValue(thisRef: R, property: KProperty<*>): T

    /**
     * Sets the value of the property for the given object.
     * @param thisRef the object for which the value is requested.
     * @param property the metadata for the property.
     * @param value the value to set.
     */
    public operator fun setValue(thisRef: R, property: KProperty<*>, value: T)
}
```

Now for the fun part, writing our own! 

## Writing Our Own Delegate

```kotlin
class GoodDoggoDelegate : ReadWriteProperty<Any?, Boolean> {

  override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
    return true
  }

  override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
  }
}
```

You might notice I didn't implement anything for `setValue` and that’s because
it doesn't matter what we put here since `getValue` is always going to return
`true`. 

Now let’s update our `Dog` class: 

```kotlin
class Dog {
  var isAGoodDoggo: Boolean by GoodDoggoDelegate()
}
```

And that’s it! When we read from `isAGoodDoggo`, the property will delegate to
the `GoodDoggoDelegate` instance and call the `getValue()` function. 

This was admittedly a very basic and not very useful example just to get you
comfortable with the concept. Now I’m going to share some more practical
examples that I have stolen straight out of apps that I have developed. 

## `ObservableProperty`

Kotlin provides some custom implementations of delegated properties for us to
use. One example is `ObservableProperty` which mimics all of the basic
functionality of a read/write property, but also calls a callback function when
the property is changed. The real “dope” aspect to the callback function used in
`ObservableProperty` is that it passes through the old and the new value. As you
might imagine this can be very useful in applications - as it is a much cleaner
alternatives to callbacks. 

## `Delegates.observable` Example

Example time ⏰! Below are some snippets from an audio recording app. The app
allowed a user to record some audio, play it back, and then upload it to a
server. These various states were reflected in code in the following `sealed
class`.

```kotlin
sealed class RecordingViewState {
  class PreRecord : RecordingViewState()
  class Recording : RecordingViewState()
  class Reviewing : RecordingViewState()
  class Transmitting : RecordingViewState()
}
```

In our `Activity`, or wherever you want to hold onto this state, we will use a
`Delegates.observable` to listen to changes to the state:

```kotlin
private var state: RecordingViewState by Delegates.observable<RecordingViewState>(PreRecord())
  { _, old, new ->
    when (new) {
      is PreRecord -> { }
      is Recording -> { }
      is Reviewing -> { }
      is Transmitting -> { }
    }
  }
```

Now, we can now easily update the necessary views depending on the new state,
while also utilizing the `old` state in cases where a particular transition or
animation is necessary. For example, if the new state is `Recording` you might
want different animations if the old (or previous) state was `PreRecord` vs if
it was `Reviewing`. Like this...  

```diff 
  private var state: RecordingViewState by Delegates.observable<RecordingViewState>(PreRecord())
  { _, old, new ->
    control_record_btn.state = new
    when (new) {
      is PreRecord -> { }
      is Recording -> {
+        if (old is PreRecord) {
+          animatePreRecordViewsAway()
+        }
+        if (old is Reviewing) {
+          hideReviewingButtons()
+        }
      }
      is Reviewing -> { }
      is Transmitting -> { }
    }
  }
```

## Custom Properties As Custom Data Structures

Another use case I have found for custom delegated properties is to use them to
create my own data structures. On a recent project, I was developing an app that
centered around baseball ⚾️. One of the screens in the app showed a list of all
the players who threw the ball during a given play and I needed a backing data
structure to reflect this list. The data structure needed to meet the following
requirements: 

1. It must be a list containing only items of type `Player` 
2. The list was ordered by the order of throws - i.e. the player at index 0
   threw the ball to the player at index 1, and so on.
3. The list cannot have consecutive duplicates - i.e. a player cannot throw to
   himself. 

I couldn't use a regular ol' `List` as that would not prohibit me from adding
duplicates 🙅🏻. I couldn't use a `Set` as the same `Player` might be in the list
twice - just not directly before or after himself 🙅🏻. So what was I to do!?
🤷🏻‍♀️

One option might have been to use a `List` and just have a crazy custom setter.
But that felt ugly and easy for someone in the future to remove or edit
incorrectly. As you probably guessed, the option I chose was to use a custom
`ObservableProperty`. 

The custom delegate looks like this:

```kotlin
class NoConsecutiveDuplicates<T>(initialValue: List<T>) : ObservableProperty<List<T>>(initialValue) {

  override fun beforeChange(property: KProperty<*>, oldValue: List<T>, newValue: List<T>): Boolean {
    return oldValue.isEmpty() || newValue.isEmpty() || oldValue.last() != newValue.last()
  }
}
```

And to use this custom delegate, the code looks like this:

```kotlin
private var playersInvolved: List<Player> by NoConsecutiveDuplicates(emptyList())
```

So when we attempt to add a `Player` to the list, the delegate’s `beforeChange`
method is called, which returns `true` if the new value is being added to the
list, and returns `false`, if the new value is discarded and the list remains
the same.

While this same functionality can certainly be achieved in other ways, I like
the clarity and reusability of using a custom `ObservableProperty` and I hope
you do too! And maybe you might even start telling your friends how dope
Kotlin’s delegated properties are!?
