Patterns. Паттерн Abstract Factory. Розв’язок задачі про складові комп’ютера

Паттерн Abstract Factory (Абстрактна фабрика класів). Розв’язок задачі про складові комп’ютера

У даній темі наведено приклад розв’язку задачі на побудову комп’ютера з використанням паттерну Abstract Factory. Розв’язок реалізований на мові C++ (консольний додаток).


Зміст


1. Умова задачі. Вимоги до класів

Реалізувати паттерн Abstract Factory для побудови комп’ютера з складових відповідно до рисунку 1.

Паттерн Abstract Factory. Розв'язок задачі про будову комп'ютера

Рисунок 1. Розв’язок задачі на побудову комп’ютера паттерном Abstract Factory. Діаграма класів

У програмі використати наступні класи та їх складові.

 

  1. Абстрактний клас IPCFactory. Служить інтерфейсом для класів OfficePcFactory та HomePcFactory.

У класі реалізувати абстрактні методи CreateBox(), CreateProcessor(), CreateMainBoard(), які відповідно повертають посилання (покажчики) на типи Box, Processor, MainBoard.

  1. Класи OfficePcFactory та HomePcFactory успадковані від класу IPCFactory. У цих класах реалізуються абстрактні методи CreateBox(), CreateProcessor(), CreateMainBoard().
  2. Абстрактні класи Box, Processor, MainBoard, які служать інтерфейсами відповідно для класів BlackBox, SilverBox, ProcessorIntel, ProcessorAMD, MainBoardIntel, MainBoardAMD.

У кожному з класів Box, Processor, MainBoard створюються наступні елементи:

  • внутрішнє приховане (private) поле info типу string, яке описує інформацію про системний блок, процесор чи материнську плату;
  • методи доступу Get(), Set() для поля info;
  • метод Print() – виводить інформацію про вміст поля info.
  1. Класи SilverBox та BlackBox описують системний блок відповідно сірого та чорного кольорів. Обидва класи реалізують інтерфейс Box.

У кожному з класів потрібно реалізувати як мінімум один конструктор, який буде викликати конструктор базового класу Box.

  1. Класи ProcessorIntel, ProcessorAMD – реалізують конкретні процесори. Класи успадковані з абстрактного класу Processor. У класах потрібно реалізувати конструктор, який викликає конструктор базового класу Processor.
  2. Класи MainBoardIntel та MainBoardAMD реалізують інтерфейс MainBoard. Кожен з класів повинен мати конструктор, який викликає конструктор базового класу MainBoard.
  3. Клас PcConfigurator – відповідає за конфігурування об’єкту типу PC заданим сімейством (офісна конфігурація або домашня конфігурація).

У класі потрібно реалізувати наступні елементи:

  • внутрішнє поле pcFactory – покажчик на абстрактний клас IPcFactory;
  • конструктор без параметрів – ініціалізує pcFactory нульовим значенням;
  • методи доступу GetPcFactory() та SetPcFactory(IPCFactory*);
  • метод GetPC(int numConfiguration). На основі номеру конфігурації (1-2) створює комп’ютер (клас PC) і повертає посилання (покажчик) на нього. При створенні комп’ютера використовується доступ до відповідної фабрики з допомогою поля pcFactory.
  1. Клас 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;
}

 


Споріднені теми