Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...
Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...
Топ:
Процедура выполнения команд. Рабочий цикл процессора: Функционирование процессора в основном состоит из повторяющихся рабочих циклов, каждый из которых соответствует...
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов...
Основы обеспечения единства измерений: Обеспечение единства измерений - деятельность метрологических служб, направленная на достижение...
Интересное:
Лечение прогрессирующих форм рака: Одним из наиболее важных достижений экспериментальной химиотерапии опухолей, начатой в 60-х и реализованной в 70-х годах, является...
Принципы управления денежными потоками: одним из методов контроля за состоянием денежной наличности является...
Финансовый рынок и его значение в управлении денежными потоками на современном этапе: любому предприятию для расширения производства и увеличения прибыли нужны...
Дисциплины:
|
из
5.00
|
Заказать работу |
Содержание книги
Поиск на нашем сайте
|
|
|
|
Компоновщик (англ. Composite pattern) — шаблон проектирования, объединяет объекты в древовидную структуру для представления иерархии от частного к целому. Компоновщик позволяет клиентам обращаться к отдельным объектам и к группам объектов одинаково.
Цель
Паттерн определяет иерархию классов, которые состоят из примитивных и сложных объектов, упрощает архитектуру клиента, делает процесс добавления новых видов объекта более простым.
Описание

