Decorator Starbuzz Code


This entry is part 2 of 2 in the series Decorator Pattern

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();
        }
    }
}
Series Navigation<< Decorator Pattern Introduction