Composition over Inheritance - Delegation in Kotlin

# Favour Composition over Inheritance

When dealing with code duplication and reusabilty issues it is good to favour Composition over Inheritance.

# Overview
<!-- 発端や概要を記載 -->

- This is a universally accepted concept.
- Inheritance is not always bad.
- Composition is not suitable for or used in all circumstances.
- Kotlin encourages Composition and makes Inheritance harder.
- Design and document for Inheritance else prohitibt it.
- Composition should be the first design choice in mind.
- We should still use Inheritance if it is required and designed for.

<a id="#reference"></a>
# Example 1

Let's look at an example. We add some an some `animals` to a program.

```言語名:Animals with duplication
class Dog {
   fun bark()
   fun eat()
}

class Cat {
   fun meow()
   fun eat()
}
```

We have dupication of the ` eat()` function so let's solve this with a base `Animal` class.

```言語名:Animals with Inheritance
class Animal {
   fun eat()
}

class Dog: Animal {
   fun bark()
}

class Cat: Animal {
   fun meow()
}
```

However, we get the error `This type is final, so it cannot be inherited from`.

This is because Kotlin helps us not abuse Interitance so by default classes are `final` which means we need the special keyword `open` to extend them (Java is the opposite). 

Let's add the `open` keyword and inherit from the base class.

```言語名:Animals with Inheritance
open class Animal {
   fun eat()
}

class Dog: Animal {
   fun bark()
}

class Cat: Animal {
   fun meow()
}
```

It looks good so far with Inheritance. 

Now let's add some more functionality to the program. We now need to add some `robots`.

```言語名:Robots with duplication
class CleaningRobot {
   fun clean()
   fun drive()
}

class FeedingRobot {
   fun feed()
   fun drive()
}

```
There is duplication on `drive()` so let's use Inheritance to solve this.

```言語名:Robots with Inheritance
open class Robot {
   fun drive()
}

class CleaningRobot: Robot {
   fun clean()
}

class FeedingRobot: Robot {
   fun feed()
}
```

All is well so far but now we add more functionality. 

We now require a `cleaning robot dog`. It needs to `drive()`, `clean()` and `bark()` but doesn't `eat()`. 

It doesn't look good for Inheritance because we can only inherit from one class. We could try and make a new super class but you will end up with an unclear base class with too much responsibility.

We are stuck because Inheritance acts as a contract that is hard to break. Also the more features you add the tighter the coupling becomes and the tighter the coulping the more you add features!

This can be avoided by opting for Composition.

# Composition
<!-- 発端や概要を記載 -->

- It is the concept of a class referencing instances of other objects (every class basically does that)
- Gives same functionality as Inheritance without the coupling.
- If Inheritance is a good fit you should use it else use Composition.
- Kotlin is a great language for Composition.

This is an example of Composition. 

Class A contains variable B

```言語名:Composition
class A { 
   val b = B() 
}
```

# Kotlin favours Composition
<!-- 発端や概要を記載 -->

- In Kotlin all classes are `final` and not `open` for Inheritance by default.
- It has the keyword `Object`. This creates a single instance of a class in the compiler.
- We can delegate the implementation of an Inerface to another class with the keyword `By`.

So let's use Composition to implement the `cleaning robot dog`. We need three Interfaces for this:

```言語名:Interfaces
interface Cleaner { 
   fun clean() 
}

interface Drivable { 
   fun drive() 
}

interface Barker { 
   fun bark() 
}
```
Now the Interfaces need implmentation. Let's create three Objects (you can also use classes here).

```言語名:Object implementions
object CleaningRobot: Cleaner { 
   override fun clean() { }
}

object DrivingRobot: Drivable { 
   override fun drive() { } 
}

object BarkingAnimal: Barker { 
    override fun bark() { } 
}
```

Now the can create the `cleaning robot dog` class and use Composition. 

The `By` keyword allows us to implement the Interface and delegate the work to the Objects.

```言語名:CleaningRobotDog with Delegation
class CleaningRobotDog: 
   Cleaner by CleaningRobot,
   Drivable by DrivingRobot,
   Barker by BarkingAnimal
```

They can then be used again and again to compose classes that require the behavior. No Inheritance needed. 

Using the `By` keyword is called Delegation. We can use the functionality available from delegating class/object which in this case is `drive()`, `clean()` and `bark()`.

<a id="#reference"></a>
# Example 2

How about a more realistic example. 

We require an analytics logger feature to log print statements for app lifecycle events `start` and `pause`. We need to include this behaviour in all our screen classes.

A beginner might use a static class for this but that will contain boilerplate code and coupling that is difficult to test.

So let's use Composition to implement the `AnalyticsLogger`:

```言語名:AnalyticsLogger
interface AnalyticsLogger { 
   fun registerLifeCycleOwner(owner: LifecycleOwner) 
}

class AnalyticsLoggerImplementation: AnalyticsLogger, LifecycleEventObserver {
   override fun registerLifeCycleOwner(owner: LifecycleOwner) {
      owner.lifecycle.addObserver(this)
   }

   override fun onStateChanged(source: LifecycleOwner, event: Lifecyle.Event) {
      when(event) {
         Lifecycle.Event.ON_RESUME -> println("User opened the screen")
         Lifecycle.Event.ON_PAUSE -> println("User closed the screen")
         else -> Unit
      }
   }
}
```

We can now add the `AnalyticsLogger` to our Activity class (screen class).

We just need to pass the LifecycleOwner inside of `registerLifeCycleOwner`.

The `By` keyword is then used delegate the work to the `AnalyticsLoggerImplementation`.

Also because we use an Interface we can add more than one (unlike class Inheritance).

```言語名: Activity class
class MainActivity: ComposeActivity, AnalyticsLogger by AnalyticsLoggerImplementation {
   override fun onCreate(saveInstanceState: Bundle?) {
      super.onCreate(saveInstanceState)
      registerLifeCycleOwner(this)
   }
}
```

I hope you learned something new today. Merry Christmas.