Decorator.cs
Код подключён напрямую из исходного файла в кодировке UTF-8, поэтому эта страница всегда показывает его актуальную версию.
← К конспекту
Скачать исходный файл
| Decorator.cs |
|---|
| using System;
namespace DesignPatterns.Structural.Decorator
{
// Общий интерфейс для базового объекта и всех декораторов
public interface ICoffee
{
string Describe();
decimal GetCost();
}
// Базовая реализация (то, что декорируем)
public sealed class Espresso : ICoffee
{
public string Describe() => "Эспрессо";
public decimal GetCost() => 90m;
}
// Базовый декоратор хранит ссылку на оборачиваемый объект
// и по умолчанию просто делегирует ему вызовы.
public abstract class CoffeeDecorator : ICoffee
{
protected readonly ICoffee Inner;
protected CoffeeDecorator(ICoffee inner)
{
Inner = inner;
}
public virtual string Describe() => Inner.Describe();
public virtual decimal GetCost() => Inner.GetCost();
}
public sealed class WithMilk : CoffeeDecorator
{
public WithMilk(ICoffee inner) : base(inner) { }
public override string Describe() => $"{Inner.Describe()} + молоко";
public override decimal GetCost() => Inner.GetCost() + 30m;
}
public sealed class WithSyrup : CoffeeDecorator
{
private readonly string _flavor;
public WithSyrup(ICoffee inner, string flavor) : base(inner)
{
_flavor = flavor;
}
public override string Describe() => $"{Inner.Describe()} + сироп ({_flavor})";
public override decimal GetCost() => Inner.GetCost() + 20m;
}
public static class Demo
{
public static void Run()
{
// Декораторы можно комбинировать в любом порядке и количестве -
// каждый добавляет своё поведение поверх предыдущего, ничего не зная об остальных.
ICoffee order = new WithSyrup(new WithMilk(new Espresso()), "карамель");
Console.WriteLine($"{order.Describe()} - {order.GetCost():C}");
}
}
}
|