Concept
I didn’t know about the Delegation Pattern until I learned Kotlin and saw people using the by
keyword when declaring a variable. So I tried to learn more and discovered a whole new world of this pattern.
~~ A bit dramatic, isn’t it? 😅😅 ~~
To make it easy to understand, Delegation means assigning tasks to someone else. But let’s just use the terms “delegation” and “delegate” to keep things clear and professional, especially in work or interviews.
The Delegation Pattern is an object-oriented design pattern that allows object composition to achieve the same code reuse as inheritance.
In short: Delegation Pattern allows objects to reuse code similarly to inheritance.
In delegation, there are two components:
- Receiving object
- Delegate object
When a request needs to be handled, the receiving object doesn’t handle it directly but delegates the task to the delegate object. It’s like having an older brother or sister who’s really good at math, and every time the teacher gives you homework, you ask them to do it for you.
So how is this different from Inheritance? In inheritance, you can also call methods from the parent class, right?
That’s true, but inheritance should only be used when the child class is truly related to the parent class. For example, a Cat
class can inherit from Animal
, but shouldn’t inherit from Transportation
. Also, the child class must override all abstract methods of the parent, which is sometimes unnecessary. Delegation gives us more flexibility.
Example Illustration
Back to the earlier example, suppose you have a brother who’s an engineer and a sister who’s a doctor. They’re both very talented.
|
|
You’re a bit of a lazy student, so you need a helper class, with a parameter being a kind person who’s always ready to help you out.
|
|
Now, every time the teacher gives homework, you can ask your brother or sister to do it for you.
|
|
Delegation Pattern in Kotlin
The by
Keyword in Kotlin
Kotlin supports the Delegation Pattern through the by
keyword, which helps reduce boilerplate code.
|
|
Now, the LazyStudentHelper
class must implement the TalentPerson
interface, so it can delegate the doHomework
method to the kindPerson
instance.
Delegated Properties
There are several ways to use Delegation when declaring variables in Kotlin:
- Lazy properties: the value is computed the first time it is accessed.
- Observable properties: listeners are notified when the property changes.
Lazy properties
lazy
is a function that takes a lambda and returns an instance of the Lazy<T>
class.
|
|
The first time lazyValue
is called, the result is computed and stored. Subsequent calls just return the stored value. So the output will be:
|
|
Observable properties
|
|
Delegates.observable()
takes two arguments:
- The initial value
- A function to handle changes to the
name
variable. It’s called every time you assign a value to the variable.
The result will be:
|
|