Hinweise zu Java-Entwurfsmustern für Anfänger – Abstraktes Fabrikmuster

 Das Abstract Factory-Muster ist wie folgt definiert:

  

1. Absicht: Bereitstellung einer Schnittstelle zum Erstellen einer Reihe verwandter oder voneinander abhängiger Objekte ohne Angabe ihrer spezifischen Klassen.

(Stellen Sie eine Schnittstelle zum Erstellen von Familien verwandter oder abhängiger Objekte bereit , ohne deren konkrete Klassen anzugeben.)

 

2. Teilnehmer: (5 Rollen)
Abstrakte Fabrik (AbstractFactory): Deklariert eine Operationsschnittstelle zum Erstellen abstrakter Produktobjekte.
ConcreteFactory: implementiert den Vorgang der Erstellung spezifischer Produktobjekte .
Abstraktes Produkt: Deklariert eine Schnittstelle für einen Produktobjekttyp.
Betonprodukt (ConcreteProdcut): Definiert ein Produktobjekt, das von der entsprechenden Betonfabrik erstellt wird. Implementieren Sie die AbstractProduct- Schnittstelle.
Client: Verwenden Sie nur die von den Klassen AbstractFactory und AbstractProduct deklarierten Schnittstellen .

 

Als ich die Rolle des Kunden zum ersten Mal sah , war ich etwas verwirrt. Ich frage mich, welche Rolle der Kunde im abstrakten Fabrikmuster spielt.

Ist es dasselbe wie der Kunde (Kunde) in den Beispielen (1 bis 7), die geschrieben wurden, als ich zuvor das „Simple Factory Pattern“ und das „Factory Method Pattern“ gelernt habe ? Bedeutet es dasselbe? Wenn ja, warum gibt es im Factory-Methodenmuster keinen Client- Teilnehmer ?

 

Das GOF-Entwurfsmuster enthält den Teilnehmer „ Client“ , Yan Hongs „Java and Patterns“ enthält jedoch nicht den Teilnehmer „ Client“ .

 

Später schien es klar zu sein, dass der Client die abstrakte Fabrik zum Zusammenstellen abstrakter Produkte verwenden und dem Client mithilfe des abstrakten Fabrikmusters eine Aufrufschnittstelle bereitstellen sollte . Wir werden die Rolle des Kunden im folgenden Beispiel 8 verstehen .

Tatsächlich wird in vielen Beispielen der Client mit der abstrakten Fabrik zusammengeführt , und einige werden mit dem Client zusammengeführt .

 

3. Struktur:

Abbildung 1: Im Entwurfsmuster von GoF (ähnlich der folgenden Form)



 

Abbildung 2: In Yan Hongs „Java and Patterns“ (ähnlich dem Formular unten)

 

 

 

Wenn ich das abstrakte Factory-Muster sehe, vergleiche ich es immer mit dem Factory-Methodenmuster .

 

Beide Modi haben die gleichen vier Zeichen:

Abstrakte Fabrik (AbstractFactory) --->Betonfabrik (ConcreteFactory)

Abstraktes Produkt (AbstractProduct) --->Konkretes Produkt (ConcreteProdcut)

 

Was ist also der Unterschied zwischen diesen beiden Modi? 

 

Sehen Sie, was der Unterschied in der Absicht ist:

1. Factory-Methodenmuster: Definieren Sie eine Schnittstelle zum Erstellen von Objekten und lassen Sie Unterklassen entscheiden, welche Klasse instanziiert werden soll. Die Factory-Methode verschiebt die Instanziierung einer Klasse auf ihre Unterklassen.

(Definieren Sie eine Schnittstelle zum Erstellen eines Objekts , aber lassen Sie Unterklassen entscheiden, welche Klasse instanziiert werden soll. Mit der Factory-Methode kann eine Klasse die Instanziierung auf Unterklassen verschieben.)

2. Abstraktes Fabrikmuster : Bietet eine Schnittstelle zum Erstellen einer Reihe verwandter oder voneinander abhängiger Objekte, ohne deren spezifische Klassen anzugeben.

(Stellen Sie eine Schnittstelle zum Erstellen von Familien verwandter oder abhängiger Objekte bereit , ohne deren konkrete Klassen anzugeben.)

 

Anhand der Absichten dieser beiden Modi können wir Folgendes erkennen:

1. Das Fabrikmethodenmuster wird zum Erstellen eines Produktobjekts verwendet . Das heißt, jede abstrakte Fabrik wird zum Erstellen eines abstrakten Produktobjekts verwendet, und jede konkrete Fabrik, die die abstrakte Fabrik erbt, wird zum Erstellen eines bestimmten Produktobjekts verwendet.

2. Das abstrakte Fabrikmuster wird zum Erstellen mehrerer (einer Menge oder einer Reihe) Produktobjekte verwendet. Das heißt, jede abstrakte Fabrik wird zum Erstellen mehrerer (einer Menge oder einer Reihe) abstrakter Produktobjekte verwendet und erbt die abstrakte Fabrik. Jede der Betonfabriken kann zur Herstellung mehrerer (eines Satzes oder einer Serie) konkreter Produktobjekte verwendet werden.

 

Nehmen wir also immer noch die „Produktion von Autos“ als Beispiel:

1. Im Fabrikmethodenmodus ist jedes Auto ein Produktobjekt (Autoteile wie Motoren, Türen usw. werden als Attribute des Autos betrachtet ).

Bei der Herstellung von Autos in einer Fabrik handelt es sich eigentlich nur um den Zusammenbau von Autoteilen.

2. Im abstrakten Fabrikmodus besteht jedes Auto aus einer Reihe von Produktobjekten für Autoteile (Motoren, Türen usw. sind alles Produkte, keine Attribute mehr ).

Der Prozess der Herstellung von Autos in einer Fabrik ist zu einem Prozess geworden, bei dem zunächst einzelne Autoteile hergestellt und dann die Autoteile zusammengebaut werden.

 

Yan Hong sagte dies in „JAVA and Patterns“:

Der größte Unterschied zwischen dem abstrakten Fabrikmuster und dem Fabrikmethodenmuster besteht darin, dass das Fabrikmethodenmuster auf eine Struktur auf Produktebene abzielt, während das abstrakte Fabrikmuster auf mehrere Strukturen auf Produktebene abzielen muss.

 

Der Begriff „Produkthierarchie“ wirkt abstrakt.

1. Was ist eine Produkthierarchie?

Audi A6, Audi A8 und sogar BMW X6 können als Produktklasse betrachtet werden, da es sich bei ihnen alles um Autos handelt.

Auch der rote Audi A6, der schwarze Audi A8 und sogar BMW können als Produktklasse betrachtet werden, da es sich bei ihnen alles um Autos handelt.

Bild 3:

 

 

Die Motoren jedes der oben genannten Autos, der Audi A6-Motor und der Audi A8-Motor (vorausgesetzt, die Motormodelle sind hier unterschiedlich), können ebenfalls als Produktebene betrachtet werden, da es sich bei allen um Motoren handelt.

Figur 4:



 

2. Was ist eine Organisation mit mehreren Produktebenen?

Der Motor des Audi A6, die Türen des Audi A6 und die Reifen des Audi A6 sind in mehrere Produktebenen gegliedert, da es sich um unterschiedliche Produkttypen handelt.

Mit anderen Worten: Motoren, Türen, Reifen und andere Autoteile stellen jeweils einen Produkttyp dar. Es gibt keine Vererbungs- und Implementierungsbeziehung und es gibt keine Schnittmenge.

 

Es besteht eine parallele Beziehung zwischen ihnen, aber wenn sie kombiniert werden, können sie ein Auto (eine Produktfamilie) bilden.

Ein Audi A6-Auto ist eine Kombination aus einer Reihe von Audi A6-Motoren, Audi A6-Türen, Audi A6-Reifen und anderen Autoteilen.

 

Abbildung 5:



  

 

Beispiele und Java-Implementierung des Abstract Factory-Musters:

 

