Structural design pattern helps assemble classes and identify their relationship to make a modular and flexible structure. In this article, I will talk about the Decorator Pattern.
The Decorator Pattern is useful for extending an object's new features while keeping old ones intact. Since this pattern deals with creating modular and flexible structures, we can mix and match various features to create new unique items.
So, how is it different from classic inheritance? To understand the difference, let's talk about how a problem can be solved in a classical way and by a decorator pattern.
Suppose we want an already present class to have a completely new feature. We might make an abstract class and other concrete classes that extend from it. Each extended concrete class is different with a unique feature. Let's say we want to mix different features to create new unique ones.
Classically, we will create another new concrete class that derives from our abstract class and implement the feature from other classes. If we want another feature to be merged, we have to create another class. This continues infinitely, where we create new classes for every new feature to mix.
On the other hand, using a decorator pattern allows mixing already present features to dynamically create new features without creating separate classes. Decorator patterns reduce the creation of multiple subclasses while also providing the mixed feature of different objects. This provides inheritance with more flexibility. It also simplifies code as we add new features separately by extending available classes.
The design diagram for the decorator pattern is given below.
Implementation and Code
Now let's see how we can implement it in our code.
First of all, I create an interface ICharacterand a class Armour. ICharacter has Armour that contains different stats like defense, agility, and strength.
After this, I have created a BasicCharacterwhich implements ICharacter. This is the base class with the default armour.
A decorator pattern is about creating a decorator that inherits from the base class or interface. I have implemented ICharacter using this process below. This is called BaseArmour. All decorators should now implement from BaseArmour.
I have created three different decorators, ChestArmour,HeadArmour, and LegArmour,which all derive from BaseArmour. Each class has a unique armour property.
Finally, I have combined various properties to create a new unique object in the program below. I have created an object that combines the chest and head to get the combined armour effect. Following this rule, we can mix and match any unique armour to create a character with the combined armour effect.
From the example above, we can see how powerful the decorator pattern is if applied properly.
Thats it! I hope you learned something new from this. I will write more about different design patterns soon.