Шаблоны проектирования
Шаблоны проектирования Abstract factory (Абстрактная фабрика) Abstract factory (Абстрактная фабрика) -- шаблон проектирования, позволяющий изменять поведение системы, варьируя создаваемые объекты, при этом сохраняя интерфейсы. Он позволяет создавать целые группы взаимосвязанных объектов, которые, будучи созданными одной фабрикой, реализуют общее поведение. Шаблон реализуется созданием абстрактного класса Factory, который представляет собой интерфейс для создания компонентов системы (например, для оконного интерфейса, он может создавать окна и кнопки). Затем пишутся наследующиеся от него классы, реализующие этот интерфейс. Цель Предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов Плюсы изолирует конкретные классы; упрощает замену семейств продуктов; гарантирует сочетаемость продуктов. Минусы сложно добавить поддержку нового вида продуктов. Применимость Система не должна зависеть от того, как создаются, компонуются и представляются входящие в нее объекты; Входящие в семейство взаимосвязанные объекты должны использоваться вместе и вам необходимо обеспечить выполнение этого ограничения; Система должна конфигурироваться одним из семейств составляющих ее объектов; требуется предоставить библиотеку объектов, раскрывая только их интерфейсы, но не реализацию. Пример C++ #include <iostream> // AbstractProductA class ICar { public: virtual void info() = 0; }; // ConcreteProductA1 class Ford : public ICar { public: virtual void info() { std::cout << "Ford" << std::endl; } }; //ConcreteProductA2 class Toyota : public ICar { public: virtual void info() { std::cout << "Toyota" << std::endl; } }; // AbstractProductB class IEngine { public: virtual void getPower() = 0; }; // ConcreteProductB1 class FordEngine : public IEngine { public: virtual void getPower() { std::cout << "Ford Engine 4.4" << std::endl; } }; //ConcreteProductB2 class ToyotaEngine : public IEngine { public: virtual void getPower() { std::cout << "Toyota Engine 3.2" << std::endl; } }; // AbstractFactory class CarFactory { public: ICar* getNewCar() { return createCar(); } IEngine* getNewEngine() { return createEngine(); } protected: virtual ICar*createCar()= 0; virtual IEngine*createEngine()= 0; }; // ConcreteFactory1 class FordFactory : public CarFactory { protected: // from CarFactory virtual ICar* createCar() { return new Ford(); } virtual IEngine* createEngine() { return new FordEngine(); } }; // ConcreteFactory2 class ToyotaFactory : public CarFactory { protected: // from CarFactory virtual ICar* createCar() { return new Toyota(); } virtual IEngine* createEngine() { return new ToyotaEngine(); } }; int main() { CarFactory* curFactory= NULL; ICar*myCar= NULL; IEngine*myEngine= NULL; ToyotaFactorytoyotaFactory; FordFactoryfordFactory; curFactory = &toyotaFactory; myCar = curFactory->getNewCar(); myCar->info(); myEngine = curFactory->getNewEngine(); myEngine->getPower(); delete myCar; delete myEngine; curFactory = &fordFactory; myCar = curFactory->getNewCar(); myCar->info(); myEngine = curFactory->getNewEngine(); myEngine->getPower(); delete myCar; delete myEngine; return 0; } Builder (Строитель) -- шаблон проектирования, порождающий объекты. Цель Отделяет конструирование сложного объекта от его представления, так что в результате одного и того же процесса конструирования могут получаться разные представления. Плюсы позволяет изменять внутреннее представление продукта; изолирует код, реализующий конструирование и представление; дает более тонкий контроль над процессом конструирования. Применение алгоритм создания сложного объекта не должен зависеть от того, из каких частей состоит объект и как они стыкуются между собой; процесс конструирования должен обеспечивать различные представления конструируемого объекта.
Пример на C++ #include <iostream> #include <memory> #include <string> // Product class Pizza { private: std::string dough; std::string sauce; std::string topping; public: Pizza() { } ~Pizza() { } void SetDough(const std::string& d) { dough = d; }; void SetSauce(const std::string& s) { sauce = s; }; void SetTopping(const std::string& t) { topping = t; } void ShowPizza() { std::cout << " Yummy !!!" << std::endl << "Pizza with Dough as " << dough << ", Sauce as " << sauce << " and Topping as " << topping << " !!! " << std::endl; } }; // Abstract Builder class PizzaBuilder { protected: std::auto_ptr<Pizza> pizza; public: PizzaBuilder() {} virtual ~PizzaBuilder() {} std::auto_ptr<Pizza> GetPizza() { return pizza; } void createNewPizzaProduct() { pizza.reset (new Pizza); } virtual void buildDough()=0; virtual void buildSauce()=0; virtual void buildTopping()=0; }; // ConcreteBuilder class HawaiianPizzaBuilder : public PizzaBuilder { public: HawaiianPizzaBuilder() : PizzaBuilder() {} ~HawaiianPizzaBuilder(){} void buildDough() { pizza->SetDough("cross"); } void buildSauce() { pizza->SetSauce("mild"); } void buildTopping() { pizza->SetTopping("ham and pineapple"); } }; // ConcreteBuilder class SpicyPizzaBuilder : public PizzaBuilder { public: SpicyPizzaBuilder() : PizzaBuilder() {} ~SpicyPizzaBuilder() {} void buildDough() { pizza->SetDough("pan baked"); } void buildSauce() { pizza->SetSauce("hot"); } void buildTopping() { pizza->SetTopping("pepperoni and salami"); } }; // Director class Waiter { private: PizzaBuilder* pizzaBuilder; public: Waiter() : pizzaBuilder(NULL) {} ~Waiter() { } void SetPizzaBuilder(PizzaBuilder* b) { pizzaBuilder = b; } std::auto_ptr<Pizza> GetPizza() { return pizzaBuilder->GetPizza(); } void ConstructPizza() { pizzaBuilder->createNewPizzaProduct(); pizzaBuilder->buildDough(); pizzaBuilder->buildSauce(); pizzaBuilder->buildTopping(); } }; // Клиент заказывает две пиццы. int main() { Waiter waiter; HawaiianPizzaBuilder hawaiianPizzaBuilder; waiter.SetPizzaBuilder (&hawaiianPizzaBuilder); waiter.ConstructPizza(); std::auto_ptr<Pizza> pizza = waiter.GetPizza(); pizza->ShowPizza(); SpicyPizzaBuilder spicyPizzaBuilder; waiter.SetPizzaBuilder(&spicyPizzaBuilder); waiter.ConstructPizza(); pizza = waiter.GetPizza(); pizza->ShowPizza(); return EXIT_SUCCESS; } Factory Method (Фабричный метод) -- шаблон проектирования, реализующий идею "виртуального конструктора", то есть создания объектов без явного указания их типа. Относится к порождающим шаблонам проектирования. Цель Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанциировать. Фабричный метод позволяет классу делегировать создание подклассам. Используется, когда: классу заранее неизвестно, объекты каких подклассов ему нужно создавать. класс спроектирован так, чтобы объекты, которые он создаёт, специфицировались подклассами. класс делегирует свои обязанности одному из нескольких вспомогательных подклассов, и планируется локализовать знание о том, какой класс принимает эти обязанности на себя. Плюсы позволяет сделать код создания объектов более универсальным, не привязываясь к конкретным классам (ConcreteProduct), а оперируя лишь общим интерфейсом (Product); позволяет установить связь между параллельными иерархиями классов. Минусы необходимость создавать наследника Creator для каждого нового типа продукта (ConcreteProduct). · Product - продукт o определяет интерфейс объектов, создаваемых абстрактным методом; · ConcreteProduct - конкретный продукт o реализует интерфейс Product; · Creator - создатель o объявляет фабричный метод, который возвращает объект типа Product. Может также содержать реализацию этого метода "по умолчанию"; o может вызывать фабричный метод для создания объекта типа Product; · ConcreteCreator - конкретный создатель o переопределяет фабричный метод таким образом, чтобы он создавал и возвращал объект класса ConcreteProduct. Пример на C++ #include<iostream> #include<string> using namespace std; // "Product" class Product{ public: virtual string getName() = 0; }; // "ConcreteProductA" class ConcreteProductA : public Product{ public: string getName(){ return "ConcreteProductA"; } }; // "ConcreteProductB" class ConcreteProductB : public Product{ public: string getName(){ return "ConcreteProductB"; } };
Страницы: 1, 2
|