- 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:
А диструктор переписать:
И для меня смысл фабричного метода, это когда ты через указатель базового класса работаешь с разными дочернеми классами.
Например в массиве: