- 1. Вывод
Обсуждение. Фреймфорки представляют собой приложения (или подсистемы) с «местами расширений» в них. Каждый такой фреймворк определяет инфраструктуру, надстройку и поток управления для своей области деятельности, а клиент фреймворка может: осуществлять поведение структуры по умолчанию «как есть», расширить выделенные фрагменты структуры или заменить выбранные фрагменты.
В шаблоне 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
У метода NewDocument забыли указать возвращаемый тип (void). Я бы сделал бы сразу с проверочкой. И то что нет освобождение памяти, наверняка для обучающего материала это не хорошо.
И вот по освобождению памяти у меня вопрос - как лучше сделать освобождение памяти?
1. Можно сделать как я показал выше (реализовать диструктор ~Application()).
2. Так как память выделялась в MyApplication, то было бы не плохо если бы она и освобождала память, тогда нужно добавить метод DeleteDocument:
А диструктор переписать:
И для меня смысл фабричного метода, это когда ты через указатель базового класса работаешь с разными дочернеми классами.
Например в массиве: