2010-04-24 6 views
6

Ich versuche, das Fabrikdesignmuster zu verstehen.Vorteil einer Fabrik zur Objekterstellung?

Ich verstehe nicht, warum es gut ist, einen Vermittler zwischen dem Kunden und dem Produkt (Objekt, das der Kunde will) zu haben.

Beispiel ohne Werk:

$mac = new Mac(); 

Beispiel mit einer Fabrik:

$appleStore = new AppleStore(); 
$mac = $appleStore->getProduct('mac'); 

Wie funktioniert das Werk Muster den Client vom Produkt entkoppeln?

Könnte jemand ein Beispiel für eine zukünftige Codeänderung geben, die sich auf Beispiel 1 negativ, aber positiv auf Beispiel 2 auswirkt, so dass ich die Bedeutung der Entkopplung verstehe?

Danke.

+1

Diese zweite scheint eher eine Beziehung als eine Fabrik für mich ...? – SeanJA

Antwort

5

Ich denke, es mit den Ressourcen, einige Arten von Objekten zu konstruieren benötigt zu tun hat.

Wenn Sie jemandem sagen, er solle einen Mac bauen, wäre das ein mühsamer Prozess, der Jahre des Designs, der Entwicklung, der Herstellung und des Testens in Anspruch nehmen würde. Dieser Vorgang müsste für jeden einzelnen Mac wiederholt werden. Wenn Sie jedoch eine Fabrik einführen, kann die ganze harte Arbeit nur einmal erledigt werden, dann können Macs billiger hergestellt werden.

Nun betrachten Sie Joomla's factory.php. Von dem, was ich sagen kann, besteht der Hauptzweck von JFactory darin, Objekte zu sammeln und sicherzustellen, dass Objekte, die identisch sein sollten, nicht kopiert werden. Zum Beispiel gibt JFactory::getUser() einen Verweis auf ein und nur ein Objekt zurück. Wenn sich in diesem Benutzerobjekt etwas ändert, wird es überall angezeigt. Beachten Sie auch, dass JFactory::getUser() eine Referenz und kein neues Objekt zurückgibt. Das kann man mit einem Konstruktor nicht machen.

Oft benötigen Sie lokalen Kontext beim Konstruieren eines Objekts, und dieser Kontext kann persistent sein und möglicherweise viele Formen annehmen. Zum Beispiel könnte eine MySQL-Datenbank Benutzer enthalten. Wenn Benutzerobjekte mit einem Konstruktor erstellt werden, müssen Sie ein Database-Objekt an den Konstruktor übergeben (oder sich auf eine globale Variable verlassen). Wenn Sie Ihre Anwendung auf PostgreSQL umstellen, ändert sich möglicherweise die Semantik des Database-Objekts, sodass alle Verwendungen des Konstruktors überprüft werden müssen. Globale Variablen lassen uns diese Details verbergen, ebenso wie Fabriken. Daher würde eine Benutzerfactory die Details zum Konstruieren von Benutzerobjekten von Orten entkoppeln, an denen Benutzerobjekte benötigt werden.

Wann sind Fabriken hilfreich? Beim Erstellen eines Objekts sind Hintergrunddetails erforderlich. Wann sind Konstrukteure besser? Wenn globale Variablen ausreichen.

+1

+1 Analogie Bonus – SeanJA

+0

aber ist dies nicht "Umzugsprozess an einen zentralen Ort" genannt. was ich nicht verstehe, ist das Wort entkoppeln. –

+0

aber wenn ich Datenbank und im using factory ändern muss, muss ich noch meinen Code in der Fabrik ändern. Es ist dieser Teil, den ich nicht ganz verstehe. So oder so muss ich mich ändern, jetzt habe ich es einfach in eine andere Klasse verschoben, die Fabrik. Ich kann verstehen, dass dies gut ist, wenn es um Frameworks/OS-Anwendungen geht. Ihre Benutzer, die mit Ihrem Code interagieren, müssen ihren Code nicht neu schreiben. aber wenn ich der Einzige bin, der den Code benutzt, den ich schreibe, wie ist die Fabrik besser? Ich muss noch ändern, wenn ich die Datenbank ändere. –

1

In diesem Beispiel wird ein Objekt vom Typ Mac und es kann nie anders alles sein:

$mac = new Mac(); 

Es ist nicht eine Unterklasse von Mac sein kann, kann es nicht eine Klasse sein, die die Schnittstelle von Mac übereinstimmt.

Während das folgende Beispiel ein Objekt vom Typ Mac oder einen anderen Typ, den die Fabrik entscheidet, zurückgeben kann.

$appleStore = new AppleStore(); 
$mac = $appleStore->getProduct('mac'); 

Sie könnten eine Reihe von Unterklassen von Mac wollen, die jeweils ein anderes Modell von Mac darstellt. Dann schreiben Sie in der Fabrik Code, um zu entscheiden, welche dieser Unterklassen verwendet werden soll. Mit dem Operator new können Sie das nicht tun.

So eine Fabrik gibt Ihnen mehr Flexibilität bei der Erstellung von Objekten. Flexibilität geht oft einher mit der Entkopplung.


Re Ihr Kommentar: Ich würde nicht sagen, nie Verwendung new. In der Tat verwende ich new für die Mehrheit der einfachen Objekterstellung. Aber es hat nichts damit zu tun, wer den Client-Code schreibt. Das Factory-Muster ist für eine Architektur gedacht, in der die Klasse dynamisch instanziiert werden kann.

In Ihrem Apple Store-Beispiel möchten Sie wahrscheinlich einen einfachen Code, um ein Produkt zu instanziieren und in einen Einkaufswagen zu legen. Wenn Sie new verwenden und Sie unterschiedliche Objekttypen für jeden unterschiedlichen Produkttyp haben, müssen Sie eine große case-Anweisung schreiben, damit Sie ein new-Objekt des entsprechenden Typs erstellen können. Jedes Mal, wenn Sie einen Produkttyp hinzufügen, müssen Sie diese case-Anweisung aktualisieren. Und Sie könnten mehrere dieser case Aussagen in anderen Teilen Ihrer Anwendung haben.

Wenn Sie eine Factory verwenden, benötigen Sie nur einen Aktualisierungsort, der weiß, wie ein Parameter zu übernehmen ist und den richtigen Objekttyp instanziiert. Alle Orte in Ihrer App würden implizit Unterstützung für den neuen Typ erhalten, ohne dass Codeänderungen erforderlich sind. Das ist ein Gewinn, egal ob du der einzige Entwickler bist oder in einem Team bist.

Aber wieder brauchen Sie keine Fabrik, wenn Sie nicht eine Vielzahl von Subtypen unterstützen müssen. Verwenden Sie einfach weiter in einfachen Fällen new.

+0

so der Fokus ist auf "wie kann ich Code schreiben, also, wenn ich meinen Code ändern, muss der Kunde nicht"? Grundsätzlich möchte ich NIEMALS, dass der Kunde neue "Endprodukte" verwendet. Ich möchte eine Abstraktionsschicht (Fabrik) für die Erstellung von Produkten bereitstellen. Er muss also nicht wissen, was hinter den Kulissen passiert. hab ich recht? aber was ist, wenn ich alles selbst code? so oder so, ich muss mich ändern. Ich verstehe nicht ganz, wo der Fokus liegt oder was ich als Entwickler machen möchte. –