- 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();
}
}
}
