**Դեկորատոր** (անգլ.՝ Decorator), կառուցվածքային նախագծման ձևանմուշ, որը նախատեսված է օբյեկտներին դինամիկ կերպով նոր վարք ավելացնելու համար։ Դեկորատոր ձևանմուշը դասի ֆունկցիոնալությունը մեծացնելու նպատակով ենթադասերի ստեղծման ճկուն այլընտրանք է հանդիսանում։

Ընդհանուր հասկացողություններ
----------------------------

* Client - հայցող
* Instance - նմուշ
* Implementation - իրականացում
* Product - արգասիք

Հիմնական բնութագիրներ
---------------------

### Խնդիր

Օբյեկտը, որը պետք է օգտագործվի, իրականացնում է հիմնական ֆունկցիաները։ Բայց կարող է անհրաժեշտ լինել նրան ավելացնել որոշակի լրացուցիչ ֆունկցիոնալություն, որը կարող է օգտագործել հիմնական ֆունկցիոնալությունից առաջ, հետո և նույնիսկ հիմնական ֆունկցիոնալության փոխարեն։

### Լուծման տարբերակ

Դեկորատորը օբյեկտի ֆունկցիոնալության ընդլայնումը դիտարկում է առանց ենթադասերի ստեղծման։

### Մասնակիցներ

`ConcreteComponent` դաս, որտեղ Դեկորատորի միջոցով ավելացվում է նոր ֆունկցիոնալություն։ Որոշ դեպքերում բազային ֆունկցիոնալությունը ներկայացվում է դասերով, որոնք ստեղծվել են `ConcreteComponent` դասի կողմից։ Այդ դեպքերում `*ConcreteComponent*` արդեն կոնկրետ դաս չէ, այլ աբստրակտ է։ `*Component*` աբստրակտ դասը տալիս է ինտերֆեյս բոլոր այդ դասերի օգտագործման համար։

### Հետևություն

1. Ավելացվող ֆունկցիոնալությունը իրագործվում է ոչ մեծ օբյեկտներում։ Առավելությունն այն է, որ այդ ֆունկցիոնալությունը դինամիկ կերպով ավելանում է `ConcreteComponent` հիմնական ֆունկցիոնալությունից առաջ կամ հետո։
2. Թույլ է տալիս դասերի վերին հիերարխիայում խուսափել ֆունկցիոնալությունների գերծանրաբեռնումից
3. Դեկորատորը և նրա բաղկացուցիչ մասերը իդենտիկ չեն։

### Իրականացում

Ստեղծվում է աբստրակտ դաս, որն իրենից ներկայացնում է ելակետային դաս։ Ինչպես նաև ստեղծվում են նրո դասեր, որոնք ավելացվում են ֆունկցիայի դասի մեջ։ Դաս-դեկորատորներում նոր ֆունկցիաները կանչվում են ըստ հարկ եղած հերթականության՝ հերթական օբյեկտի կանչից առաջ կամ հետո։

Ցանկության դեպքում հնարավոր է նաև օգտագործել ելակետային դասը (առանց ֆունկցիոնալության ընդարձակման), եթե նրա օբյեկտի վրա պահպանվել է հղումը։

Ձևանմուշի կիրառություն
----------------------

Windows-ի կորիզում դրայվեր-ֆիլտրերն (WDM (Windows Driver Model) ճարտարապետություն) իրենցից ներկայացնում են դեկորատորներ։ Չնայած նրան, որ WDM-ն իրականացրած է Objective-C ծրագրավորման լեզվով, նրանցում հստակորեն հետևել են դեկորատոր ձևանմուշի կիրառմանը։

COM (Component Object Model) ճարտարապետությունը չի սպասարկում ժառանգումը։ Դրա փոխարեն այն առաջարկում է դեկորատորներ (կոնկերտ ճարտարապետության մեջ այն կոչվում է «ագրեգացիա»)։

Օրինակներ
---------

### C++

```
#include <iostream>
#include <memory>
 
class IComponent {
public:
 virtual void operation() = 0;
 virtual ~IComponent(){}
};
 
class Component : public IComponent {
public:
 virtual void operation() {
 std::cout<<"World!"<<std::endl;
 }
};
 
class DecoratorOne : public IComponent {
 std::shared\_ptr<IComponent> m\_component;
 
public:
 DecoratorOne(IComponent\* component): m\_component(component) {}
 
 virtual void operation() {
 std::cout << ", ";
 m\_component->operation();
 }
};
 
class DecoratorTwo : public IComponent {
 std::shared\_ptr<IComponent> m\_component;
 
public:
 DecoratorTwo(IComponent\* component): m\_component(component) {}
 
 virtual void operation() {
 std::cout << "Hello";
 m\_component->operation();
 }
};
 
int main() {
 DecoratorTwo obj(new DecoratorOne(new Component()));
 obj.operation(); // prints "Hello, World!\n"
 
 return 0;
}

```

### C#

