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;
}

 


Связанные темы