- Decorator Pattern Introduction
- Decorator Starbuzz Code
This post contains the code I wrote for the example in the book Head First Design Patterns.. The name of the Windows Presentation Foundation project is called DecoratorStarbuzz.
This project is a C# project, not Java. It is also a Window Presentation Foundation (WPF) project.
Below is the XAML code for the WPF project I called DecoratorStarbuzz.
<Window x:Class="DecoratorStarbuzz.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:DecoratorStarbuzz" mc:Ignorable="d" Title="Head First Design Patterns - Ch 3" Height="250" Width="400"> <StackPanel Margin="10"> <TextBlock FontSize="14" FontWeight="Bold">Chapter 3 - The Decorator Pattern</TextBlock> <TextBlock x:Name="txtBlk" TextWrapping="Wrap"></TextBlock> <TextBlock FontSize="14" FontWeight="DemiBold" x:Name="txtBlk0" TextWrapping="Wrap">Welcome to StarBuzz</TextBlock> <TextBlock x:Name="txtBlk1" TextWrapping="Wrap"></TextBlock> <TextBlock x:Name="txtBlk2" TextWrapping="Wrap"></TextBlock> </StackPanel> </Window>
Below is the C# code behind. I created a WPF solution and called the solution DecoratorStarbuzz. You can create your own project and use this code.
using System; using System.Windows; namespace DecoratorStarbuzz { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); BeginOrdering(); } public void BeginOrdering() { Beverage beverage = new Espresso(); string str = beverage.getDescription(); DateTime dt = DateTime.Now; txtBlk2.Text = str + " $" + beverage.cost() + " - " + dt.ToShortDateString() + " " + dt.ToShortTimeString() + " Thank You." + "\n" + "\n"; Beverage beverage2 = new DarkRoast(); beverage2 = new Mocha(beverage2); // Mocha "has-a" Dark Roast beverage2 = new Mocha(beverage2); // Mocha has a Mocha that has a Dark Roast beverage2 = new Whip(beverage2); txtBlk2.Text = txtBlk2.Text + beverage2.getDescription() + " $" + beverage2.cost().ToString() + "\n" + "\n"; // perhaps a better way to create decorator objects is found in the // Factory Pattern and the Builder Pattern. Beverage beverage3 = new Decaf(); beverage3 = new Soy(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); txtBlk2.Text = txtBlk2.Text + beverage3.getDescription() + " $" + beverage3.cost() + "\n" + "\n"; } } }
Below is the code for the Beverage.
namespace DecoratorStarbuzz { public abstract class Beverage { public string description = "Unknown Beverage"; public abstract double cost(); public virtual string getDescription() { return description; } } }
Espresso.cs
namespace DecoratorStarbuzz { public class Espresso : Beverage { public Espresso() { description = "Espresso"; // Beverage.description } public override double cost() { return 1.99; } } }
DarkRoast.cs
namespace DecoratorStarbuzz { public class DarkRoast : Beverage { public DarkRoast() { description = "Dark Roast Coffee"; } public override double cost() { return .99; } } }
Decaf.cs
namespace DecoratorStarbuzz { public class Decaf : Beverage { public Decaf() { description = "Decaf Coffee"; } public override double cost() { return 1.10; } } }
CondimentDecorator.cs
namespace DecoratorStarbuzz { public abstract class CondimentDecorator : Beverage { public override abstract string getDescription(); } }
Mocha.cs
namespace DecoratorStarbuzz { public class Mocha : CondimentDecorator { Beverage beverage; public Mocha(Beverage beverage) { this.beverage = beverage; } public override string getDescription() { return beverage.getDescription() + " Mocha"; } public override double cost() { return 0.20 + beverage.cost(); } } }
Soy.ca
namespace DecoratorStarbuzz { class Soy : CondimentDecorator { Beverage beverage; public Soy(Beverage beverage) { this.beverage = beverage; } public override string getDescription() { return beverage.getDescription() + " Soy"; } public override double cost() { return 0.15 + beverage.cost(); } } }
Whip.cs
namespace DecoratorStarbuzz { class Whip : CondimentDecorator { Beverage beverage; public Whip(Beverage beverage) { this.beverage = beverage; } public override string getDescription() { return beverage.getDescription() + " Whip"; } public override double cost() { return 0.10 + beverage.cost(); } } }