🎉 Ура! Після трьох років роботи, я нарешті випустив англійську версію книжки про патерни! Ось вона »

C#: Декоратор

Decorator Декоратор Decorator

Декоратор — це структурний патерн, який дозволяє додавати «на льоту» нові поведінки об’єктам, розміщаючи їх в об’єктах-обгортках.

Декоратор дозволяє загортати об’єкти безліч разів завдяки тому, що і обгортки, і реальні об’єкти, що загортаються, мають спільний інтерфейс.

Детальніше про Декоратор

Особливості паттерна на C#

Складність:

Популярність:

Застосування: Патерн можна часто зустріти в C#-коді, особливо якщо код створено для роботи з потоками даних.

Ознаки застосування патерну: Декоратор можна розпізнати за створенними методами, які приймають в параметрах об’єкти того ж абстрактного типу чи інтерфейсу, що і поточний клас.

Приклад: Структура патерну

Цей приклад показує структуру патерну Декоратор, а саме — з яких класів він складається, які ролі ці класи виконують і як вони взаємодіють один з одним.

Program.cs: Приклад структури патерну

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RefactoringGuru.DesignPatterns.Composite.Structural
{
    class Program
    {
        static void Main(string[] args)
        {
            Client client = new Client();

            var simple = new ConcreteComponent();
            Console.WriteLine("Client: I get a sumple component:");
            client.ClientCode(simple);
            Console.WriteLine();

            ConcreteDecoratorA d1 = new ConcreteDecoratorA(simple);
            ConcreteDecoratorB d2 = new ConcreteDecoratorB(d1);
            Console.WriteLine("Client: Now I get a decorated component:");
            client.ClientCode(d2);
        }
    }

    public class Client
    {
        public void ClientCode(Component component)
        {
            Console.WriteLine("RESULT: " + component.Operation());
        }
    }

    public abstract class Component
    {
        public abstract string Operation();
    }

    class ConcreteComponent : Component
    {
        public override string Operation()
        {
            return "ConcreteComponent";
        }
    }

    abstract class Decorator : Component
    {
        protected Component component;

        public void SetComponent(Component component)
        {
            this.component = component;
        }

        public Decorator(Component component)
        {
            this.component = component;
        }

        public override string Operation()
        {
            if (component != null)
            {
                return component.Operation();
            }
            else
            {
                return string.Empty;
            }
        }
    }

    class ConcreteDecoratorA : Decorator
    {
        public ConcreteDecoratorA(Component comp) : base(comp)
        {
        }

        public override string Operation()
        {
            return "ConcreteDecoratorA(" + base.Operation() + ")";
        }
    }

    class ConcreteDecoratorB : Decorator
    {
        public ConcreteDecoratorB(Component comp) : base(comp)
        {
        }

        public override string Operation()
        {
            return "ConcreteDecoratorB(" + base.Operation() + ")";
        }
    }
}

Output.txt: Результат виконання

Client: I get a sumple component:
RESULT: ConcreteComponent

Client: Now I get a decorated component:
RESULT: ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent))