Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
!Шпора по ООПиП (3).docx
Скачиваний:
35
Добавлен:
22.09.2019
Размер:
2.31 Mб
Скачать

83. Декоратор (шаблон проектирования)

структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту. Шаблон Декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности.

Известен также под менее распространённым названием Обёртка (Wrapper), которое во многом раскрывает суть реализации шаблона.

Задача

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

Способ решения

Декоратор предусматривает расширение функциональности объекта без определения подклассов.

Участники

Класс ConcreteComponent — класс, в который с помощью шаблона Декоратор добавляется новая функциональность. В некоторых случаях базовая функциональность предоставляется классами, производными от класса ConcreteComponent. В подобных случаях класс ConcreteComponent является уже не конкретным, а абстрактным. Абстрактный класс Component определяет интерфейс для использования всех этих классов.

Следствия

1. Добавляемая функциональность реализуется в небольших объектах. Преимущество состоит в возможности динамически добавлять эту функциональность до или после основной функциональности объекта ConcreteComponent. 2. Позволяет избегать перегрузки функциональными классами на верхних уровнях иерархии 3. Декоратор и его компоненты не являются идентичными

Реализация

Создается абстрактный класс, представляющий как исходный класс, так и новые, добавляемые в класс функции. В классах-декораторах новые функции вызываются в требуемой последовательности — до или после вызова последующего объекта.

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

Замечания и комментарии

  • Хотя объект-декоратор может добавлять свою функциональность до или после функциональности основного объекта, цепочка создаваемых объектов всегда должна заканчиваться объектом класса ConcreteComponent.

  • Базовые классы языка Java широко используют шаблон Декоратор для организации обработки операций ввода-вывода.

using System;

namespace Decorator

{

class MainApp

{

static void Main()

{

// Create ConcreteComponent and two Decorators

ConcreteComponent c = new ConcreteComponent();

ConcreteDecoratorA d1 = new ConcreteDecoratorA();

ConcreteDecoratorB d2 = new ConcreteDecoratorB();

// Link decorators

d1.SetComponent(c);

d2.SetComponent(d1);

d2.Operation();

// Wait for user

Console.Read();

}

}

/// <summary>

/// Component - компонент

/// </summary>

/// <remarks>

/// <li>

/// <lu>определяем интерфейс для объектов, на которые могут быть динамически

/// возложены дополнительные обязанности;</lu>

/// </li>

/// </remarks>

abstract class Component

{

public abstract void Operation();

}

/// <summary>

/// ConcreteComponent - конкретный компонент

/// </summary>

/// <remarks>

/// <li>

/// <lu>определяет объект, на который возлагается дополнительные обязанности</lu>

/// </li>

/// </remarks>

class ConcreteComponent : Component

{

public override void Operation()

{

Console.WriteLine("ConcreteComponent.Operation()");

}

}

/// <summary>

/// Decorator - декоратор

/// </summary>

/// <remarks>

/// <li>

/// <lu>хранит ссылку на объект <see cref="Component"/> и определяет интерфейс,

/// соответствующий интерфейсу <see cref="Component"/></lu>

/// </li>

/// </remarks>

abstract class Decorator : Component

{

protected Component component;

public void SetComponent(Component component)

{

this.component = component;

}

public override void Operation()

{

if (component != null)

{

component.Operation();

}

}

}

/// <summary>

/// ConcreteDecorator - конкретный декоратор

/// </summary>

/// <remarks>

/// <li>

/// <lu>возглагает дополнительные обязанности на компонент.</lu>

/// </li>

/// </remarks>

class ConcreteDecoratorA : Decorator

{

private string addedState;

public override void Operation()

{

base.Operation();

addedState = "New State";

Console.WriteLine("ConcreteDecoratorA.Operation()");

}

}

// "ConcreteDecoratorB"

class ConcreteDecoratorB : Decorator

{

public override void Operation()

{

base.Operation();

AddedBehavior();

Console.WriteLine("ConcreteDecoratorB.Operation()");

}

void AddedBehavior()

{

}

}

}