Evgenii Legotckoi
Evgenii Legotckoi24 сентября 2018 г. 8:23

Пример - Фабричный метод на C++

Содержание

Обсуждение. Фреймфорки представляют собой приложения (или подсистемы) с «местами расширений» в них. Каждый такой фреймворк определяет инфраструктуру, надстройку и поток управления для своей области деятельности, а клиент фреймворка может: осуществлять поведение структуры по умолчанию «как есть», расширить выделенные фрагменты структуры или заменить выбранные фрагменты.

В шаблоне Factory Method рассматривается понятие «создание» в контексте фреймворков. В этом примере структура знает, КОГДА должен быть создан новый документ, а не КАКОЙ это документ. «Заполнитель» Application::CreateDocument() был объявлен фреймворком, и клиент должен «заполнить пробел» для своего ;конкретного документа(ов). Затем, когда клиент запрашивает Application::NewDocument(), фреймворк впоследствии вызывает метод MyApplication::CreateDocument().


#include <iostream.h>

/* Abstract base class declared by framework */
class Document
{
  public:
    Document(char *fn)
    {
        strcpy(name, fn);
    }
    virtual void Open() = 0;
    virtual void Close() = 0;
    char *GetName()
    {
        return name;
    }
  private:
    char name[20];
};

/* Concrete derived class defined by client */
class MyDocument: public Document
{
  public:
    MyDocument(char *fn): Document(fn){}
    void Open()
    {
        cout << "   MyDocument: Open()" << endl;
    }
    void Close()
    {
        cout << "   MyDocument: Close()" << endl;
    }
};

/* Framework declaration */
class Application
{
  public:
    Application(): _index(0)
    {
        cout << "Application: ctor" << endl;
    }
    /* The client will call this "entry point" of the framework */
    NewDocument(char *name)
    {
        cout << "Application: NewDocument()" << endl;
        /* Framework calls the "hole" reserved for client customization */
        _docs[_index] = CreateDocument(name);
        _docs[_index++]->Open();
    }
    void OpenDocument(){}
    void ReportDocs();
    /* Framework declares a "hole" for the client to customize */
    virtual Document *CreateDocument(char*) = 0;
  private:
    int _index;
    /* Framework uses Document's base class */
    Document *_docs[10];
};

void Application::ReportDocs()
{
  cout << "Application: ReportDocs()" << endl;
  for (int i = 0; i < _index; i++)
    cout << "   " << _docs[i]->GetName() << endl;
}

/* Customization of framework defined by client */
class MyApplication: public Application
{
  public:
    MyApplication()
    {
        cout << "MyApplication: ctor" << endl;
    }
    /* Client defines Framework's "hole" */
    Document *CreateDocument(char *fn)
    {
        cout << "   MyApplication: CreateDocument()" << endl;
        return new MyDocument(fn);
    }
};

int main()
{
  /* Client's customization of the Framework */
  MyApplication myApp;

  myApp.NewDocument("foo");
  myApp.NewDocument("bar");
  myApp.ReportDocs();
}

Вывод

Application: ctor
MyApplication: ctor
Application: NewDocument()
   MyApplication: CreateDocument()
   MyDocument: Open()
Application: NewDocument()
   MyApplication: CreateDocument()
   MyDocument: Open()
Application: ReportDocs()
   foo
   bar
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

f
  • 9 августа 2019 г. 10:48
  • (ред.)

У метода NewDocument забыли указать возвращаемый тип (void). Я бы сделал бы сразу с проверочкой. И то что нет освобождение памяти, наверняка для обучающего материала это не хорошо.

    bool NewDocument(char *name)
    {
        if (_index >= 10) { return false; }
        cout << "Application: NewDocument()" << endl;
        /* Framework calls the "hole" reserved for client customization */

        _docs[_index] = CreateDocument(name);
        _docs[_index++]->Open();
        return true;
    }
    ~Application()
    {
        for (int i = _index - 1; i >= 0; --i) {
            delete _docs[i];
        }
    }

И вот по освобождению памяти у меня вопрос - как лучше сделать освобождение памяти?
1. Можно сделать как я показал выше (реализовать диструктор ~Application()).
2. Так как память выделялась в MyApplication, то было бы не плохо если бы она и освобождала память, тогда нужно добавить метод DeleteDocument:

    void DeleteDocument(Document *doc)
    {
        delete doc;
    }

А диструктор переписать:

    ~Application()
    {
        for (int i = _index - 1; i >= 0; --i) {
            DeleteDocument(_docs[i]);
        }
    }

И для меня смысл фабричного метода, это когда ты через указатель базового класса работаешь с разными дочернеми классами.
Например в массиве:

class Document {};

class Document1 : public Document {};

class Document2 : public Document {};

void main() {
    const int TYPE1 = 1;
    const int TYPE2 = 2;
    Document *m[10];
    for (int i = 0; i < 10; ++i) {
        int type;
        cin >> type;
        if (type == TYPE1) { m[i] = new Document1(); }
        else { m[i] = new Document2(); }
    }
    // some code
}

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:50баллов,
  • Очки рейтинга-4
m
  • molni99
  • 26 октября 2024 г. 8:37

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80баллов,
  • Очки рейтинга4
m
  • molni99
  • 26 октября 2024 г. 8:29

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:20баллов,
  • Очки рейтинга-10
Последние комментарии
i
innorwall14 ноября 2024 г. 19:42
Как Копировать Файлы в Linux If only females relatives with DZ offspring were considered these percentages were 23 order priligy online uk
i
innorwall14 ноября 2024 г. 17:09
Qt/C++ - Урок 068. Hello World с использованием системы сборки CMAKE в CLion ditropan pristiq dosing With the Yankees leading, 4 3, Rivera jogged in from the bullpen to a standing ovation as he prepared for his final appearance in Chicago buy priligy pakistan
i
innorwall14 ноября 2024 г. 12:05
EVILEG-CORE. Использование Google reCAPTCHA 2001; 98 29 34 priligy buy
i
innorwall14 ноября 2024 г. 12:00
PyQt5 - Урок 007. Работаем с QML QtQuick (Сигналы и слоты) priligy 30mg Am J Obstet Gynecol 171 1488 505
Сейчас обсуждают на форуме
i
innorwall14 ноября 2024 г. 11:39
добавить qlineseries в функции priligy amazon canada 93 GREB1 protein GREB1 AB011147 6
i
innorwall11 ноября 2024 г. 18:55
Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
9
9Anonim25 октября 2024 г. 16:10
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…
ИМ
Игорь Максимов3 октября 2024 г. 11:05
Реализация навигации по разделам Спасибо Евгений!

Следите за нами в социальных сетях