- 1. Fazit
Diskussion. Frameworks sind Anwendungen (oder Subsysteme) mit „Erweiterungsplätzen“ darin. Jedes dieser Frameworks definiert das Framework, das Add-On und den Kontrollfluss für seinen Tätigkeitsbereich, und der Framework-Client kann: das Standardverhalten der Struktur "wie es ist" implementieren, die ausgewählten Fragmente der Struktur erweitern oder die ersetzen ausgewählte Fragmente.
Das Factory-Method-Pattern befasst sich mit dem Konzept der „Kreation“ im Kontext von Frameworks. In diesem Beispiel weiß das Framework, WANN ein neues Dokument erstellt werden soll, nicht WAS es ist. Der "Platzhalter" Application::CreateDocument() wurde vom Framework deklariert, und der Client muss für sein ;konkretes Dokument(e) "die Lücke füllen". Wenn der Client Application::NewDocument() anfordert, ruft das Framework anschließend die Methode MyApplication::CreateDocument() auf.
#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(); }
Fazit
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:
А диструктор переписать:
И для меня смысл фабричного метода, это когда ты через указатель базового класса работаешь с разными дочернеми классами.
Например в массиве: