Verstehe die Unterschiede in den Motivationen:
Angenommen, Sie erstellen ein Tool, in dem Sie Objekte haben, und eine konkrete Implementierung der Wechselbeziehungen der Objekte. Da Sie Variationen in den Objekten vorhersehen, haben Sie eine Indirektion erstellt, indem Sie die Verantwortung für das Erstellen von Varianten der Objekte einem anderen Objekt zugewiesen haben ( wir nennen es abstrakte Factory ). Diese Abstraktion hat großen Nutzen, da Sie zukünftige Erweiterungen vorhersehen, die Varianten dieser Objekte benötigen.
Eine weitere faszinierende Motivation in diesem Gedankengang ist ein Fall, in dem jedes oder keines der Objekte aus der gesamten Gruppe eine entsprechende Variante aufweist. Unter bestimmten Bedingungen wird eine der Varianten verwendet, und in jedem Fall müssen alle Objekte dieselbe Variante haben. Dies ist möglicherweise etwas kontraintuitiv zu verstehen, da wir häufig der Meinung sind, dass der konkrete Implementierungscode niemals brechen sollte, solange die Varianten eines Objekts einem gemeinsamen einheitlichen Vertrag folgen ( Schnittstelle im weiteren Sinne ). Die faszinierende Tatsache hierbei ist, dass dies nicht immer der Fall ist, insbesondere wenn das erwartete Verhalten nicht durch einen Programmiervertrag modelliert werden kann.
Ein einfaches ( die Idee von GoF entlehnt ) ist eine beliebige GUI-Anwendung, beispielsweise ein virtueller Monitor, der das Erscheinungsbild von MS, Mac oder Fedora-Betriebssystemen emuliert. Wenn hier beispielsweise alle Widget-Objekte wie Fenster, Schaltflächen usw. eine MS-Variante haben, mit Ausnahme einer Bildlaufleiste, die von der MAC-Variante abgeleitet ist, schlägt der Zweck des Tools schlecht fehl.
Diese oben genannten Fälle bilden das Grundbedürfnis von Abstract Factory Pattern .
Stellen Sie sich andererseits vor, Sie schreiben ein Framework, damit viele Benutzer mithilfe Ihres Frameworks verschiedene Tools ( wie das in den obigen Beispielen ) erstellen können. Durch die Idee eines Frameworks müssen Sie dies nicht tun, obwohl Sie keine konkreten Objekte in Ihrer Logik verwenden konnten. Sie legen lieber Verträge auf hoher Ebene zwischen verschiedenen Objekten und deren Interaktion ab. Während Sie ( als Framework-Entwickler ) auf einer sehr abstrakten Ebene bleiben, ist jeder Builder des Tools gezwungen, Ihren Framework-Konstrukten zu folgen. Sie ( die Tool Builder ) können jedoch frei entscheiden, welches Objekt erstellt werden soll und wie alle von ihnen erstellten Objekte interagieren. Im Gegensatz zum vorherigen Fall ( von Abstract Factory Pattern ) sind Sie ( als Framework-Ersteller)) müssen in diesem Fall nicht mit konkreten Objekten arbeiten; und kann vielmehr auf der Vertragsebene der Objekte bleiben. Darüber hinaus haben Sie oder die Werkzeugbauer im Gegensatz zum zweiten Teil der vorherigen Motivationen nie die Situation, Objekte aus Varianten zu mischen. Während der Framework-Code auf Vertragsebene bleibt, ist jeder Tool-Builder ( aufgrund der Art des Falls selbst ) darauf beschränkt, seine eigenen Objekte zu verwenden. Die Objekterstellung wird in diesem Fall an jeden Implementierer delegiert, und Framework-Anbieter bieten lediglich einheitliche Methoden zum Erstellen und Zurückgeben von Objekten. Solche Methoden sind für Framework-Entwickler unumgänglich, um mit ihrem Code fortzufahren, und haben einen speziellen Namen namens Factory-Methode ( Factory Method Pattern für das zugrunde liegende Muster ).
Einige Anmerkungen:
- Wenn Sie mit der 'Vorlagenmethode' vertraut sind, werden Sie feststellen, dass bei Programmen, die sich auf eine beliebige Form von Framework beziehen, häufig Factory-Methoden von Vorlagenmethoden aufgerufen werden. Im Gegensatz dazu sind Template-Methoden von Anwendungsprogrammen oft eine einfache Implementierung eines bestimmten Algorithmus und ohne Factory-Methoden.
- Um die Vollständigkeit der Gedanken zu gewährleisten, kann ein Werkzeugbauer unter Verwendung des oben erwähnten Frameworks , wenn er innerhalb jeder Fabrikmethode ein Werkzeug baut, anstatt ein konkretes Objekt zu erstellen, die Verantwortung weiter an eine Zusammenfassung delegieren -Fabrikobjekt, vorausgesetzt, der Tool-Builder sieht Variationen der konkreten Objekte für zukünftige Erweiterungen vor.
Beispielcode:
//Part of framework-code
BoardGame {
Board createBoard() //factory method. Default implementation can be provided as well
Piece createPiece() //factory method
startGame(){ //template method
Board borad = createBoard()
Piece piece = createPiece()
initState(board, piece)
}
}
//Part of Tool-builder code
Ludo inherits BoardGame {
Board createBoard(){ //overriding of factory method
//Option A: return new LudoBoard() //Lodu knows object creation
//Option B: return LudoFactory.createBoard() //Lodu asks AbstractFacory
}
….
}
//Part of Tool-builder code
Chess inherits BoardGame {
Board createBoard(){ //overriding of factory method
//return a Chess board
}
….
}