The Abstract Factory pattern (Abstract class factory). Solving the problem of computer components
This topic provides an example of solving a computer design problem using the Abstract Factory pattern. The solution is implemented in C++ (console application).
Contents
1. Task. Class requirements
Implement the Abstract Factory pattern to build a computer from components in accordance with Figure 1.
Figure 1. Solving the problem of building a computer using the Abstract Factory pattern. Class diagram
The program must use the following classes and their components.
- Abstract class IPCFactory. Serves as an interface to the OfficePcFactory and HomePcFactory classes.
In the class, implement abstract methods CreateBox(), CreateProcessor(), CreateMainBoard(), which respectively return a reference (pointers) to the types Box, Processor, MainBoard.
- The OfficePcFactory and HomePcFactory classes are inherited from the IPCFactory class. These classes implement the abstract methods CreateBox(), CreateProcessor(), CreateMainBoard().
- Abstract classes Box, Processor, MainBoard, which serve as interfaces for the classes BlackBox, SilverBox, ProcessorIntel, ProcessorAMD, MainBoardIntel, MainBoardAMD.
The following elements are created in each of the classes Box, Processor, MainBoard:
- internal hidden (private) field info of type string, describing information about the system unit, processor or motherboard;
- access methods Get(), Set() for the info field;
- Print() method – displays information about the contents of the info field.
- The SilverBox and BlackBox classes describe a system block that is gray and black, respectively. Both classes implement the Box interface.
Each class must implement at least one constructor that will call the constructor of the base class Box.
- The ProcessorIntel, ProcessorAMD classes implement specific processors. The classes are inherited from the abstract Processor class. The classes must implement a constructor that calls the constructor of the Processor base class.
- The MainBoardIntel and MainBoardAMD classes implement the MainBoard interface. Each class must have a constructor that calls the constructor of the MainBoard base class.
- The PcConfigurator class is responsible for configuring a PC type object with a given family (office configuration or home configuration).
The class must implement the following elements:
- internal field pcFactory – pointer to the abstract class IPcFactory;
- constructor without parameters – initializes pcFactory with a zero value;
- access methods GetPcFactory() and SetPcFactory(IPCFactory*);
- GetPC(int numConfiguration) method. Based on the configuration number (1-2), creates a computer (PC class) and returns a reference (pointer) to it. When creating a computer, the corresponding factory is accessed using the pcFactory field.
- The PC class is the result obtained from the GetPC() function of the PcConfigurator class. The class must implement the following elements:
- internal fields box, processor, mainBoard, which are pointers to the abstract classes Box, Processor, MainBoard;
- constructor without parameters – initializes internal fields with nullptr values;
- PC(Box*, Processor*, MainBoard*) constructor – initializes internal fields with the values of pointers to real objects of the classes Box, Processor, MainBoard, respectively);
- get/set type access methods: GetBox(), SetBox(Box*), GetProcessor(), SetProcessor(Processor*), GetMainBoard(), SetMainBoard(MainBoard*);
- Print() method – displays information about the current configuration.
⇑
2. Text of the program in C++
#include <iostream> using namespace std; // ----------------------------------------------- // Abstract components of a computer // System block - abstract class class Box abstract { private: string info; // information describing the system unit 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; } }; // Processor - abstract class class Processor abstract { private: string info; // Processor description 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; } }; // Motherboard 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; } }; // --------------------------------------------- // Classes of real devices. // Gray system unit. class SilverBox : public Box { public: SilverBox(string _info = "SilverBox") : Box(_info) { } }; // The system unit is black class BlackBox : public Box { public: BlackBox(string _info = "BlackBox") : Box(_info) { } }; // Processor from 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) { } }; // A class describing a computer and its components 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; } // Methods 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; } // Display the current computer configuration void Print(string msg) { cout << msg << endl; if (box) box->Print("Box:"); if (processor) processor->Print("Processor: "); if (mainBoard) mainBoard->Print("MainBoard: "); cout << "------------------------" << endl; } }; // The interface for creating the configuration // of the computer system unit is the factory interface class IPCFactory abstract { public: virtual Box* CreateBox() = 0; // pure virtual function virtual Processor* CreateProcessor() = 0; virtual MainBoard* CreateMainBoard() abstract; }; // Specific configurations. // "Home" computer configuration: // - system block - gray (SilverBox); // - processor Intel - (ProcessorIntel); // - motherboard Intel - (MainBoardIntel). class HomePcFactory : public IPCFactory { public: // create a system block Box* CreateBox() override { return new SilverBox(); } // create a processor Processor* CreateProcessor() override { return new ProcessorIntel(); } MainBoard* CreateMainBoard() override { return new MainBoardIntel(); } }; // Office configuration // - system block - black (BlackBox); // - processor AMD - (Processor AMD); // - motherboard - AMD - (MainBoard AMD). class OfficePcFactory : public IPCFactory { public: // Create a system block Box* CreateBox() override { return new BlackBox(); } // processor AMD Processor* CreateProcessor() override { return new ProcessorAMD(); } // motherboard AMD MainBoard* CreateMainBoard() override { return new MainBoardAMD(); } }; // PcConfigurator class - is responsible for configuring a PC object with a given family class PcConfigurator { IPCFactory* pcFactory; public: PcConfigurator() { pcFactory = nullptr; } IPCFactory* GetPCFactory() { return pcFactory; } void SetPCFactory(IPCFactory* pcCurrentFactory) { pcFactory = pcCurrentFactory; } // Get a computer based on configuration number // 1 - office configuration // 2 - home configuration PC* GetPC(int numConfiguration) { Box* box = nullptr; Processor* processor = nullptr; MainBoard* mainBoard = nullptr; if (numConfiguration == 1) { // office configuration pcFactory = new OfficePcFactory(); box = (BlackBox*)pcFactory->CreateBox(); processor = (ProcessorIntel*)pcFactory->CreateProcessor(); mainBoard = (MainBoardIntel*)pcFactory->CreateMainBoard(); } else { // home configuration pcFactory = new HomePcFactory(); box = (SilverBox*)pcFactory->CreateBox(); processor = (ProcessorAMD*)pcFactory->CreateProcessor(); mainBoard = (MainBoardAMD*)pcFactory->CreateMainBoard(); } return new PC(box, processor, mainBoard); } }; void main() { // 1. Enter the number of the configuration you want to receive int numConfiguration; cout << "numConfiguration = "; cin >> numConfiguration; // 2. Create a configurator PcConfigurator* configurator = new PcConfigurator(); // 3. Get a computer by configuration number PC* computer = configurator->GetPC(numConfiguration); // 4. Display information about the received configuration computer->Print("Computer"); // 5. Free memory 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; }
⇑
Related topics
- Builder pattern. Review and research. Implementation in C++
- Factory Method. Implementation of the structure in C++
- Prototype. Implementation of structure in C++
- Singleton pattern. Overview. Features of use. Implementation in C++
⇑