Wenn es um Fabriken und Montagebänder geht, wird die Arbeit immer wieder wiederholt. Es ist wirklich schwieriger als wir Programmierer.
Das Factory-Muster wird auch sehr häufig verwendet. Seine offizielle Erklärung lautet: Definieren Sie eine Schnittstelle zum Erstellen von Objekten und lassen Sie Unterklassen entscheiden, welche Klasse instanziiert werden soll. Das Factory-Muster verschiebt die Instanziierung einer Klasse auf ihre Unterklassen.
Wie in der Abbildung gezeigt, gibt es im System zwei Arten von Superbenutzern und normalen Benutzern. Definieren Sie eine öffentliche Benutzerklasse und eine öffentliche abstrakte Factory Klasse abstractUserFactory, userFactory Die Klasse implementiert die createUser-Methode zum Erstellen der User-Klasse, indem sie die abstractUserFactory-Klasse erbt und dadurch das Factory-Muster realisiert:
PHP-Code
<?php abstract class abstractUserFactory { public abstract function createUser(); } class userFactory extends <span style="font-size: 1em; line-height: 1.5;">abstractUserFactory </span><span style="font-size: 1em; line-height: 1.5;">{</span> Php代码 public function createUser( $className ) { try{ if(class_exists($className)) return new $className(); else{ $error = "no class"; throw new Exception($error); } }catch( Exception $e ) { echo 'Caught exception: ', $e->getMessage(), "\n"; } } } interface User{ public function getGrade(); } class superUser implements User{ public function getGrade() { echo 1; } } class commonUser implements User{ public function getGrade() { echo 0; } } $userFactory = new userFactory(); $userFactory->createUser( 'superUser' )->getGrade(); $userFactory->createUser( 'commonUser' )->getGrade(); 运行结果:10Caught exception: no class
Vorteile des Factory-Musters:
1. Gute Kapselung und klare Codestruktur. Die Erstellung eines Objekts ist bedingt eingeschränkt. Wenn ein Aufrufer beispielsweise ein bestimmtes Produktobjekt benötigt, muss er nur den Klassennamen (oder die Einschränkungszeichenfolge) des Produkts kennen Objekt, das die Kopplung zwischen Modulen reduziert.
2. Sehr gute Skalierbarkeit. Beim Hinzufügen von Produktkategorien kann die „Umarmung von Veränderungen“ abgeschlossen werden, solange die spezifische Fabrikklasse entsprechend geändert oder eine Fabrikklasse erweitert wird. Wenn Sie im obigen Beispiel beispielsweise einen Blue Diamond-Benutzer hinzufügen müssen, müssen Sie nur eine BlueUser-Klasse hinzufügen. Die Factory-Klasse kann die Systemerweiterung abschließen, ohne Aufgaben zu ändern.
3. Produktkategorien abschirmen. Diese Funktion ist sehr wichtig. Der Aufrufer muss sich nicht darum kümmern, wie sich die Implementierung der Produktklasse ändert. Solange die Schnittstelle des Produkts unverändert bleibt, sollte dies der Fall sein nicht ändern.
4. Typischer Entkopplungsrahmen. Der High-Level-Modulwert muss die abstrakte Klasse des Produkts kennen, und andere Implementierungsklassen müssen nicht berücksichtigt werden. Dies entspricht dem Dimit-Gesetz. Ich muss nicht kommunizieren, wenn ich es nicht benötige. Es steht auch im Einklang mit dem Abhängigkeitsinversionsprinzip. Es basiert nur auf der Abstraktion der Produktklasse. Nach dem Substitutionsprinzip ist es kein Problem, Produktunterklassen zu verwenden.
Verwendungsszenarien des Fabrikmusters:
1. Das Fabrikmuster ist ein Ersatz für ein neues Objekt und kann daher überall dort verwendet werden, wo Objekte generiert werden müssen. Sie müssen jedoch sorgfältig überlegen, ob Sie es hinzufügen möchten Für die Verwaltung wird eine Factory-Klasse verwendet, was die Komplexität des Codes erhöht.
2. Wenn Sie ein flexibles und skalierbares Framework benötigen, können Sie die Verwendung des Factory-Musters in Betracht ziehen. Alles ist ein Objekt und alles ist ein Produkt.
3. Factory-Muster können in heterogenen Projekten verwendet werden.
4. Sie können das testgetriebene Entwicklungsframework verwenden. Um beispielsweise eine Klasse A zu testen, müssen Sie gleichzeitig eine Klasse B generieren, die mit Klasse A verknüpft ist. Wir können das Factory-Muster verwenden, um Klasse B zu virtualisieren, um die Kopplung zwischen Klasse A und Klasse B zu vermeiden. (Derzeit gibt es in Java JMock und EasyMock, und dieses Szenario wurde abgeschwächt.)
Erweiterung des Factory-Musters:
1. Einfaches Factory-Muster (häufig in PHP verwendet)
Ein Modul erfordert nur Eine Factory-Klasse muss nicht generiert werden. Verwenden Sie einfach eine statische Methode. Gemäß dieser Anforderung ändern wir die abstractUserFactory im obigen Beispiel, wie in der Abbildung gezeigt:
Entfernen Sie die abstrakte Klasse „abstractUserFactory“ und setzen Sie „createUser“ auf eine statische Klasse, was den Klassenerstellungsprozess vereinfacht. Der Nachteil besteht darin, dass die Fabrikklasse schwierig zu erweitern ist und das Öffnungs- und Schließprinzip nicht eingehalten wird, es sich jedoch dennoch um ein sehr praktisches Entwurfsmuster handelt.
2. Upgrade auf mehrere Fabrikklassen (eins zu eins zwischen Produkten und Fabriken)
Jede Produktklasse entspricht einer Erstellungsklasse Die Verantwortung der Erstellungsklasse ist klar und einfach strukturiert, hat jedoch einen gewissen Einfluss auf die Skalierbarkeit und Wartbarkeit. Wenn Sie eine Produktklasse erweitern möchten, müssen Sie eine entsprechende Fabrikklasse erstellen, was die Schwierigkeit der Erweiterung erhöht. Da die Anzahl der Fabrikklassen und Produkte gleich ist, muss bei der Wartung die Beziehung zwischen den beiden Objekten berücksichtigt werden.
Natürlich wird in komplexen Anwendungen im Allgemeinen die Multi-Factory-Methode verwendet und dann eine Koordinationsklasse hinzugefügt, um zu verhindern, dass der Aufrufer mit jeder Unterfabrik kommuniziert. Die Funktion der Koordinationsklasse besteht darin, sie zu kapseln die Sub-Factory-Klasse und stellen High-Level-Module mit einer einheitlichen Zugriffsschnittstelle bereit.
3. Alternativer Singleton-Modus
Dieser Modus wird durch Instanziieren einer Klasse implementiert, die einen privaten Konstruktor ohne Argumente durch Reflektion definiert. Eine visuelle Inspektion ist mit PHP nicht möglich, daher werde ich sie hier überspringen.
4. Verzögerte Initialisierung
Nachdem ein Objekt verbraucht wurde, wird es nicht sofort freigegeben. Die Factory-Klasse behält ihren ursprünglichen Zustand bei und wartet auf die erneute Verwendung. Für die von PHP interpretierte Sprache kann es auf Lazy Loading erweitert werden, d. h. die entsprechende Klassendatei wird nur geladen, wenn die Factory-Klasse bereit ist, ein neues Objekt zu erstellen, anstatt mögliche Klassen jedes Mal zu laden, wenn das Skript ausgeführt wird.