diff --git a/README.md b/README.md index e69de29..103f313 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,6 @@ +Паттерн "Декоратор" динамически наделяет объект новыми возможностями и является гибкой альтернативой субклассированию в области расширения функциональности (поведения). + +Типы декораторов соответствуют типам декорируемых компонентов (соответствие достигается посредством наследования или реализации интерфейса). Декораторы изменяют поведение компонентов, добавляя новую функциональность до и (или) после (или даже вместо) вызовов методов компонентов. Компонент может декорироваться любым количеством декораторов. Декораторы обычно прозрачны для клиентов компонента (если клиентский код не зависит от конкретного типа компонента). + +*Принцип:* +- Согласно принципу открытости/закрытости системы должны проектироваться так, чтобы их закрытые компоненты были изолированы от новых расширений. \ No newline at end of file diff --git a/lesson_3/Beverage.hpp b/lesson_3/Beverage.hpp new file mode 100644 index 0000000..b8d93aa --- /dev/null +++ b/lesson_3/Beverage.hpp @@ -0,0 +1,37 @@ +/* + * Beverage.hpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#pragma once + +#include + +class Beverage +{ +public: + enum Size {TALL, GRANDE, VENTI}; + Size size = Size::TALL; + std::string description = "Unknown Beverage"; + + virtual std::string getDescription() const + { + return description; + } + + virtual void setSize(Size size) + { + this->size = size; + } + + virtual Size getSize() const + { + return size; + } + + virtual double cost() const = 0; + + virtual ~Beverage() {} +}; diff --git a/lesson_3/CondimentDecorator.hpp b/lesson_3/CondimentDecorator.hpp new file mode 100644 index 0000000..1023316 --- /dev/null +++ b/lesson_3/CondimentDecorator.hpp @@ -0,0 +1,26 @@ +/* + * CondimentDecorator.hpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#pragma once + +#include "Beverage.hpp" +#include + +class CondimentDecorator: public Beverage +{ +public: + Beverage *beverage; + + CondimentDecorator(Beverage *beverage): beverage(beverage) {} + + virtual std::string getDescription() const = 0; + + ~CondimentDecorator() + { + delete beverage; + } +}; diff --git a/lesson_3/DarkRoast.hpp b/lesson_3/DarkRoast.hpp new file mode 100644 index 0000000..8267401 --- /dev/null +++ b/lesson_3/DarkRoast.hpp @@ -0,0 +1,24 @@ +/* + * DarkRoast.hpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#pragma once + +#include "Beverage.hpp" + +class DarkRoast: public Beverage +{ +public: + DarkRoast() + { + description = "Dark Roast"; + } + + double cost() const override + { + return 0.99; + } +}; diff --git a/lesson_3/Decaf.hpp b/lesson_3/Decaf.hpp new file mode 100644 index 0000000..c93b568 --- /dev/null +++ b/lesson_3/Decaf.hpp @@ -0,0 +1,24 @@ +/* + * Decaf.hpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#pragma once + +#include "Beverage.hpp" + +class Decaf: public Beverage +{ +public: + Decaf() + { + description = "Decaf"; + } + + double cost() const override + { + return 1.05; + } +}; diff --git a/lesson_3/Espresso.hpp b/lesson_3/Espresso.hpp new file mode 100644 index 0000000..f9a20da --- /dev/null +++ b/lesson_3/Espresso.hpp @@ -0,0 +1,24 @@ +/* + * Espresso.hpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#pragma once + +#include "Beverage.hpp" + +class Espresso: public Beverage +{ +public: + Espresso() + { + description = "Espresso"; + } + + double cost() const override + { + return 1.99; + } +}; diff --git a/lesson_3/HouseBlend.hpp b/lesson_3/HouseBlend.hpp new file mode 100644 index 0000000..b3047d9 --- /dev/null +++ b/lesson_3/HouseBlend.hpp @@ -0,0 +1,24 @@ +/* + * HouseBlend.hpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#pragma once + +#include "Beverage.hpp" + +class HouseBlend: public Beverage +{ +public: + HouseBlend() + { + description = "House Blend"; + } + + double cost() const override + { + return 0.89; + } +}; diff --git a/lesson_3/Milk.hpp b/lesson_3/Milk.hpp new file mode 100644 index 0000000..26fbe75 --- /dev/null +++ b/lesson_3/Milk.hpp @@ -0,0 +1,26 @@ +/* + * Milk.hpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#pragma once + +#include "CondimentDecorator.hpp" + +class Milk: public CondimentDecorator +{ +public: + Milk(Beverage *beverage): CondimentDecorator(beverage) {} + + std::string getDescription() const override + { + return beverage->getDescription() + ", Milk"; + } + + double cost() const override + { + return 0.10 + beverage->cost(); + } +}; diff --git a/lesson_3/Mocha.hpp b/lesson_3/Mocha.hpp new file mode 100644 index 0000000..771e3cf --- /dev/null +++ b/lesson_3/Mocha.hpp @@ -0,0 +1,26 @@ +/* + * Mocha.hpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#pragma once + +#include "CondimentDecorator.hpp" + +class Mocha: public CondimentDecorator +{ +public: + Mocha(Beverage *beverage): CondimentDecorator(beverage) {} + + std::string getDescription() const override + { + return beverage->getDescription() + ", Mocha"; + } + + double cost() const override + { + return 0.20 + beverage->cost(); + } +}; diff --git a/lesson_3/Soy.hpp b/lesson_3/Soy.hpp new file mode 100644 index 0000000..a645f73 --- /dev/null +++ b/lesson_3/Soy.hpp @@ -0,0 +1,41 @@ +/* + * Soy.hpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#pragma once + +#include "CondimentDecorator.hpp" + +class Soy: public CondimentDecorator +{ +public: + Soy(Beverage *beverage) : CondimentDecorator(beverage) {} + + std::string getDescription() const override + { + return beverage->getDescription() + ", Soy"; + } + + double cost() const override + { + double cost = 0.15 + beverage->cost(); + + if (beverage->getSize() == Size::TALL) + { + cost += .10; + } + else if (beverage->getSize() == Size::GRANDE) + { + cost += .15; + } + else if (beverage->getSize() == Size::VENTI) + { + cost += .20; + } + + return cost; + } +}; diff --git a/lesson_3/Whip.hpp b/lesson_3/Whip.hpp new file mode 100644 index 0000000..76c5ac3 --- /dev/null +++ b/lesson_3/Whip.hpp @@ -0,0 +1,26 @@ +/* + * Whip.hpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#pragma once + +#include "CondimentDecorator.hpp" + +class Whip: public CondimentDecorator +{ +public: + Whip(Beverage *beverage): CondimentDecorator(beverage) {} + + std::string getDescription() const override + { + return beverage->getDescription() + ", Whip"; + } + + double cost() const override + { + return 0.10 + beverage->cost(); + } +}; diff --git a/lesson_3/main.cpp b/lesson_3/main.cpp new file mode 100644 index 0000000..6cd0a6c --- /dev/null +++ b/lesson_3/main.cpp @@ -0,0 +1,48 @@ +/* + * main.cpp + * + * Created on: 1 нояб. 2021 г. + * Author: alexander + */ + +#include "Beverage.hpp" +#include "Espresso.hpp" +#include "DarkRoast.hpp" +#include "Mocha.hpp" +#include "Whip.hpp" +#include "HouseBlend.hpp" +#include "Soy.hpp" +#include "Decaf.hpp" +#include "Milk.hpp" +#include + +int main() +{ + Beverage *beverage = new Espresso(); + std::cout << beverage->getDescription() << " $" << beverage->cost() << std::endl; + + Beverage *beverage2 = new DarkRoast(); + beverage2 = new Mocha(beverage2); + beverage2 = new Mocha(beverage2); + beverage2 = new Whip(beverage2); + std::cout << beverage2->getDescription() << " $" << beverage2->cost() << std::endl; + + Beverage *beverage3 = new HouseBlend(); + beverage3->setSize(Beverage::Size::VENTI); + beverage3 = new Soy(beverage3); + beverage3 = new Mocha(beverage3); + beverage3 = new Whip(beverage3); + std::cout << beverage3->getDescription() << " $" << beverage3->cost() << std::endl; + + Beverage *beverage4 = new Decaf(); + beverage4 = new Mocha(beverage4); + beverage4 = new Mocha(beverage4); + beverage4 = new Milk(beverage4); + std::cout << beverage4->getDescription() << " $" << beverage4->cost() << std::endl; + + delete beverage; + delete beverage2; + delete beverage3; + + return 0; +}