Möchte ein Kunde einen FAW-Volkswagen kaufen, müssen auch Motor und Karosserie des Wagens dem entsprechenden Modell entsprechen.

Kunde A möchte einen Audi A6 kaufen, und Kunde A möchte einen Audi A8 kaufen. Beispiel 8:

 

Automotor (abstraktes Produkt):

 

/*
 * 汽车发动机(抽象产品)
 */
public interface Engine {

}

 

Audi A6 Motor (spezifische Produkte):

 

/*
 * 奥迪A6的发动机(具体产品)
 */
public class AudiA6Engine implements Engine{
	
	public String toString(){
		return "奥迪A6发动机";
	}

}

 

Audi A8 Motor (spezifische Produkte):

 

/*
 * 奥迪A8的发动机(具体产品)
 */
public class AudiA8Engine implements Engine{
	
	public String toString(){
		return "奥迪A8发动机";
	}

}

 

 

Karosserie (abstraktes Produkt):

 

/*
 * 汽车车身(抽象产品)
 */
public interface CarBody {

}

 

Audi A6 Karosserie (spezifische Produkte): 

  

/*
 * 奥迪A6的车身(具体产品)
 */
public class AudiA6CarBody implements CarBody {
	
	public String toString(){
		return "奥迪A6车身";
	}

}

 

Audi A8 Karosserie (spezifische Produkte):

 

/*
 * 奥迪A8的车身(具体产品)
 */
public class AudiA8CarBody implements CarBody {
	
	public String toString(){
		return "奥迪A8车身";
	}

}

 

 

FAW-Volkswagen-Fabrik (Abstrakte Fabrik):

 

/*
 * 一汽大众工厂(抽象工厂)
 */
public interface CarFactory {
	/*
	 * 生产汽车发动机的工厂方法(创建一种产品对象)
	 */
	public Engine createEngine();
	
	/*
	 * 生产汽车车身的工厂方法(创建另一种产品对象)
	 */
	public CarBody createCarBody();

}

 

Audi A6 Werk (spezifisches Werk):

 

/*
 * 奥迪A6工厂(具体工厂)
 */
public class AudiA6CarFactory implements CarFactory {

	/*
	 * 生产奥迪A6发动机的工厂方法(创建一种具体产品对象)
	 */
	public CarBody createCarBody() {
		return new AudiA6CarBody();
	}

	/*
	 * 生产奥迪A6车身的工厂方法(创建另一种具体产品对象)
	 */
	public Engine createEngine() {
		return new AudiA6Engine();
	}

}

 

Audi A8 Werk (spezifisches Werk):

 

/*
 * 奥迪A8工厂(具体工厂)
 */
public class AudiA8CarFactory implements CarFactory {
	
	/*
	 * 生产奥迪A6发动机的工厂方法(创建一种具体产品对象)
	 */
	public CarBody createCarBody() {
		return new AudiA8CarBody();
	}

	/*
	 * 生产奥迪A6车身的工厂方法(创建另一种具体产品对象)
	 */
	public Engine createEngine() {
		return new AudiA8Engine();
	}

}

 

Auto (Client):

Ein Auto ist eigentlich eine Produktfamilie, also eine Reihe (eine Reihe) von Autoteileprodukten (Produktfamilie).

Hier wird eine Autoklasse definiert, die nur abstrakte Fabriken (CarFactory) und abstrakte Produkte ( Engine, CarBody ) verwendet und keine spezifischen Fabriken ( AudiA6CarFactory, AudiA8CarFactory ) und spezifischen Produkte ( AudiA6Engine, AudiA8Engine, AudiA6CarBody, AudiA8CarBody  ) umfasst .

 

/*
 * 汽车(客户端)
 * 通过生产发动机的工厂和生产车身的工厂,生产汽车发动机和汽车车身,
 * 最终,汽车由一套产品族(一套汽车零部件)组成。
 */
public class Car {
	
	private CarBody body;
	private Engine engine;
	
	public Car(CarFactory carFactory){
		this.body = carFactory.createCarBody();
		this.engine = carFactory.createEngine();
		
	}
	
