Heim  >  Artikel  >  Java  >  Detaillierte Erklärung der abstrakten Fabrik in Java

Detaillierte Erklärung der abstrakten Fabrik in Java

黄舟
黄舟Original
2017-09-15 09:51:501181Durchsuche

In diesem Artikel werden hauptsächlich die relevanten Informationen des Java-Entwurfsmusters Abstract Factory im Detail vorgestellt, die einen gewissen Referenzwert haben.

1. Konzept

Bietet eine Schnittstelle zum Erstellen einer Reihe verwandter oder voneinander abhängiger Objekte, ohne deren konkrete Klassen anzugeben.

2. Mustermotivation

Diese Reihe von Objekten ist voneinander abhängig und entspricht einer Produktfamilie

3. Die Struktur des Musters

Auf dem Bild oben können wir deutlich sehen, dass das Muster der abstrakten Fabrik die folgenden 4 Rollen umfasst:

1. Rolle der abstrakten Fabrik (AbstractFactory ): Der Kern des abstrakten Factory-Musters, das nichts mit einer bestimmten Geschäftslogik zu tun hat. Es handelt sich normalerweise um eine JAVA-Schnittstelle oder eine abstrakte Klasse.

2. Konkrete Fabrik: Diese Rolle ist normalerweise eng mit einer bestimmten Geschäftslogik verbunden. Die Factory-Methode in dieser Rolle instanziiert bestimmte Produkte und gibt sie basierend auf einer bestimmten Geschäftslogik zurück. Der Client verwendet diese Rolle und ruft die Factory-Methode auf der Rolle, um ein bestimmtes Produktobjekt zu erhalten. Diese Rolle wird normalerweise von einer bestimmten JAVA-Klasse übernommen.

3. Abstrakte Produktrolle: Die Klasse, die diese Rolle spielt, ist die übergeordnete Klasse des durch das Factory-Methodenmuster erstellten Produkts oder die gemeinsame Schnittstelle, normalerweise eine Schnittstelle oder abstrakte Klasse.

4. Spezifische Produktrolle: Jedes durch das abstrakte Fabrikmuster erstellte Produkt ist eine Instanz dieser Rolle und verfügt über eine bestimmte JAVA-Klasse, die diese übernimmt.

Der Beispielcode lautet wie folgt:


public class AbstractProductA 
{
  
  /**
  * @roseuid 59AC05990327
  */
  public AbstractProductA() 
  {
  
  }
}


public class ProductA1 extends AbstractProductA 
{
  
  /**
  * @roseuid 59AC05990359
  */
  public ProductA1() 
  {
  
  }
}


public class ProductA2 extends AbstractProductA 
{
  
  /**
  * @roseuid 59AC05990381
  */
  public ProductA2() 
  {
  
  }
}

public class AbstractProductB 
{
  
  /**
  * @roseuid 59AC059903BA
  */
  public AbstractProductB() 
  {
  
  }
}

public class ProductB1 extends AbstractProductB 
{
  
  /**
  * @roseuid 59AC059A001F
  */
  public ProductB1() 
  {
  
  }
}

public class ProductB2 extends AbstractProductB 
{
  
  /**
  * @roseuid 59AC059A0049
  */
  public ProductB2() 
  {
  
  }
}


public abstract class AbstractFactory 
{
  
  /**
  * @roseuid 59AC05690005
  */
  public AbstractFactory() 
  {
  
  }
  
  /**
  * @return AbstractProductA
  * @roseuid 59ABFB0103BE
  */
  public Abstract AbstractProductA createProductA() ;
  
  
  /**
  * @return AbstractProductB
  * @roseuid 59ABFB3B029D
  */
  public Abstract AbstractProductB createProductB() ;
}


public class ConcreteFactory1 extends AbstractFactory 
{
  
  /**
  * @roseuid 59AC057A02FC
  */
  public ConcreteFactory1() 
  {
  
  }
  
  /**
  * @return AbstractProductA
  * @roseuid 59ABFB9C00C9
  */
  public AbstractProductA createProductA() 
  {
    return new ProductA1();
  }
  
  /**
  * @return AbstractProductB
  * @roseuid 59ABFBA30011
  */
  public AbstractProductB createProductB() 
  {
    return new ProductB1();
  }
}



public class ConcreteFactory2 extends AbstractFactory 
{
  
  /**
  * @roseuid 59AC057A02C0
  */
  public ConcreteFactory2() 
  {
  
  }
  
  /**
  * @return AbstractProductA
  * @roseuid 59ABFCC701B9
  */
  public AbstractProductA createProductA() 
  {
    return new ProductA2();
  }
  
