Ich versuche immer noch, Designmuster hier zu verstehen. Nachdem ich das abstrakte Fabrikmuster gelernt hatte, stellte ich fest, dass dieses Muster nicht gut skaliert werden kann. Schauen Sie sich das Uml-Diagramm des abstrakten Fabrikmusters an
Wenn ich ein neues 'AbstractProductC' erstellen muss, muss ich in 'AbstractFactory' eine abstrakte Methode 'CreateProductC' hinzufügen, die sich auf die Implementierung von ConcreateFactory1 und ConcreateFactory2 auswirkt.
Meine Frage hier ist, skaliert Abstract Factory überhaupt (oder) ich denke hier in die falsche Richtung?
Danke im Voraus
design
design-patterns
Jitendar
quelle
quelle
Antworten:
Abstract Factory skaliert ganz gut.
Es gibt ein Grundprinzip, das besagt, dass eine Klasse eine Sache gut machen sollte. Ihr Problem hier ist, dass Sie versuchen, viele Klassen dazu zu bringen, viele Dinge zu tun.
Sie müssen sich nicht an eine abstrakte Fabrik halten. Sie können (und sollten) mehrere haben:
AbstractProductAFactory
definiert die Schnittstelle zur Herstellung von ProductA. Ihre konkreten Implementierungen (ConcreteProductAFactory1, ConcreteProductAFactory2) würden es erweitern.AbstractProductBFactory
definiert die Schnittstelle zur Herstellung von ProductB. Ihre konkreten Implementierungen (ConcreteProductBFactory1
,ConcreteProductBFactory2
) würden es erweitern.Wenn Sie dann ein ProductC benötigen, erstellen Sie ein neues
AbstractProductCFactory
. Sie müssen keine Ihrer anderen Fabriken auf diese Weise ändern.UPDATE Idealerweise sollte ProductA eine Produktklasse darstellen, dh alle Produkte, die eine Schnittstelle gemeinsam nutzen, die Sie ProductA nennen. In den Kommentaren schlage ich vor, dass dies so etwas wie eine Pizza ist:
Und so weiter. Das Hinzufügen einer PanPizzaFactory wirkt sich nicht auf eine der anderen Klassen aus - es handelt sich lediglich um eine neue konkrete Implementierung der PizzaFactory. Wenn Sie Produkte haben, die keine Pizza sind - zum Beispiel Sandwiches -, erstellen Sie dort eine weitere abstrakte Fabrik (z
AbstractSandwichFactory
. B. ).Der eigentliche Punkt ist, dass Sie keine abstrakte Fabrik haben möchten, die zwei sehr unterschiedliche Produkttypen mit zwei unterschiedlichen "Build" -Methoden erstellt. Gruppieren Sie sie so logisch wie möglich, damit sie eine Schnittstelle gemeinsam nutzen, und erstellen Sie dann eine abstrakte Factory, die definiert, wie konkrete Fabriken Implementierungen dieser Schnittstelle erstellen sollen.
quelle
AbstractPizzaFactory.buildPizza(List<Topping> toppings)
.Das Problem bei der Skalierung besteht darin, dass Code auf viele verschiedene Arten skaliert werden kann. Das Problem, das Sie haben, wird einfach durch die Notwendigkeit verursacht, in eine Richtung zu skalieren, für die das Entwurfsmuster nicht vorgesehen ist. Im Falle des Abstract Factory-Musters soll es so skaliert werden, dass neue Betonfabriken hinzugefügt werden. Das Hinzufügen neuer Produkte führt jedoch zu großen strukturellen Änderungen.
Einer der Punkte des Software-Designs und der Architektur besteht darin, die wahrscheinlichsten Richtungen zu identifizieren, in die der Code skaliert, und Muster basierend auf diesen wahrscheinlichen Richtungen auszuwählen. Wenn Sie feststellen, dass das Hinzufügen eines neuen Produkts wahrscheinlicher ist als das Hinzufügen einer neuen Betonfabrik, ist die Verwendung von Abstract Factory keine gute Idee, und es ist möglicherweise besser, das Design komplett zu überdenken.
quelle
Ja, Sie haben Recht, "abstrakte Fabrik" lässt sich nicht gut skalieren, wenn Sie zusätzliche abstrakte Produkte benötigen .
In vielen realen Szenarien müssen Sie jedoch eine sich ändernde Anzahl von Produkten, aber nur eine kleine, feste Anzahl von abstrakten Produkten unterstützen. Nehmen Sie zum Beispiel das Beispiel für GUI-Widgets aus dem Wikipedia-Artikel über abstrakte Fabriken . Die abstrakte GUI-Factory könnte eine Methode
createWidget
(anstelle voncreateButton
) haben, bei derWidget
es sich um das "abstrakte Produkt" handelt, das die oberste Basisklasse für eine Familie von mehreren Dutzend GUI-Elementen darstellt. Das Hinzufügen neuer GUI-Widgets bedeutet in keiner Weise eine Änderung der Benutzeroberfläche der abstrakten Factory, sodass keine der Schnittstellen der konkreten Factory geändert werden muss.Viele abstrakte Produkte bedeuten, dass Ihr Code viele verschiedene Klassenhierarchien enthält. In diesem Fall können Sie für jede Hierarchie eine eigene Factory (oder abstrakte Factory) erstellen.
quelle
Ihr Skalierungsfaktor ist eine einfache Frage des Abhängigkeitsmanagements. Je mehr Abhängigkeiten eine Klasse hat, desto stabiler und durchdachter sollte ihre API sein.
Es ist kein Problem, eine Fabrik zu schaffen, die durch die Verantwortung für die Schaffung von Typen ähnlicher oder zusammenhängender Natur definiert ist. Aber je mehr Klassen von dieser Fabrik abhängen, desto strenger sollte dieser Zusammenhalt sein.
(Hinweis: Dies kann schrittweise erfolgen, nicht unbedingt durch einen BDUF.)
quelle