I think many of you are the fans of Diablo. I’m one of you In Diablo series, you can choose different characters to begin your Diablo journey. As a programmer, maybe you’ll write a base class, named Character. Suppose there are only two characters, named FatCharacter and ThinCharacter.
And we will define some common operations in the base class Character, define special skills in the derived classes.
You can see the sample source code first.
Download Full Project
Now, you can use the characters to walk around. However,, it’s dangerous to walk around in Diablo, because the monsters are everywhere, so the characters need to protect themselves. The FatCharacter can push the monsters, and the ThinCharacter can escape from the monsters’ attack. Maybe it’s not enough; we’d better give the characters some weapons, like sword or blade.
Now, our implementation is not suitable, so we need to change. A solution is, add more classes, such as FatCharacterWithSword, FatCharacterWithBlade and so on, and let these classes inherited from the FatCharacter and the ThinCharacter.
The class hierarchy will be as follows.
Now, the characters can use the weapon to beat the monsters.
Do you like this implementation? In this class hierarchy, you can see some classes are exactly the same, especially in level 3. If you want to add some other weapons, you may need to write the classes twice, one for the FatCharacter, and another for ThinCharacter. If you want to add a normal stature character, it would be worse and worse. Class explosion!
Watch the implementation carefully. There are two varying points, one is the character’s stature, and the other is the weapon. These two should be varying independently, not together. So, we need a new pattern to solve this, it is bridge pattern.
Decouple an abstraction from its implementation so that the two can vary independently.
– By THE GOF BOOK
In order to let the two vary independently, we should use composite instead of inheritance. Let the weapon be a part of the character, and the sword and the blade implement the weapon interface. Now the class hierarchy will be as follows.
Now, if you want to add a normal stature character, you just need to write a new class, not two or more, also, if you want to add an axe, you just need to write a new class and implement the weapon interface. You character can use the new weapon to attack the monsters.
In general, composite brings more flexibility than inheritance. Another important thing is separate the varying point, let them vary independently.
For more information you can take a look at the GoF book!
Enjoy!