  /**
  * @return AbstractProductB
  * @roseuid 59ABFCC9001F
  */
  public AbstractProductB createProductB() 
  {
    return new ProductB2();
  }
}


public class Client 
{
  
  
  /**
  * @roseuid 59AC055700AB
  */
  public Client() 
  {
  
  }

  public static void main(String[] args){
      AbstractFactory theAbstractFactory;
    AbstractProductA theAbstractProductA;
    AbstractProductB theAbstractProductB;

    theAbstractFactory=new ConcreteFactory1();

    theAbstractProductA=theAbstractFactory.createProductA();
    theAbstractProductB=theAbstractFactory.createProductB();
 
  }
}

Gemäß dem Musterstrukturdiagramm oben , wir „stellen eine Schnittstelle zum Erstellen einer Reihe verwandter oder voneinander abhängiger Objekte bereit, ohne deren spezifische Klassen anzugeben“ Führen Sie eine kurze Analyse durch:

1. Verwandte oder voneinander abhängige Objekte, hier sind Instanzen von ProduktA1. Die Instanz mit ProduktB1 ist a Gemäß der Geschäftslogik kann ProduktA1

nur mit ProduktB1 unter derselben Produkthierarchiestruktur interagieren und nicht verknüpft werden mit ProduktB2.

2. Stellen Sie eine Schnittstelle zum Erstellen einer Reihe verwandter oder voneinander abhängiger Objekte bereit, ohne deren spezifische Klassen anzugeben. Die Schnittstellen hier sind AbstractProductA und AbstractProductB im Strukturdiagramm wird programmiert, ohne auf die spezifische Implementierung angewiesen zu sein, was dem Abhängigkeitsinversionsprinzip entspricht. „Es besteht keine Notwendigkeit, ihre spezifischen Klassen anzugeben.“ Das heißt, der Client weiß nicht, ob ProductA1, ProductA2, ProductB1 und ProductB2 vorhanden sind. Der Client muss lediglich die Factory-Methode der jeweiligen Factory aufrufen, um die spezifische Produktinstanz zurückzugeben.

4. Musterbeispiele

