public interface IIceCream { void Prepare(); decimal GetPrice(); } public class ChocolateIceCream : IIceCream { public void Prepare() { Console.WriteLine("Preparing a chocolate ice cream."); } public decimal GetPrice() { return 2.50m; // base price for chocolate ice cream } } public class VanillaIceCream : IIceCream { public void Prepare() { Console.WriteLine("Preparing a vanilla ice cream."); } public decimal GetPrice() { return 2.00m; // base price for vanilla ice cream } } public abstract class IceCreamDecorator(IIceCream decorated) : IIceCream { protected IIceCream _decorated = decorated; public abstract void Prepare(); public abstract decimal GetPrice(); } public class SprinkleDecorator(IIceCream decorated) : IceCreamDecorator(decorated) { public override void Prepare() { // call the base first _decorated.Prepare(); Console.WriteLine("Adding sprinkles!"); } public override decimal GetPrice() { return _decorated.GetPrice() + 0.50m; // add price for sprinkles } } public class ChocolateSyrupDecorator(IIceCream decorated) : IceCreamDecorator(decorated) { public override void Prepare() { // call the base prepare first _decorated.Prepare(); Console.WriteLine("Adding chocolate syrup!"); } public override decimal GetPrice() { return _decorated.GetPrice() + 0.75m; // add price for chocolate syrup } } public class CaramelSyrupDecorator(IIceCream decorated) : IceCreamDecorator(decorated) { public override void Prepare() { // call the base prepare first _decorated.Prepare(); Console.WriteLine("Adding caramel syrup!"); } public override decimal GetPrice() { return _decorated.GetPrice() + 0.75m; // add price for caramel syrup } } internal class Program { static void Main(string[] args) { decimal price = new CaramelSyrupDecorator( new ChocolateSyrupDecorator( new SprinkleDecorator( new ChocolateIceCream() ) ) ).GetPrice(); Console.WriteLine($"Total price: {price:C}"); } }