Head First Design Patterns: 2 of 10
Tags: softwareenging, designpatterns, kotlin, java
Published: 2021-06-24 05:20:44

I just learnt my second design from the Head First Design Pattern book. Today, I learnt about the Decorator pattern.

According to Head First Design Patterns, the Decorator pattern is a pattern used to attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. 

This simply means Decorators allow you to add new behaviours to a class by wrapping them in a wrapper class. A wrapper is an object that has a reference to a target class and delegates all actions to the target class. 
Decorators must be of the same type of the wrapped class. This is what makes the decorator pattern different from a normal wrapper. 

Decorators come in handy situations such as these:
1. Adding new behaviour to classes you don't own.
2. A situation whereby using inheritance would lead to too many classes because of the different scenarios that must be covered by the software. For example, you were asked to design a software that calculates the total price of food  for a Nigerian native restaurant. Because of the various combinations of solids and soups, there would be a lot of classes to create and maintain.

In situations such as these, you can use the Decorator pattern. Here's how to implement the Decorator pattern.
```kotlin
abstract class Solid {
    abstract val description: String
    abstract val price: Int
}

class Eba : Solid() {
    override val description: String
        get() = "Eba"
    override val price: Int
        get() = 100
}

class Fufu : Solid(){
    override val description: String
        get() = "Fufu"
    override val price: Int
        get() = 200

}
```

```kotlin
abstract class SolidDecorator(val solid: Solid) : Solid() {
    abstract override val description: String
}

class NativeSoupDecorator(solid: Solid) : SolidDecorator(solid) {
    override val description: String
        get() = "${solid.description} with Native Soup"
    override val price: Int
        get() = solid.price + 500
}

class AfangSoupDecorator(solid: Solid) : SolidDecorator(solid) {
    override val description: String
        get() = "${solid.description} with Afang Soup"
    override val price: Int
        get() = solid.price + 500
}
```
Like I said before, Decorators are a special kind of wrappers. Take a look at the `SolidDecorator` abstract class. It has a reference to a `Solid` class and it also subclasses `Solid`. This is what makes Decorators special. You can then create many concrete classes of the `SolidDecorator` adding new behaviours to the initial wrapped class. Decorators can also add their behaviour before and/or after delegating actions to the target object.

```kotlin
    var order : Solid = Eba()
    order = NativeSoupDecorator(solid = order)
    order = AfangSoupDecorator(solid = order)
    order = FishDecorator(order)
    println("${order.description} price: ${order.price}")

    var order2 : Solid = Eba()
    order2 = NativeSoupDecorator(solid = order2)
    order2 = GoatMeatDecorator(solid = order2)
    println("${order2.description} price: ${order2.price}")

Eba, Native Soup, Afang Soup, goat meat price: 2100
Eba, Native Soup, goat meat price: 650
```

An example of the decorator pattern in android development can be found in this library: https://github.com/nhaarman/ListViewAnimations