```
using System;

namespace Decorator
{
 class MainApp
 {
 static void Main()
 {
 // Create ConcreteComponent and two Decorators
 ConcreteComponent c = new ConcreteComponent();
 ConcreteDecoratorA dA = new ConcreteDecoratorA();
 ConcreteDecoratorB dB = new ConcreteDecoratorB();

 // Link decorators
 dA.SetComponent(c);
 dB.SetComponent(dA);

 dA.Operation();

 Console.WriteLine();

 dB.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.Write("Привет");
 }
 }

 /// <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>
 /// ConcreteDecoratorA - конкретный декоратор
 /// </summary>
 /// <remarks>
 /// <li>
 /// <lu>Выполняет основную задачу</lu>
 /// </li>
 /// </remarks>
 class ConcreteDecoratorA : Decorator
 {
 public override void Operation()
 {
 base.Operation();
 }
 }

 /// <summary>
 /// ConcreteDecorator - конкретный декоратор
 /// </summary>
 /// <remarks>
 /// <li>
 /// <lu>Выполняет основную задачу + дополнительную</lu>
 /// </li>
 /// </remarks>
 class ConcreteDecoratorB : Decorator
 {
 public override void Operation()
 {
 base.Operation();

 Console.Write(" Мир!");
 }
 }
}

```

### Java

```
public interface InterfaceComponent {
 void doOperation();
}

class MainComponent implements InterfaceComponent {
 
 @Override
 public void doOperation() {
 System.out.print("World!");
 } 
}

abstract class Decorator implements InterfaceComponent {
 protected InterfaceComponent component;
 
 public Decorator (InterfaceComponent c) {
 component = c;
 }
 
 @Override
 public void doOperation() {
 component.doOperation();
 }
 
 public void newOperation() {
 System.out.println("Do Nothing");
 }
}

class DecoratorSpace extends Decorator{
 
 public DecoratorSpace(InterfaceComponent c) {
 super(c);
 }
 
 @Override
 public void doOperation() {
 System.out.print(" ");
 super.doOperation();
 }
 
 @Override
 public void newOperation() {
 System.out.println("New space operation");
 } 
}

class DecoratorComma extends Decorator {

 public DecoratorComma(InterfaceComponent c) {
 super(c);
 }
 
 @Override
 public void doOperation() {
 System.out.print(",");
 super.doOperation();
 } 
 
 @Override
 public void newOperation() {
 System.out.println("New comma operation");
 }
}

class DecoratorHello extends Decorator {
 
 public DecoratorHello(InterfaceComponent c) {
 super(c);
 }
 
 @Override
 public void doOperation() {
 System.out.print("Hello");
 super.doOperation();
 }
 
 @Override
 public void newOperation() {
 System.out.println("New hello operation");
 }
}

class Main {
 
 public static void main (String... s) {
 Decorator c = new DecoratorHello(new DecoratorComma(new DecoratorSpace(new MainComponent())));
 c.doOperation(); // Ծրագրի կատարման արդյունքը "Hello, World!"
 c.newOperation(); // New hello operation
 }
}

```

Ծանոթագրություններ
------------------

1. ↑  Gamma Erich (1995)։ *Design Patterns*։ Reading, MA: Addison-Wesley Publishing Co, Inc.։ էջեր 175ff։ ISBN 0-201-63361-2


|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * դ
* ք
* խ
Նախագծման ձևանմուշներ |
| --- |
|  |
| ԳօՖիձևանմուշներ | 

|  |  |
| --- | --- |
| Ստեղծող | Աբստրակտ ֆաբրիկա • Կառուցող • Ֆաբրիկային մեթոդ • Նախատիպ • Եզակի օգտագործման |
| Կառուցվածքային | Ադապտեր • Կամուրջ • Կազմող • Դեկորատոր • Ճակատ • Հարմարեցնող • Պրոքսի |
| Վարքագծային | Պարտականությունների շղթա • Հրաման • Թարգմանիչ • Իտերատոր • Միջնորդ • Պահպանող • Դիտորդ • Վիճակ • Մարտավարություն • Կաղապարային մեթոդ • Այցելող |

 |
|  |
| Ստեղծող ձևանմուշներ | Ծույլ բեռնում • Բազմակի օգտագործման • Օբյեկտների ավազան • Ռեսուրսի ստանալը ինիցիալիզացիա է |
|  |
| Կառուցվածքային ձևանմուշներ | Ճակատը հսկող • Մոդուլ |
|  |
| Համաձայնեցման ձևանմուշներ | Ակտիվ օբյեկտ • Հենվող • Մեկուսացում կրկնակի ստուգումով • Ասինքրոն կանչի մեթոդ • Պահպանվող կախոց • Ռեգիստրացնող • Կողպեքավորող • Մոնիտոր • Նախագործող • Ապագործող • Ընթերցողներ-գրողի կողպեք • Պլանավորման • Հոսքերի ավազանի • Հոսքերի լոկալ հիշողություն |
|  |
| Ճարտարապետական ձևանմուշներ | Ճակատը հսկող ձևանմուշ • Զավթող ձևանմուշ • ձևանմուշի ներկայացման վերահսկում • Բազմաշերտ • Հատկորոշում • Հրատարակող-ստորագրող • Մերկ օբյեկտներ • Ծառայության լոկատոր • Ակտիվ գրառման • Բազմության իդենտիֆիկացման • Data access object • Data transfer object |
|  |
| Այլ ձևանմուշներ | Կախվածության ներդնում • Mock օբյեկտ • Զրոյական օբյեկտ • Ծառայող • Թունելային տարատեսակի |

 |