close
Today, I am going to organize something about decorator pattern, which is my thoghts after watching the tutorial created by Christopher Okhravi.
Besides I would like to implement it by using C# and hope that would help someone who is also learning decorator pattern.
Decaf and Espresso are sub-classes of BeverageBase, so both of them inherit two public abstract methods: getDesc() and Cost().
BeverageBase portion:
1: public abstract class BeverageBase
2: {
3: public abstract string getDesc();
4: public abstract int Cost();
5: }
Decaf portion:
1: public class Decaf : BeverageBase
2: {
3: public override int Cost()
4: {
5: return 2;
6: }
7:
8: public override string getDesc()
9: {
10: Console.WriteLine("2. Decaf");
11: return "Decaf";
12: }
13: }
Espresso portion:
1: public class Espresso:BeverageBase
2: {
3: public override int Cost()
4: {
5: return 1;
6: }
7: public override string getDesc()
8: {
9: Console.WriteLine("1. Espresso");
10: return "Espresso";
11: }
12: }
Now the problem is if we want to add something to Decaf or Espresso, how would you do that?
Intuitively, you may create another class named AddonDecorator, which also inherits BeverageBase class.
But the combination of addons are changeable, for example:
1. espresso + caramel
2. decaf + soymilk
3. decaf + soymilk + caramel
4. decaf + soymilk + 2*caramel
The above example shows four different combinations by using multiple“+”operators, which put all addons together step by step.
Here, caramel and soymilk are two kinds of addons.
Both of them can be viewed as sort of variations of BeverageBase, namely AddonDecorator
AddonDecorator Portion:
1: public abstract class AddonDecorator : BeverageBase
2: {
3:
4: }
For example, if we create a new menu of beverage: decaf + soymilk + caramel.
It not only keeps functions of BeverageBase(decaf) but also adds some addtional stuffs, namely AddonDecorators(soymilk + caramel).
Here comes the concept of decorator pattern: if we want to keep something( is_a) and also to add something (has_a).
CaramelDecorator portion:
1: public class CaramelDecorator : AddonDecorator // is_a
2: {
3: BeverageBase beverage; // has_a
4:
5: public CaramelDecorator(BeverageBase _beverage)
6: {
7: this.beverage = _beverage;
8: }
9: public override int Cost()
10: {
11: return this.beverage.Cost() + 3;
12: }
13:
14: public override string getDesc()
15: {
16: if (beverage != null)
17: {
18: beverage.getDesc();
19: }
20: Console.WriteLine("3. Caramel");
21: return "Caramel";
22: }
23: }
SoymilkDecorator Portion:
1: public class SoymilkDecorator : AddonDecorator // is_a
2: {
3: BeverageBase beverage; // has_a
4: public SoymilkDecorator(BeverageBase _beverage)
5: {
6: this.beverage = _beverage;
7: }
8:
9: public override int Cost()
10: {
11: return this.beverage.Cost() + 4;
12: }
13:
14: public override string getDesc()
15: {
16: if(beverage!=null)
17: {
18: beverage.getDesc();
19: }
20: Console.WriteLine("4. Soymilk");
21: return "Soymilk";
22: }
23: }
1: static void Main(string[] args)
2: {
3: BeverageBase decaf = new Decaf();
4: BeverageBase espresso = new Espresso();
5:
6: BeverageBase order1 = new CaramelDecorator(espresso);
7: Console.WriteLine("Order1 : espresso + caramel");
8: order1.getDesc();
9: Console.WriteLine("Pay for order1: {0}\n", order1.Cost());
10:
11: BeverageBase order2 = new SoymilkDecorator(decaf);
12: Console.WriteLine("Order2 : decaf + soymilk");
13: order2.getDesc();
14: Console.WriteLine("Pay for order2: {0}\n", order2.Cost());
15:
16: BeverageBase order3 = new CaramelDecorator(order2);
17: Console.WriteLine("Order3 : decaf + soymilk + caramel");
18: order3.getDesc();
19: Console.WriteLine("Pay for order3: {0}\n", order3.Cost());
20:
21: BeverageBase order4 = new CaramelDecorator(order3);
22: Console.WriteLine("Order4 : decaf + soymilk + 2*caramel");
23: order4.getDesc();
24: Console.WriteLine("Pay for order4: {0}\n", order4.Cost());
25: Console.ReadKey();
26:
27: }
The following screenshot demonstrates the above four combinations of beverage by using decorator pattern technique.
Now let`s review four types of order in another way
1. espresso + caramel
2. decaf + soymilk
3. decaf + soymilk + caramel
4. decaf + soymilk + 2*caramel
(1) Decorating Sequence: decorator #1→decorator #2→decorator #3
-
( SoymilkDecorator decorates Decaf ), which is labeled as decorator #1
-
( CaramelDecorator decorates decorator #1), which is labeled as decorator #2
-
( CaramelDecorator decorates decorator #2), which is labeled as decorator #3
(2) Calling Sequence: decorator #3→decorator #2→decorator #1
(3) Executing Sequence: decorator #1→decorator #2→decorator #3
Other usefule articles:
全站熱搜
留言列表