Примеры
Пример на Java
import java.util.List;
import java.util.ArrayList;
/** "Component" */
interface Graphic {
//Prints the graphic.
public void print();
}
/** "Composite" */
class CompositeGraphic implements Graphic {
//Collection of child graphics.
private List<Graphic> mChildGraphics = new ArrayList<Graphic>();
//Prints the graphic.
public void print() {
for (Graphic graphic: mChildGraphics) {
graphic.print();
}
}
//Adds the graphic to the composition.
public void add(Graphic graphic) {
mChildGraphics.add(graphic);
}
//Removes the graphic from the composition.
public void remove(Graphic graphic) {
mChildGraphics.remove(graphic);
}
}
/** "Leaf" */
class Ellipse implements Graphic {
//Prints the graphic.
public void print() {
System.out.println("Ellipse");
}
}
/** Client */
public class Program {
public static void main(String[] args) {
//Initialize four ellipses
Ellipse ellipse1 = new Ellipse();
Ellipse ellipse2 = new Ellipse();
Ellipse ellipse3 = new Ellipse();
Ellipse ellipse4 = new Ellipse();
//Initialize three composite graphics
CompositeGraphic graphic = new CompositeGraphic();
CompositeGraphic graphic1 = new CompositeGraphic();
CompositeGraphic graphic2 = new CompositeGraphic();
//Composes the graphics
graphic1.add(ellipse1);
graphic1.add(ellipse2);
graphic1.add(ellipse3);
graphic2.add(ellipse4);
graphic.add(graphic1);
graphic.add(graphic2);
//Prints the complete graphic (four times the string "Ellipse").
graphic.print();
}
}
Декоратор (шаблон проектирования)
Декоратор, Decorator — структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту. Шаблон Декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности.
Известен также под менее распространённым названием Обёртка (Wrapper), которое во многом раскрывает суть реализации шаблона.
Основные характеристики
Задача
Объект, который предполагается использовать, выполняет основные функции. Однако может потребоваться добавить к нему некоторую дополнительную функциональность, которая будет выполняться до, после или даже вместо основной функциональности объекта.
Способ решения
Декоратор предусматривает расширение функциональности объекта без определения подклассов.
Участники
Класс ConcreteComponent — класс, в который с помощью шаблона Декоратор добавляется новая функциональность. В некоторых случаях базовая функциональность предоставляется классами, производными от класса ConcreteComponent. В подобных случаях класс ConcreteComponent является уже не конкретным, а абстрактным. Абстрактный класс Component определяет интерфейс для использования всех этих классов.
Следствия
1. Добавляемая функциональность реализуется в небольших объектах. Преимущество состоит в возможности динамически добавлять эту функциональность до или после основной функциональности объекта ConcreteComponent.
2. Позволяет избегать перегрузки функциональными классами на верхних уровнях иерархии
3. Декоратор и его компоненты не являются идентичными
Реализация
Создается абстрактный класс, представляющий как исходный класс, так и новые, добавляемые в класс функции. В классах-декораторах новые функции вызываются в требуемой последовательности — до или после вызова последующего объекта.
При желании остаётся возможность использовать исходный класс (без расширения функциональности), если на его объект сохранилась ссылка.
Замечания и комментарии
Применение шаблона
Примеры реализации [показать]
Пример реализации шаблона на C#
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()
{
}
}
}
Примеры реализации на JavaScript
Шаблон декоратор в языках с динамической типизацией может быть применен без интерфейсов и традиционного для ООП наследования.
Этот пример скопирован с английской версии статьи. Расчет стоимости кофе:
// ConcreteComponent (класс для последующего декорирования)
function Coffee() {
this.cost = function() {
return 1;
};
}
// Decorator A
function Milk(coffee) {
this.cost = function() {
return coffee.cost() + 0.5;
};
}
// Decorator B
function Whip(coffee) {
this.cost = function() {
return coffee.cost() + 0.7;
};
}
// Decorator C
function Sprinkles(coffee) {
this.cost = function() {
return coffee.cost() + 0.2;
};
}
// Можно использовать, например, так:
var coffee = new Milk(new Whip(new Sprinkles(new Coffee())));
alert(coffee.cost());
// Или более наглядно:
var coffee = new Coffee();
coffee = new Sprinkles(coffee);
coffee = new Whip(coffee);
coffee = new Milk(coffee);
alert(coffee.cost());
Реализация имеющегося выше C# примера. В ConcreteComponent добавлена локальная переменная price, которая будет изменяться как в нем самом, так и декораторах. Имена классов (кроме постфиксов "A" и "B") совпадают с именами участников шаблона.
function Component() {
this.operation = function() { };
this.getPrice = function() { };
this.setPrice = function() { };
}
function ConcreteComponent() {
var price = 10;
this.operation = function() {
price += 4;
alert("ConcreteComponent.operation, price: "+ price);
};
this.getPrice = function() {
return price;
};
this.setPrice = function(val) {
price = val;
};
}
ConcreteComponent.prototype = new Component();
ConcreteComponent.prototype.constructor = ConcreteComponent;
function Decorator() {
var component;
this.setComponent = function(val) {
component = val;
};
this.getComponent = function() {
return component;
};
this.operation = function() {
component.operation();
};
this.getPrice = function() {
return component.getPrice();
};
this.setPrice = function(val) {
component.setPrice(val);
};
}
Decorator.prototype = new Component();
Decorator.prototype.constructor = Decorator;
function ConcreteDecoratorA() {
Decorator.call(this);
var operation = this.operation; // ссылка на метод, определенный в Decorator
this.operation = function() {
this.setPrice(this.getPrice() + 3);
alert("ConcreteDecoratorA.operation, price: "+ this.getPrice());
operation();
};
}
function ConcreteDecoratorB() {
var dublicate = this; // ссылка на инстанцирующийся объект (т.к. this может меняться)
Decorator.call(this);
var operation = this.operation; // ссылка на метод, определенный в Decorator
this.operation = function() {
this.setPrice(this.getPrice() + 1);
alert("ConcreteDecoratorB.operation, price: "+ this.getPrice());
addedBehavior();
operation();
};
function addedBehavior() {
dublicate.setPrice(dublicate.getPrice() + 2);
alert("addedBehavior, price: "+ dublicate.getPrice());
}
}
// использование
c = new ConcreteComponent();
d1 = new ConcreteDecoratorA();
d2 = new ConcreteDecoratorB();
alert("изначальная цена: " + c.getPrice()); // 10
d1.setComponent(c);
d2.setComponent(d1);
d2.operation();
alert("цена после преобразования: " + c.getPrice()); // 20
Литература
Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес Приемы объектно-ориентированного проектирования. Паттерны проектирования = Design Patterns: Elements of Reusable Object-Oriented Software. — СПб: «Питер», 2007. — С. 366.
Алан Шаллоуей, Джеймс Р. Тротт Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М.: «Вильямс», 2002. — С. 288.
|
|
|
Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...
Эмиссия газов от очистных сооружений канализации: В последние годы внимание мирового сообщества сосредоточено на экологических проблемах...
Типы оградительных сооружений в морском порту: По расположению оградительных сооружений в плане различают волноломы, обе оконечности...
История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...
© cyberpediasu.com 2017-2026 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!