Folgen wir zur weiteren Analyse den Beispielen im Fabrikmethodenmuster. Jetzt gibt sich diese Reifenfabrik nicht mehr damit zufrieden, nur Autoreifen zu produzieren. Er hat jetzt die Produktionslinie für Motoren (EngineLine), Türen (DoorLine) und verschiedene andere Teileproduktionslinien für das gesamte Auto eingeführt. Man kann sagen, dass er jetzt problemlos ein Auto herstellen kann, aber nicht alle Autos können hergestellt werden , er kann derzeit nur zwei Arten von Autos produzieren: Benz und BMW (eine solche Fabrik reicht für NX zum Beispiel, ein Auto enthält jetzt nur Reifen, Türen und Motoren (natürlich müssen es mehr sein). Dann kann diese Fabrik den BMW- und Benz-Autos folgen, die gemäß den Anforderungen des Kunden hergestellt wurden, wie unten gezeigt:

Der Code lautet wie folgt:


public interface Door {
  public void open();
  public void close();
}
public class BenzDoor implements Door {

  @Override
  public void open() {
    System.out.println("奔驰车门开");
  }

  @Override
  public void close() {
    System.out.println("奔驰车门关");
  }
}
public class BmwDoor implements Door {

  @Override
  public void open() {
    System.out.println("宝马车门开");
  }

  @Override
  public void close() {
    System.out.println("宝马车门关");
  }

}
public interface Tire {
  public void getColor();
  public void getLife();
  public void getWidth();
}
public class BenzTire implements Tire {

  @Override
  public void getColor() {
    System.out.println("benz车color");
  }

  @Override
  public void getLife() {
    System.out.println("benz车life");
  }

  @Override
  public void getWidth() {
    System.out.println("benz车width");
  }
}
public class BmwTire implements Tire {

  @Override
  public void getColor() {
    System.out.println("bmw车color");
  }

  @Override
  public void getLife() {
    System.out.println("bmw车life");
  }

  @Override
  public void getWidth() {
    System.out.println("bmw车width");
  }

}
public interface Engine {
  public void start();

  public void stop();

}
public class BenzEngine implements Engine {

  @Override
  public void start() {
    System.out.println("benz车start");

  }

  @Override
  public void stop() {
    System.out.println("benz车stop");

  }

}
public class BmwEngine implements Engine {

  @Override
  public void start() {
    System.out.println("bmw车start");

  }

  @Override
  public void stop() {
    System.out.println("bmw车stop");

  }

}
public interface PartFactory {
  public Door createDoor();

  public Tire createTire();

  public Engine createEngine();

}
public class BenzPartFactory implements PartFactory {

  @Override
  public Door createDoor() {
    return new BenzDoor();
  }

  @Override
  public Tire createTire() {
    return new BenzTire();
  }

  @Override
  public Engine createEngine() {
    return new BenzEngine();
  }

}
public class BmwPartFactory implements PartFactory {

  @Override
  public Door createDoor() {
    return new BmwDoor();
  }

  @Override
  public Tire createTire() {
    return new BmwTire();
  }

  @Override
  public Engine createEngine() {
    return new BmwEngine();
  }

}
public class Car {
  private Door door;
  private Engine engine;
  private Tire tire;

  public Car(PartFactory factory) {
    this.door = factory.createDoor();
    this.engine = factory.createEngine();
    this.tire = factory.createTire();
  }

  public Door getDoor() {
    return door;
  }

  public Engine getEngine() {
    return engine;
  }

  public Tire getTire() {
    return tire;
  }  
}
public class Client {
  
  public static void main(String[] args) {
    PartFactory partFactory=new BenzPartFactory();
    Car benzCar=new Car(partFactory);
    
    benzCar.getDoor().open();
    benzCar.getEngine().start();
    benzCar.getTire().getColor();
    
  }

}

Lauf Die Ergebnisse sind wie folgt:

Benz-Autotür offen
Benz-Autostart
Benz-Autofarbe

Laut Über dem Klassendiagramm und den Betriebsergebnissen kann die folgende Analyse durchgeführt werden:

BenzDoor, BenzTire und BenzEngine haben eine starke Beziehung. Wir können sagen, dass ein Benz-Auto keine BMW-Türen verwenden kann, also BmwDoor. Diese starke Beziehung wird durch BenzPartFactory gut gepflegt. Für den Kunden, wie die oben genannte Kundenklasse, wenn der Kunde ein Benz-Auto möchte, benötige ich nur eine Fabrik, die Benz-Autos herstellt. Alle Produktinstanzen in dieser Fabrik sind Teile von Benz-Autos. Das sehen wir auch an den Laufergebnissen.

Stellen Sie sich vor, dass mit der Entwicklung dieser Fabrik nun auch Audi-Autos produziert werden. Zu diesem Zeitpunkt müssen wir nur die Audi-Türklassen AudiDoor, AudiTire, AudiEngine und AudiPartFactory hinzufügen. etwaige Änderungen. Aber der Kunde sagte: Ich möchte ein Paar Flügel am Auto anbringen, damit es fliegen kann, wenn es einen Stau gibt. Zu diesem Zeitpunkt müssen wir eine Fabrikmethode hinzufügen, die die Flügel an jede Fabrik zurückgeben kann, und wir Es ist nicht notwendig, jede Fabrik zu ändern. Daher unterstützt die abstrakte Fabrik nicht das Open-Close-Prinzip zum Hinzufügen hierarchischer Produktstrukturen, sondern das Open-Close-Prinzip für Produktfamiliendimensionen (z. B. Audi-Autos).

5. Modusbeschränkungen

Es eignet sich zum Generieren einer miteinander verbundenen oder abhängigen Produktfamilie und unterstützt die Erweiterung in Richtung der Produktfamilie, ist jedoch nicht für die Produktebene geeignet Richtung.

6. Variationen und Erweiterungen von Mustern

1. Die abstrakte Fabrik stellt eine statische Fabrikmethode bereit: Die abstrakte Fabrik kann eine statische Fabrikmethode bereitstellen, die über Parameter zurückgegeben wird Instanz einer konkreten Fabrik.

2. Zusammenführen der abstrakten Fabrik mit der spezifischen Fabrik: Wenn es in der Produktfamilienrichtung nur eine Produktfamilie gibt, ist die abstrakte Fabrik zu diesem Zeitpunkt nicht erforderlich Darüber hinaus können Sie eine statische Methode für diese spezifische Factory bereitstellen, die ihre eigene Instanz zurückgibt.

7. Beziehung zu anderen Mustern

Wenn es nur eine Produktebenenstruktur gibt, dann ist es das Factory-Methodenmuster, wie unten gezeigt:

Wenn es mehrere hierarchische Produktstrukturen gibt, ist jede Fabrikmethode in der abstrakten Fabrik ein „Fabrikmethoden“-Muster.

8. Vor- und Nachteile des Modells

Es unterstützt das Open-Close-Prinzip in Richtung Produktfamilie, unterstützt jedoch nicht das Open-Close-Prinzip in Richtung der Produkthierarchie.

Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung der abstrakten Fabrik in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn