Wzorzec projektowy dekorator - decorator

Autor podstrony: Krzysztof Zajączkowski

Stronę tą wyświetlono już: 3182 razy

Opis wzorca projektowego dekorator

Wzorzec projektowy dekorator należy do wzorców strukturalnych. Wzorzec tego typu umożliwia rozszerzenie funkcjonalności podstawowego obiektu poprzez opakowanie go. Obiekt opakowujący nazywa się dekoratorem i zawiera on wskaźnik do interfejsu głównego obiektu po którym również on dziedziczy.

Przykład diagramu UML wzorca projektowego dekorator

Poniższy przykład diagramu UML umożliwia rozszerzenie działania obiektu podstawowego klasy Tank, która dziedziczy interfejs iTank o nowe elementy takie jak:

Powyższe klasy dziedziczą po interfejsie iDecorator, który zawiera wskaźnik na interfejs iTank, po którym równocześnie dziedziczy. Ważną rolę odgrywa tutaj również destruktor wirtualny umożliwiający poprawne zwalnianie pamięci dynamicznie zadeklarowanej.

Przykładowy diagram UML wzorca projektowego dekorator
Rys. 1
Przykładowy diagram UML wzorca projektowego dekorator

Przykład implementacji dekoratora w C++

#include <iostream> #include <string> class iTank{ public: virtual void writeDescription() const = 0; virtual void externalTank() const {}; virtual void externalMachineGun() const {}; virtual ~iTank(){}; }; class Tank : public iTank{ protected: std::string tankType; float fuelMaximum; float fuelLevel; float cannonDiameter; public: Tank(std::string tankType, float fuelMaximum, float fuelLevel, float cannonDiameter) : tankType(tankType), fuelMaximum(fuelMaximum), fuelLevel(fuelLevel), cannonDiameter(cannonDiameter){} virtual void writeDescription() const { std::cout<<"Tank type: "<<tankType<<std::endl; std::cout<<"=================================="<<std::endl; std::cout<<"Maximum fuel level: "<<fuelMaximum<<std::endl; std::cout<<"FuelLevel: "<<fuelLevel * fuelMaximum<<std::endl; std::cout<<"Cannon diameter: "<<cannonDiameter<<std::endl<<std::endl; externalTank(); externalMachineGun(); } }; class iDecorator : public iTank{ protected: iTank* itank; public: iDecorator(iTank* itank) : itank(itank){} virtual ~iDecorator(){ if(itank){ std::cout<<"Delete external tank!"<<std::endl<<std::endl; delete itank; itank = NULL; } } }; class ExternalTank : public iDecorator{ protected: float fuelMaximum; float fuelLevel; public: ExternalTank(iTank* itank, float fuelMaximum, float fuelLevel) : iDecorator(itank), fuelMaximum(fuelMaximum), fuelLevel(fuelLevel){}; virtual ~ExternalTank(){ std::cout<<"Delete external fuel tank!"<<std::endl; } virtual void writeDescription() const { if(itank) itank->writeDescription(); externalTank(); externalMachineGun(); } virtual void externalTank() const { std::cout<<"External fuel tank"<<std::endl; std::cout<<"=================================="<<std::endl; std::cout<<"Maximum fuel level: "<<fuelMaximum<<std::endl; std::cout<<"FuelLevel: "<<fuelLevel * fuelMaximum<<std::endl<<std::endl; } }; class ExternalMachineGun : public iDecorator{ protected: float diameter; public: ExternalMachineGun(iTank* itank, float diameter) : iDecorator(itank), diameter(diameter){}; virtual ~ExternalMachineGun(){ std::cout<<"Delete external machine gun"<<std::endl; } virtual void writeDescription() const { if(itank) itank->writeDescription(); externalTank(); externalMachineGun(); } virtual void externalMachineGun() const { std::cout<<"External machine gun"<<std::endl; std::cout<<"=================================="<<std::endl; std::cout<<"Diameter: "<<diameter<<std::endl<<std::endl; } }; void deleteTank(iTank* &itank){ if(itank){ delete itank; itank = NULL; } } int main(){ iTank* tank = new Tank("M1A1 Abrams", 1900, 1, 105); tank->writeDescription(); iTank* tankWithExternalTank = new ExternalTank(new Tank("M1A1 Abrams", 1500, 1, 105), 1500, 1); tankWithExternalTank->writeDescription(); iTank* tankWithExternalMachineGun = new ExternalMachineGun(new Tank("M1A1 Abrams", 1500, 1, 105), 30); tankWithExternalMachineGun->writeDescription(); iTank* tankWithExternalTankAndMachineGun = new ExternalTank(new ExternalMachineGun(new Tank("M1A1 Abrams", 1500, 1, 105), 30), 1500, 1); tankWithExternalTankAndMachineGun->writeDescription(); deleteTank(tank); std::cout<<"Remove tank witk external tank:"<<std::endl<<std::endl; deleteTank(tankWithExternalTank); std::cout<<"Remove tank witk external machine gun:"<<std::endl<<std::endl; deleteTank(tankWithExternalMachineGun); std::cout<<"Remove tank witk external machine gun and external fuel tank:"<<std::endl<<std::endl; deleteTank(tankWithExternalTankAndMachineGun); std::cin.get(); return 0; }

Wynik działania powyższego kodu:

Tank type: M1A1 Abrams
==================================
Maximum fuel level: 1900
FuelLevel: 1900
Cannon diameter: 105

Tank type: M1A1 Abrams
==================================
Maximum fuel level: 1500
FuelLevel: 1500
Cannon diameter: 105

External fuel tank
==================================
Maximum fuel level: 1500
FuelLevel: 1500

Tank type: M1A1 Abrams
==================================
Maximum fuel level: 1500
FuelLevel: 1500
Cannon diameter: 105

External machine gun
==================================
Diameter: 30

Tank type: M1A1 Abrams
==================================
Maximum fuel level: 1500
FuelLevel: 1500
Cannon diameter: 105

External machine gun
==================================
Diameter: 30

External fuel tank
==================================
Maximum fuel level: 1500
FuelLevel: 1500

Remove tank witk external tank:

Delete external fuel tank!
Delete external tank!

Remove tank witk external machine gun:

Delete external machine gun
Delete external tank!

Remove tank witk external machine gun and external fuel tank:

Delete external fuel tank!
Delete external tank!

Delete external machine gun
Delete external tank!
Strony powiązane
strony powiązane
  1. sourcemaking.com/design_patterns/decorator - strona opisująca wzorzec projektowy dekorator [En]
  2. pl.wikipedia.org - opis tego wzorca na stronie Wikipedii
Propozycje książek
tytuł: C++. Projektowanie oprogramowania. Zasady i wzorce projektowe autor: Klaus Iglberger

Tytuł:

C++. Projektowanie oprogramowania. Zasady i wzorce projektowe

Autor:

Klaus Iglberger

tytuł: Wzorce projektowe. Rusz głową! Tworzenie rozszerzalnego i łatwego w utrzymaniu oprogramowania obiektowego. Wydanie II autor: Eric Freeman, Elisabeth Robson

Tytuł:

Wzorce projektowe. Rusz głową! Tworzenie rozszerzalnego i łatwego w utrzymaniu oprogramowania obiektowego. Wydanie II

Autor:

Eric Freeman, Elisabeth Robson

tytuł: React 17. Wzorce projektowe i najlepsze praktyki. Projektowanie i rozwijanie nowoczesnych aplikacji internetowych. Wydanie III autor: Carlos Santana Roldán

Tytuł:

React 17. Wzorce projektowe i najlepsze praktyki. Projektowanie i rozwijanie nowoczesnych aplikacji internetowych. Wydanie III

Autor:

Carlos Santana Roldán

tytuł: Wzorce projektowe. Rusz głową! Tworzenie rozszerzalnego i łatwego w utrzymaniu oprogramowania obiektowego. Wydanie II autor: Eric Freeman, Elisabeth Robson

Tytuł:

Wzorce projektowe. Rusz głową! Tworzenie rozszerzalnego i łatwego w utrzymaniu oprogramowania obiektowego. Wydanie II

Autor:

Eric Freeman, Elisabeth Robson

tytuł: Wzorce projektowe w .NET Core 3. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F# autor: Dmitri Nesteruk

Tytuł:

Wzorce projektowe w .NET Core 3. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F#

Autor:

Dmitri Nesteruk

tytuł: Wzorce projektowe. Elementy oprogramowania obiektowego wielokrotnego użytku autor: Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

Tytuł:

Wzorce projektowe. Elementy oprogramowania obiektowego wielokrotnego użytku

Autor:

Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

tytuł: Projektowanie interfejsów., Sprawdzone wzorce projektowe. Wydanie III autor: Jenifer Tidwell, Charles Brewer, Aynne Valencia-Brooks

Tytuł:

Projektowanie interfejsów., Sprawdzone wzorce projektowe. Wydanie III

Autor:

Jenifer Tidwell, Charles Brewer, Aynne Valencia-Brooks

tytuł: Kubernetes. Wzorce projektowe. Komponenty wielokrotnego użycia do projektowania natywnych aplikacji chmurowych autor: Bilgin Ibryam,  Roland Huß

Tytuł:

Kubernetes. Wzorce projektowe. Komponenty wielokrotnego użycia do projektowania natywnych aplikacji chmurowych

Autor:

Bilgin Ibryam, Roland Huß

tytuł: Wzorce projektowe w .NET. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F# autor: Dmitri Nesteruk

Tytuł:

Wzorce projektowe w .NET. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F#

Autor:

Dmitri Nesteruk

tytuł: Programowanie zorientowane obiektowo. Wzorce projektowe. Wydanie II autor: Alan Shalloway, James R. Trott

Tytuł:

Programowanie zorientowane obiektowo. Wzorce projektowe. Wydanie II

Autor:

Alan Shalloway, James R. Trott

W związku z tym, że firma Helion nie wywiązuje się z swoich zobowiązań naliczania prowizji za każdą zakupioną książkę a kontakt z ową frmą jest nie możliwy autor strony zmuszony został do zablokowania linkowania książek. Za wszelkie niedogodności z tym związane z góry przepraszam i obiecuję włączenie linkowania gdy tylko sprawa zostanie wyjaśniona