	public String toString(){
		return "[" + this.body+"/" + this.engine + "]";
	}

}

 

Kundenanruf (zum Testen):

Beim Aufruf des abstrakten Factory-Musters wird die Client-Rolle Car verwendet , da der eingehende Parametertyp der Konstruktorkorrespondenz der Car-Klasse eine abstrakte Factory ist.

Solange wir bei Bedarf ein gewünschtes spezifisches Fabrikobjekt ( AudiA6CarFactory) übergeben , können wir auf diese Weise das gewünschte Produktfamilienobjekt ( adioA6Car) erhalten .

Wenn Sie ein anderes Produktfamilienobjekt (adioA8Car) erhalten möchten , übergeben Sie einfach ein anderes spezifisches Fabrikobjekt (AudiA8CarFactory) . 

 

/*
 * 使用抽象工厂的客户端(用于测试)
 */
public class Customers {
	 
	public static void main(String[] args){
		
//		创建一个奥迪A6生产工厂(具体工厂对象)
		CarFactory adioA6CarFactory = new AudiA6CarFactory();
//		顾客A购买了奥迪A6(具体工厂对象作为参数,将会被用来创建汽车对象(包含了一系列相关的汽车部件产品对象))
		Car adioA6Car = new Car(adioA6CarFactory);
		System.out.println("顾客A买了一辆汽车" + adioA6Car);

//		创建一个奥迪A8生产工厂(具体工厂对象)
		CarFactory adioA8CarFactory = new AudiA8CarFactory();
//		顾客B购买了奥迪A8(具体工厂对象作为参数,将会被用来创建汽车对象(包含了一系列相关的汽车部件产品对象))
		Car adioA8Car = new Car(adioA8CarFactory);
		System.out.println("顾客B买了一辆汽车" + adioA8Car);		
		
	}

}

 

Operationsergebnis:

顾客A买了一辆汽车[奥迪A6车身/奥迪A6发动机]
顾客B买了一辆汽车[奥迪A8车身/奥迪A8发动机]

 

 

 Strukturdiagramm dieses Beispiels:

  

 

 

 

 

 

Um es kurz zusammenzufassen: Durch den Vergleich des Factory-Methodenmusters können wir die Vorteile des abstrakten Factory-Musters verstehen :

1. Durch absichtlichen Vergleich,

Der Zweck der Verwendung des abstrakten Fabrikmusters besteht darin, eine Reihe verwandter oder voneinander abhängiger Objekte (mehrere oder mehrere Kategorien) zu erstellen.

Der Zweck der Verwendung des Factory-Methodenmusters besteht darin, (ein oder eine Klasse von) Objekten zu erstellen.

2. Durch Strukturvergleich,

Da das abstrakte Fabrikmuster darin besteht, mehrere verwandte Produktobjekte zu erstellen, wird eine Client-Rolle (Client) hinzugefügt, um die erstellten Produktfamilien zu integrieren.

Gleichzeitig ist die Fabrik im abstrakten Fabrikmuster keine Fabrik für irgendein Produkt, sondern eine Fabrik für mehrere Produkte. Ich denke, das könnte der Grund sein, warum die Musterfabrik der abstrakten Fabrik als „abstrakte“ Fabrik bezeichnet wird . Mit anderen Worten, seine „Abstraktion“ ist die „Abstraktion“ mehrerer Produkte.

 

 

In vielen Materialien und praktischen Anwendungen werden die meisten Vorteile des abstrakten Fabrikmusters durch die Kombination von Konfigurationsdateien und Reflexion vollständig widergespiegelt.

Der Link unten ist ein abstraktes Factory-Muster, das von einem Blogger mit .NET erklärt wurde. Ich denke, es ist leicht zu verstehen und hat einen großen Referenzwert für praktische Anwendungen.

.NET-Entwurfsmuster (3): Abstraktes Factory-Muster (Abstract Factory)

 

Ich denke du magst

Origin blog.csdn.net/louis_lee7812/article/details/83767831
Empfohlen
Rangfolge