Decorator pattern provides 2 main features:
1. It attaches additional responsibilities to an object dynamically.
2. It provides a flexible alternative to sub-classing for extending functionality.
Here I am going to use D&D character creation as an example although I feel it is better to use Factory pattern instead but for the sake of this tutorial, let’s just use it.
We have “Character” abstract class and “Human” class extends it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package { // Abstract class public class Character { protected var name:String; function Character() {} public function getName():String { return name; } public function fight():String { throw new Error("Need to extend it!"); } } // Concrete class public class Human extends Character { function Human() { name = "Human"; } override public function fight():String { return name + " fight with hand"; } } } |
Now we want to attach the character with weapons, we create “WeaponDecorator” abstract class that extends “Character” which ensure the interface compatibility. Then we create “Sword” class that extends it and pass the “Character” reference through the constructor by composition and attach new weapon in “fight()” method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package { // Abstract decorator public class WeaponDecorator extends Character { protected var char:Character; function WeaponDecorator(char:Character) { this.char = char; } } // Concrete decorator public class Sword extends WeaponDecorator { function Sword(char:Character) { super(char); } override public function fight():String { return (this.char.fight() + " and sword"); } } } |
Here is the client code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package { import flash.display.*; import flash.events.*; public class Main extends MovieClip { function Main() { var human:Character = new Human(); trace(human.fight()); // Decorating human with sword var swordman:WeaponDecorator = new Sword(human); trace(swordman.fight()); } } } // Output: // Human fight with hand // Human fight with hand and sword |
Of course, you can add another weapon by creating another weapon class like “Axe” and pass the sword reference to it etc…
No user commented in " Decorator Pattern "
Follow-up comment rss or Leave a TrackbackLeave A Reply