Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Created May 27, 2024 08:18
Show Gist options
  • Save sunmeat/c4f3ca97546f03eab89fd931142b1e5c to your computer and use it in GitHub Desktop.
Save sunmeat/c4f3ca97546f03eab89fd931142b1e5c to your computer and use it in GitHub Desktop.
pattern decorator C# example
// размеры чашек
enum Size { S = 80, M = 180, L = 280, XXL = 500 }
abstract class Beverage // базовый абстрактный напиток
{
protected Size size;
protected double price;
protected string? description;
public Size GetSize()
{
return size;
}
public double GetPrice()
{
return price;
}
public string? GetDescription()
{
return description;
}
public void Print()
{
Console.WriteLine(description + " = " + price + " UAH");
}
}
// чёрный чай - (относительно) конкретный базовый напиток без добавок
class BlackTea : Beverage
{
public BlackTea(Size size)
{
this.size = size;
description = "black tea from teabag";
if (size == Size.M) price = 27; // 180г
else if (size == Size.L) price = 32; // 280г
else throw new ArgumentException("invalid cup size");
}
}
// зелёный чай - конкретный базовый напиток без добавок
class GreenTea : Beverage
{
public GreenTea()
{
// size = ...
description = "green leaf tea";
price = 45;
}
}
// эспрессо - конкретный базовый напиток без добавок
class Espresso : Beverage
{
public Espresso()
{
// size = ...
description = "small portion of strong coffee";
price = 29;
}
}
////////////////////////////////////////////////////////////////
// базовая абстрактная добавка
abstract class Condiment : Beverage // добавка помечена как наследник напитка - это важно для реализации паттерна!
{
protected Beverage? beverage; // ссылка на оригинальный напиток
}
// молоко
class MilkCondiment : Condiment
{
public MilkCondiment(Beverage beverage)
{
this.beverage = beverage; // базовый напиток, в который пойдёт добавка
description = this.beverage.GetDescription() + " + Milk (3 UAH)";
price = this.beverage.GetPrice() + 3;
}
public MilkCondiment() // молоко может быть основой напитка
{
this.beverage = this; // базовый напиток, в который пойдёт добавка
description = "glass of milk";
price = 10;
}
}
class ChocolateCondiment : Condiment
{
public ChocolateCondiment(Beverage beverage)
{
this.beverage = beverage;
description = this.beverage.GetDescription() + " + Chocolate (5 UAH)";
price = this.beverage.GetPrice() + 5;
}
}
class SugarCondiment : Condiment
{
public SugarCondiment(Beverage beverage)
{
this.beverage = beverage;
description = this.beverage.GetDescription() + " + Sugar (1 UAH)";
price = this.beverage.GetPrice() + 1;
}
}
class Program
{
static void Main(string[] args)
{
Beverage espresso = new Espresso();
Beverage blackTea = new BlackTea(Size.L);
Beverage greenTea = new GreenTea();
espresso.Print();
blackTea.Print();
greenTea.Print();
Console.WriteLine("================================================");
Beverage capuccino = new SugarCondiment(new MilkCondiment(new Espresso()));
capuccino.Print();
Beverage chocolateCapuccino = new ChocolateCondiment(capuccino);
chocolateCapuccino.Print();
Beverage extraSweetBlackTea = new SugarCondiment(new SugarCondiment(new SugarCondiment(new BlackTea(Size.L))));
extraSweetBlackTea.Print();
Beverage glassOfMilk = new MilkCondiment(new MilkCondiment(new MilkCondiment()));
glassOfMilk.Print();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment