Դեկորատոր (նախագծման ձևանմուշ)
Դեկորատոր (անգլ.՝ Decorator), կառուցվածքային նախագծման ձևանմուշ, որը նախատեսված է օբյեկտներին դինամիկ կերպով նոր վարք ավելացնելու համար։ Դեկորատոր ձևանմուշը դասի ֆունկցիոնալությունը մեծացնելու նպատակով ենթադասերի ստեղծման ճկուն այլընտրանք է հանդիսանում[1]։
Ընդհանուր հասկացողություններ[խմբագրել | խմբագրել կոդը]
- Client - հայցող
- Instance - նմուշ
- Implementation - իրականացում
- Product - արգասիք
Հիմնական բնութագիրներ[խմբագրել | խմբագրել կոդը]
Խնդիր[խմբագրել | խմբագրել կոդը]
Օբյեկտը, որը պետք է օգտագործվի, իրականացնում է հիմնական ֆունկցիաները։ Բայց կարող է անհրաժեշտ լինել նրան ավելացնել որոշակի լրացուցիչ ֆունկցիոնալություն, որը կարող է օգտագործել հիմնական ֆունկցիոնալությունից առաջ, հետո և նույնիսկ հիմնական ֆունկցիոնալության փոխարեն։
Լուծման տարբերակ[խմբագրել | խմբագրել կոդը]
Դեկորատորը օբյեկտի ֆունկցիոնալության ընդլայնումը դիտարկում է առանց ենթադասերի ստեղծման։
Մասնակիցներ[խմբագրել | խմբագրել կոդը]
ConcreteComponent
դաս, որտեղ Դեկորատորի միջոցով ավելացվում է նոր ֆունկցիոնալություն։ Որոշ դեպքերում բազային ֆունկցիոնալությունը ներկայացվում է դասերով, որոնք ստեղծվել են ConcreteComponent
դասի կողմից։ Այդ դեպքերում ConcreteComponent
արդեն կոնկրետ դաս չէ, այլ աբստրակտ է։ Component
աբստրակտ դասը տալիս է ինտերֆեյս բոլոր այդ դասերի օգտագործման համար։
Հետևություն[խմբագրել | խմբագրել կոդը]
- Ավելացվող ֆունկցիոնալությունը իրագործվում է ոչ մեծ օբյեկտներում։ Առավելությունն այն է, որ այդ ֆունկցիոնալությունը դինամիկ կերպով ավելանում է
ConcreteComponent
հիմնական ֆունկցիոնալությունից առաջ կամ հետո։ - Թույլ է տալիս դասերի վերին հիերարխիայում խուսափել ֆունկցիոնալությունների գերծանրաբեռնումից
- Դեկորատորը և նրա բաղկացուցիչ մասերը իդենտիկ չեն։
Իրականացում[խմբագրել | խմբագրել կոդը]
Ստեղծվում է աբստրակտ դաս, որն իրենից ներկայացնում է ելակետային դաս։ Ինչպես նաև ստեղծվում են նրո դասեր, որոնք ավելացվում են ֆունկցիայի դասի մեջ։ Դաս-դեկորատորներում նոր ֆունկցիաները կանչվում են ըստ հարկ եղած հերթականության՝ հերթական օբյեկտի կանչից առաջ կամ հետո։
Ցանկության դեպքում հնարավոր է նաև օգտագործել ելակետային դասը (առանց ֆունկցիոնալության ընդարձակման), եթե նրա օբյեկտի վրա պահպանվել է հղումը։
Ձևանմուշի կիրառություն[խմբագրել | խմբագրել կոդը]
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
}
}
Ծանոթագրություններ[խմբագրել | խմբագրել կոդը]
- ↑ Gamma, Erich; և այլք: (1995). Design Patterns. Reading, MA: Addison-Wesley Publishing Co, Inc. էջեր 175ff. ISBN 0-201-63361-2.
|