Декоратор (Decorator)

Шаблон Декоратор предназначен для динамического добавления к объекту новой функциональности. Он является гибкой альтернативой наследованию (в том числе множественному). Декоратор служит обёрткой для декорируемого объекта и реализует тот же интерфейс, что и класс декорируемого объекта. Однако декоратор добавляет свой код до, после или вместо вызовов методов декорируемого объекта. Это приводит к модификации исходного поведения и появлению новых возможностей.

Выделим следующих участников шаблона Декоратор (рис. 2). Интерфейс IComponent определяет общие функции исходных компонентов и декораторов[4]. Класс ConcreteComponent – это компонент, функциональность которого необходимо модифицировать. Класс Decorator – базовый декоратор (как правило, он включает механизм хранения компонента и реализует простую переадресацию). Конкретные декораторы ConcreteDecoratorA и ConcreteDecoratorB наследуются от базового декоратора, добавляя определённое состояние и (или) поведение.

Рис. 2. Схема шаблона Декоратор.

Разберём использование шаблона Декоратор на следующем примере. Пусть имеется класс Element, описывающий элемент блок-схемы. Для простоты ограничимся текстом элемента и методом его отображения на консоли.

public interface IElement

{

string Text { get; set; }

void Draw();

}

public class Element: IElement

{

public string Text { get; set; }

public void Draw()

{

Console.WriteLine("Element text = {0}", Text);

}

}

Создадим базовый декоратор для класса Element.

public class ElementDecorator: IElement

{

protected readonly IElement Component;

public ElementDecorator(IElement component)

{

Component = component;

}

public virtual string Text

{

get { return Component.Text; }

set { Component.Text = value; }

}

public virtual void Draw()

{

Component.Draw();

}

}

Теперь разработаем два декоратора: один для добавления отступов перед элементом, а второй – для обрамления элемента в скобки.

public class ElementWithIdent: ElementDecorator

{

public int Ident { get; set; }

public ElementWithIdent(IElement component): base(component)

{

}

public override void Draw()

{

MakeIdent();

base.Draw();

}

private void MakeIdent()

{

Console.Write(new string(' ', Ident));

}

}

public class ElementWithBrackets: ElementDecorator

{

public ElementWithBrackets(IElement component): base(component)

{

}

public override void Draw()

{

Console.WriteLine("[");

base.Draw();

Console.WriteLine("]");

}

}

Все готово к применению компонентов и их декораторов. Вначале создадим исходный компонент, а потом дополним его возможности, используя оба декоратора. Обратите внимание на то, что несколько декораторов могут независимо применяться к одному и тому же объекту, а также на то, что декоратор может декорировать объект, который уже декорирован.

// обыкновенный элемент

IElement element = new Element {Text = "Demo"};

element.Draw();

// декорирование отступом

IElement ei = new ElementWithIdent(element) {Ident = 4};

ei.Draw();

// дополнительное декорирование скобками

IElement eb = new ElementWithBrackets(ei);

eb.Draw();


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: