Паттерн Abstract Factory (Абстрактна фабрика класів). Розв’язок задачі про складові комп’ютера
У даній темі наведено приклад розв’язку задачі на побудову комп’ютера з використанням паттерну Abstract Factory. Розв’язок реалізований на мові C++ (консольний додаток).
Зміст
1. Умова задачі. Вимоги до класів
Реалізувати паттерн Abstract Factory для побудови комп’ютера з складових відповідно до рисунку 1.
Рисунок 1. Розв’язок задачі на побудову комп’ютера паттерном Abstract Factory. Діаграма класів
У програмі використати наступні класи та їх складові.
- Абстрактний клас IPCFactory. Служить інтерфейсом для класів OfficePcFactory та HomePcFactory.
У класі реалізувати абстрактні методи CreateBox(), CreateProcessor(), CreateMainBoard(), які відповідно повертають посилання (покажчики) на типи Box, Processor, MainBoard.
- Класи OfficePcFactory та HomePcFactory успадковані від класу IPCFactory. У цих класах реалізуються абстрактні методи CreateBox(), CreateProcessor(), CreateMainBoard().
- Абстрактні класи Box, Processor, MainBoard, які служать інтерфейсами відповідно для класів BlackBox, SilverBox, ProcessorIntel, ProcessorAMD, MainBoardIntel, MainBoardAMD.
У кожному з класів Box, Processor, MainBoard створюються наступні елементи:
- внутрішнє приховане (private) поле info типу string, яке описує інформацію про системний блок, процесор чи материнську плату;
- методи доступу Get(), Set() для поля info;
- метод Print() – виводить інформацію про вміст поля info.
- Класи SilverBox та BlackBox описують системний блок відповідно сірого та чорного кольорів. Обидва класи реалізують інтерфейс Box.
У кожному з класів потрібно реалізувати як мінімум один конструктор, який буде викликати конструктор базового класу Box.
- Класи ProcessorIntel, ProcessorAMD – реалізують конкретні процесори. Класи успадковані з абстрактного класу Processor. У класах потрібно реалізувати конструктор, який викликає конструктор базового класу Processor.
- Класи MainBoardIntel та MainBoardAMD реалізують інтерфейс MainBoard. Кожен з класів повинен мати конструктор, який викликає конструктор базового класу MainBoard.
- Клас PcConfigurator – відповідає за конфігурування об’єкту типу PC заданим сімейством (офісна конфігурація або домашня конфігурація).
У класі потрібно реалізувати наступні елементи:
- внутрішнє поле pcFactory – покажчик на абстрактний клас IPcFactory;
- конструктор без параметрів – ініціалізує pcFactory нульовим значенням;
- методи доступу GetPcFactory() та SetPcFactory(IPCFactory*);
- метод GetPC(int numConfiguration). На основі номеру конфігурації (1-2) створює комп’ютер (клас PC) і повертає посилання (покажчик) на нього. При створенні комп’ютера використовується доступ до відповідної фабрики з допомогою поля pcFactory.
- Клас PC є результатом, який отримується з функції GetPC() класу PcConfigurator. У класі потрібно реалізувати наступні елементи:
- внутрішні поля box, processor, mainBoard, які є покажчиками на абстрактні класи Box, Processor, MainBoard;
- конструктор без параметрів – ініціалізує внутрішні поля значеннями nullptr;
- конструктор PC(Box*, Processor*, MainBoard*) – ініціалізує внутрішні поля значеннями покажчиків на реальні об’єкти відповідно класів Box, Processor, MainBoard);
- методи доступу типу get/set: GetBox(), SetBox(Box*), GetProcessor(), SetProcessor(Processor*), GetMainBoard(), SetMainBoard(MainBoard*);
- метод Print() – виводить інформацію про поточну конфігурацію.
⇑
2. Текст програми на мові C++
#include <iostream> using namespace std; // ----------------------------------------------- // Абстрактні складові комп'ютера // Системний блок - абстрактний клас class Box abstract { private: string info; // інформація, що описує системний блок public: Box(string _info = "Box") : info(_info) { } string Get() { return info; } void Set(string info) { this->info = info; } void Print(string msg) { cout << msg << " => " << info << endl; } }; // Процесор - абстрактний клас class Processor abstract { private: string info; // Опис процесора public: Processor(string info = "Processor") : info(info) { } string Get() { return info; } void Set(string info) { this->info = info; } void Print(string msg) { cout << msg << " => " << info << endl; } }; // Материнська плата class MainBoard abstract { private: string info; public: MainBoard(string info = "MainBoard") : info(info) { } string Get() { return info; } void Set(string info) { this->info = info; } void Print(string msg) { cout << msg << " => " << info << endl; } }; // --------------------------------------------- // Класи реальних пристроїв // Сірий системний блок class SilverBox : public Box { public: SilverBox(string _info = "SilverBox") : Box(_info) { } }; // Системний блок чорного кольору class BlackBox : public Box { public: BlackBox(string _info = "BlackBox") : Box(_info) { } }; // Процесор фірми Intel class ProcessorIntel : public Processor { public: ProcessorIntel(string _info = "Processor Intel") : Processor(_info) { } }; class ProcessorAMD : public Processor { public: ProcessorAMD(string _info = "Processor AMD") : Processor(_info) { } }; class MainBoardIntel : public MainBoard { public: MainBoardIntel(string _info = "MainBoard Intel") : MainBoard(_info) { } }; class MainBoardAMD : public MainBoard { public: MainBoardAMD(string _info = "MainBoard AMD") : MainBoard(_info) { } }; // Клас з описом комп'ютера та його складових class PC { private: Box* box; Processor* processor; MainBoard* mainBoard; public: PC() { box = nullptr; processor = nullptr; mainBoard = nullptr; } PC(Box* box, Processor* processor, MainBoard* mainBoard) { this->box = box; this->processor = processor; this->mainBoard = mainBoard; } // Методи типу Get(), Set() Box* GetBox() { return box; } void SetBox(Box* _box) { box = _box; } Processor* GetProcessor() { return processor; } void SetProcessor(Processor* _processor) { processor = _processor; } MainBoard* GetMainBoard() { return mainBoard; } void SetMainBoard(MainBoard* _mainBoard) { mainBoard = _mainBoard; } // Вивести поточну конфігурацію комп'ютера void Print(string msg) { cout << msg << endl; if (box) box->Print("Box:"); if (processor) processor->Print("Processor: "); if (mainBoard) mainBoard->Print("MainBoard: "); cout << "------------------------" << endl; } }; // Інтерфейс зі створення конфігурації // системного блоку комп'ютера - це є інтерфейс фабрики class IPCFactory abstract { public: virtual Box* CreateBox() = 0; // чисто віртуальна ф-я virtual Processor* CreateProcessor() = 0; virtual MainBoard* CreateMainBoard() abstract; }; // Конкретні конфігурації // "Домашня" конфігурація комп'ютера: // - системний блок - сірий (SilverBox); // - процесор Intel - (ProcessorIntel); // - материнська плата Intel - (MainBoardIntel). class HomePcFactory : public IPCFactory { public: // створити системний блок Box* CreateBox() override { return new SilverBox(); } // створити процесор Processor* CreateProcessor() override { return new ProcessorIntel(); } MainBoard* CreateMainBoard() override { return new MainBoardIntel(); } }; // Офісна конфігурація // - системний блок - чорний (BlackBox); // - процесор AMD - (Processor AMD); // - материнська плата - AMD - (MainBoard AMD). class OfficePcFactory : public IPCFactory { public: // Створити системний блок Box* CreateBox() override { return new BlackBox(); } // процесор AMD Processor* CreateProcessor() override { return new ProcessorAMD(); } // материнська плата AMD MainBoard* CreateMainBoard() override { return new MainBoardAMD(); } }; // Клас PcConfigurator - відповідає за конфігурування // об'єкту PC заданим сімейством class PcConfigurator { IPCFactory* pcFactory; public: PcConfigurator() { pcFactory = nullptr; } IPCFactory* GetPCFactory() { return pcFactory; } void SetPCFactory(IPCFactory* pcCurrentFactory) { pcFactory = pcCurrentFactory; } // Отримати комп'ютер на основі номеру конфігурації // 1 - офісна конфігурація // 2 - домашня конфігурація PC* GetPC(int numConfiguration) { Box* box = nullptr; Processor* processor = nullptr; MainBoard* mainBoard = nullptr; if (numConfiguration == 1) { // Офісна конфігурація pcFactory = new OfficePcFactory(); box = (BlackBox*)pcFactory->CreateBox(); processor = (ProcessorIntel*)pcFactory->CreateProcessor(); mainBoard = (MainBoardIntel*)pcFactory->CreateMainBoard(); } else { // Домашня конфігурація pcFactory = new HomePcFactory(); box = (SilverBox*)pcFactory->CreateBox(); processor = (ProcessorAMD*)pcFactory->CreateProcessor(); mainBoard = (MainBoardAMD*)pcFactory->CreateMainBoard(); } return new PC(box, processor, mainBoard); } }; void main() { // 1. Ввести номер конфігурації, яку потрібно отримати int numConfiguration; cout << "numConfiguration = "; cin >> numConfiguration; // 2. Створити конфігуратора PcConfigurator* configurator = new PcConfigurator(); // 3. Отримати комп'ютер на основі номеру конфігурації PC* computer = configurator->GetPC(numConfiguration); // 4. Вивести інформацію про отриману конфігурацію computer->Print("Computer"); // 5. Звільнити пам'ять Box* box = computer->GetBox(); Processor* processor = computer->GetProcessor(); MainBoard* mainBoard = computer->GetMainBoard(); if (box) delete box; if (processor) delete processor; if (mainBoard) delete mainBoard; if (configurator) delete configurator; if (computer) delete computer; }
⇑
Споріднені теми
- Огляд та дослідження. Реалізація на C++
- Factory Method. Реалізація структури на C++
- Паттерн Prototype. Реалізація структури на C++
- Паттерн Singleton. Огляд. Особливості застосування. Реалізація на C++
⇑