Decorator Design Patter Using Swift

Decorator Design Pattern

It allows you to add behavior to an individual object.
It helps to add such behavior changes, dynamically without affecting the behavior of the other objects from the same parent class.

Decorator design pattern strong holds to Single Responsibility principle. i.e a Base concrete Object.

It is somewhat similar to chain or responsibility design pattern (ex: UIViewController,UIView) where exactly one of the class handles the responsibility, ex: touch events to UITextField, the iOS infrastructure tries to find the responder who can respond to it, if you have implemented a delegate or a IBAction change event , it is directed to that root UIView -> UIViewController -> UIWindow -> UIApplication.

In case of the Decorator Design pattern all classes handle the request which we will see in the example listed below.

A simple example to understand with this would be creating a "Simple Coffee" object and "Coffee Latte".

I will try to make a parent struct to hold a Simple Coffee object. From this structure we can derive CoffeeLatte with the help of a Decorator.

You can download the Code from GitHub

Below Steps is what we need to follow in order to achieve a solution.

- Create a Protocol which defines the basic behavior i.e CoffeeProtocol

This includes cost and ingredients of the Coffee.

protocol CoffeeProtocol {
    var cost : Float { get }
    var ingredients:String { get }

}

- Create a concrete Implementation of this Behavior i.e SimpleCoffee

Here will assign some basic cost and ingredients to make a simple coffee. Example it cost's $1 and ingredients coffee.

struct SimpleCoffee: CoffeeProtocol {
    var cost: Float = 1.0
    
    var ingredients: String = "Coffee"

}

- We need to Implement a CoffeeLatte which will be derived from CoffeeProtocol. How?  that's a good question explained Further.

* Create a decorator protocol which simply takes in a SimpleCoffee. This decorator Protocol (i.e CoffeeDecoratorProtocol) extends from basic behavior protocol(CoffeeProtcol)

protocol CoffeeDecoratorProtocol:CoffeeProtocol {
    var simpleCoffe: SimpleCoffee { get  }
}

* Create a concrete structure by implementing decorator protocol. i.e CoffeeLatte

As mentioned previously all class handle the request. We call the base class and add a cost of 1.0 to the CoffeeLatte and ingredients as milk.


struct CoffeLatte:CoffeeDecoratorProtocol {
    var simpleCoffe: SimpleCoffee
    
    
    var cost: Float {
        return simpleCoffe.cost +  1.0
    }
    
    var ingredients: String {
        return simpleCoffe.ingredients + ", Milk"
    }
}



So far we have accomplished our objective of flexibility. But, what about extensibility?

I would like to add coffee latte with flavor. ex: Coffee Latte with Strawberry Flavor.

For this we need this to our basic behavior i.e add flavor to CoffeeProtocol.

protocol CoffeeProtocol {
    var cost : Float { get }
    var ingredients:String { get }
    
    var flavor:String {get} // Added to create Coffee Latter Strawberry Flavor

}

SimpleCoffee and CoffeeLatte would not have flavor's. So it will be blank for them.

But the new CoffeeLatteStrawberry will have it with the help of Decorator protocol.

if notice here the behavior of the existing structure SimpleCoffee and CoffeeLatte is unchanged.


struct CoffeeLatteStrawberry:CoffeeDecoratorProtocol {
    var simpleCoffe: SimpleCoffee
    
    var cost: Float {
        return simpleCoffe.cost + 2.0
    }
    
    var ingredients: String {
        return simpleCoffe.ingredients + ", Milk , Strawberry syrup"
    }
    
    var flavor: String {
        return simpleCoffe.flavor + "Strawberry"
    }
    
    
}


The final code with implementation in AppDelegate will print below lines of code in the console.

Coffee  (flavor ) =  1.0
Coffee, Milk  (flavor ) =  2.0

Coffee, Milk , Strawberry syrup  (flavor Strawberry) =  3.0


Comments

Popular posts from this blog

hitTest on iOS to identify the view being hit

CMTimeMakeWithSeconds explained

Custom Editing Control for UITableViewCell , like iPhone Mail Appliation