it-swarm.com.de

Was sind statische Fabrikmethoden?

Was ist eine "statische Fabrik" -Methode?

224
freddiefujiwara

Wir vermeiden den direkten Zugriff auf Datenbankverbindungen, da sie ressourcenintensiv sind. Wir verwenden also eine statische Factory-Methode getDbConnection, die eine Verbindung erstellt, wenn wir die Grenze unterschreiten. Andernfalls wird versucht, eine "Ersatzverbindung" bereitzustellen, die mit einer Ausnahme fehlschlägt, wenn keine vorhanden ist.

public class DbConnection{
   private static final int MAX_CONNS = 100;
   private static int totalConnections = 0;

   private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();

   private DbConnection(){
     // ...
     totalConnections++;
   }

   public static DbConnection getDbConnection(){

     if(totalConnections < MAX_CONNS){
       return new DbConnection();

     }else if(availableConnections.size() > 0){
         DbConnection dbc = availableConnections.iterator().next();
         availableConnections.remove(dbc);
         return dbc;

     }else {
         throw new NoDbConnections();
     }
   }

   public static void returnDbConnection(DbConnection dbc){
     availableConnections.add(dbc);
     //...
   }
}
109

Das static Factory-Methodenmuster ist eine Möglichkeit, die Objekterstellung zu kapseln. Ohne eine Factory-Methode würden Sie einfach den Konstruktor der Klasse direkt aufrufen: Foo x = new Foo(). Mit diesem Muster würden Sie stattdessen die Factory-Methode aufrufen: Foo x = Foo.create(). Die Konstruktoren sind als privat gekennzeichnet, sodass sie nur von innerhalb der Klasse aus aufgerufen werden können. Die Factory-Methode ist als static markiert, sodass sie aufgerufen werden kann, ohne dass zuvor ein Objekt vorhanden ist.

Dieses Muster hat einige Vorteile. Zum einen kann die Factory aus vielen Unterklassen (oder Implementierern einer Schnittstelle) auswählen und diese zurückgeben. Auf diese Weise kann der Aufrufer das gewünschte Verhalten über Parameter festlegen, ohne eine potenziell komplexe Klassenhierarchie kennen oder verstehen zu müssen.

Ein weiterer Vorteil besteht darin, wie Matthew und James hervorgehoben haben, den Zugriff auf eine begrenzte Ressource wie Verbindungen zu kontrollieren. Dies ist ein Weg, um Pools wiederverwendbarer Objekte zu implementieren - anstatt ein Objekt zu bauen, zu verwenden und abzureißen. Wenn das Bauen und die Zerstörung teure Prozesse sind, kann es sinnvoller sein, sie einmal zu bauen und zu recyceln. Die Factory-Methode kann ein vorhandenes, unbenutztes instanziiertes Objekt zurückgeben, wenn ein Objekt vorhanden ist, oder ein Objekt erstellen, wenn die Objektanzahl unter einem unteren Schwellenwert liegt, oder eine Ausnahme auslösen oder null zurückgeben, wenn es über dem oberen Schwellenwert liegt.

Laut dem Artikel auf Wikipedia erlauben mehrere Factory-Methoden auch unterschiedliche Interpretationen ähnlicher Argumenttypen. Normalerweise hat der Konstruktor denselben Namen wie die Klasse, was bedeutet, dass Sie nur einen Konstruktor mit einer gegebenen Signatur haben können. Fabriken sind nicht so eingeschränkt, was bedeutet, dass Sie zwei verschiedene Methoden haben können, die dieselben Argumenttypen akzeptieren: 

Coordinate c = Coordinate.createFromCartesian(double x, double y)

und 

Coordinate c = Coordinate.createFromPolar(double distance, double angle)

Dies kann auch zur Verbesserung der Lesbarkeit verwendet werden, wie Rasmus Hinweise.

438
Jason Owen

HINWEIS! "Die statische Factory-Methode istNICHTdas gleiche wie das Factory-Methode - Muster" (c) Effective Java, Joshua Bloch.

Factory-Methode: "Definieren Sie eine Schnittstelle zum Erstellen eines Objekts, aber lassen Sie die Klassen, die die Schnittstelle implementieren, entscheiden, welche Klasse instanziiert werden soll. Die Factory-Methode lässt eine Klasse die Instantiierung auf Unterklassen verschieben" (c) GoF.

"Die statische Factory-Methode ist einfach eine statische Methode, die eine Instanz einer Klasse zurückgibt." (c) Wirksames Java, Joshua Bloch. Normalerweise befindet sich diese Methode in einer bestimmten Klasse.

Der Unterschied:

Die Schlüsselidee der statischen Factory-Methode besteht darin, die Kontrolle über die Objekterstellung zu erlangen und sie vom Konstruktor an die statische Methode zu delegieren. Die Entscheidung, ob ein Objekt erstellt werden soll, wird wie in Abstract Factory außerhalb der Methode gemacht (in der Regel jedoch nicht immer). Die Schlüsselidee (!) Von Factory Method ist die Delegierung der Entscheidung, welche Instanz der Klasse in Factory Method erstellt werden soll. Z.B. Die klassische Singleton-Implementierung ist ein Spezialfall der statischen Factory-Methode. Beispiel für häufig verwendete statische Factory-Methoden:

  • wert von 
  • bekomme Instanz 
  • newInstance
149

Die Lesbarkeit kann durch statische Factory-Methoden verbessert werden:

Vergleichen Sie

public class Foo{
  public Foo(boolean withBar){
    //...
  }
}

//...

// What exactly does this mean?
Foo foo = new Foo(true);
// You have to lookup the documentation to be sure.
// Even if you remember that the boolean has something to do with a Bar
// you might not remember whether it specified withBar or withoutBar.

zu

public class Foo{
  public static Foo createWithBar(){
    //...
  }

  public static Foo createWithoutBar(){
    //...
  }
}

// ...

// This is much easier to read!
Foo foo = Foo.createWithBar();
67
Rasmus Faber
  • haben im Gegensatz zu Konstruktoren Namen, die den Code verdeutlichen können.
  • es muss nicht bei jedem Aufruf ein neues Objekt erstellt werden - Objekte kann bei Bedarf zwischengespeichert und wiederverwendet werden.
  • kann einen Subtyp ihres Rückgabetyps zurückgeben - kann insbesondere Rückgabe eines Objekts, dessen Implementierungsklasse dem Aufrufer nicht bekannt ist . Dies ist ein sehr wertvolles und in vielen Frameworks weit verbreitetes Feature welche Schnittstellen als Rückgabetyp statischer Factory-Methoden verwenden.

aus http://www.javapractices.com/topic/TopicAction.do?Id=21

20
soldier.moth

Auf die Wartbarkeit kommt es an. Um dies besser auszudrücken, müssen Sie immer dann, wenn Sie mit dem Schlüsselwort new ein Objekt erstellen, den von Ihnen geschriebenen Code an eine Implementierung koppeln.

Mit dem Factory-Muster können Sie die Erstellung eines Objekts von dem unterscheiden, was Sie mit dem Objekt tun. Wenn Sie alle Objekte mithilfe von Konstruktoren erstellen, verkabeln Sie im Wesentlichen den Code, der das Objekt verwendet, mit der Implementierung. Der Code, der Ihr Objekt verwendet, ist von diesem Objekt "abhängig". Dies scheint auf der Oberfläche nicht viel zu sein, aber wenn sich das Objekt ändert (denken Sie daran, die Signatur des Konstruktors zu ändern oder das Objekt zu untergliedern), müssen Sie alles zurückverwandeln.

Heutzutage sind Fabriken weitgehend für die Verwendung von Dependency Injection gestrichen worden, da sie viel Kesselplattencode erfordern, der sich als etwas schwierig erweisen kann. Abhängigkeitseinspritzung entspricht im Wesentlichen Fabriken, Sie können jedoch festlegen, wie Ihre Objekte deklarativ miteinander verbunden werden (durch Konfiguration oder Anmerkungen).

18
cwash

Wenn der Konstruktor einer Klasse privat ist, können Sie kein Objekt für eine Klasse von außerhalb erstellen. 

class Test{
 int x, y;
 private Test(){
  .......
  .......
  }
}

Wir können kein Objekt für eine übergeordnete Klasse von außerhalb erstellen. Sie können also nicht auf x, y von außerhalb der Klasse zugreifen. Was nützt dann diese Klasse? 
Hier ist die Antwort: FABRIK Methode.
Fügen Sie die untenstehende Methode in der obigen Klasse hinzu 

public static Test getObject(){
  return new Test();
}

Sie können jetzt ein Objekt für diese Klasse von außerhalb erstellen. Wie der Weg ...

Test t = Test.getObject();

Daher wird eine statische Methode aufgerufen, die das Objekt der Klasse durch Ausführen ihres privaten Konstruktors zurückgibt FABRIK Methode
.

10
Santhosh

Ich dachte, ich werde diesem Beitrag etwas Licht hinzufügen, was ich weiß. Wir haben diese Technik in unserem recent Android project ausgiebig angewendet. Anstelle von creating objects using new operator können Sie auch static method verwenden, um eine Klasse zu instanziieren. Code-Auflistung:

//instantiating a class using constructor
Vinoth vin = new Vinoth(); 

//instantiating the class using static method
Class Vinoth{
  private Vinoth(){
  }
  // factory method to instantiate the class
  public static Vinoth getInstance(){
    if(someCondition)
        return new Vinoth();
  }
}

Statische Methoden unterstützen die Erstellung von bedingten Objekten : Jedes Mal, wenn Sie einen Konstruktor aufrufen, wird ein Objekt erstellt, aber das möchten Sie möglicherweise nicht. Angenommen, Sie möchten einige Bedingungen nur prüfen, wenn Sie ein neues Objekt erstellen möchten. Sie würden nicht jedes Mal eine neue Instanz von Vinoth erstellen, es sei denn, Ihre Bedingung ist erfüllt. 

Ein anderes Beispiel aus Effective Java .

public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
}

Diese Methode übersetzt einen booleschen Grundwert in eine boolesche Objektreferenz. Die Boolean.valueOf(boolean)-Methode veranschaulicht uns, sie erstellt niemals ein Objekt. Die Möglichkeit von static factory methods, dasselbe Objekt aus wiederholten invocations zurückzugeben, ermöglicht Klassen, jederzeit die strikte Kontrolle darüber zu haben, welche Instanzen vorhanden sind.

Static factory methods ist, dass sie im Gegensatz zu constructors eine object einer beliebigen subtype ihres Rückgabetyps zurückgeben können. Eine Anwendung dieser Flexibilität besteht darin, dass eine API Objekte zurückgeben kann, ohne dass ihre Klassen öffentlich gemacht werden. Das Ausblenden von Implementierungsklassen auf diese Weise führt zu einer sehr kompakten API.

Calendar.getInstance () ist ein hervorragendes Beispiel für das Vorstehende. Es erstellt abhängig von der Ländereinstellung eine BuddhistCalendar, JapaneseImperialCalendar oder standardmäßig eine Georgian.

Ein anderes Beispiel, das ich mir vorstellen könnte, ist Singleton pattern, wo Sie Ihre Konstruktoren dazu bringen, eine eigene getInstance-Methode zu erstellen, in der Sie sicherstellen, dass immer nur eine Instanz verfügbar ist. 

public class Singleton{
    //initailzed during class loading
    private static final Singleton INSTANCE = new Singleton();

    //to prevent creating another instance of Singleton
    private Singleton(){}

    public static Singleton getSingleton(){
        return INSTANCE;
    }
}
8
Thalaivar

Eine Factory-Methode Eine Methode, die die Instantiierung eines Objekts abstrahiert. Im Allgemeinen sind Fabriken nützlich, wenn Sie wissen, dass Sie eine neue Instanz einer Klasse benötigen, die eine Schnittstelle implementiert, die implementierende Klasse jedoch nicht kennen.

Dies ist nützlich, wenn Sie mit Hierarchien verwandter Klassen arbeiten. Ein gutes Beispiel hierfür ist ein GUI-Toolkit. Sie könnten einfach Aufrufe an die Konstrukteure für konkrete Implementierungen jedes Widgets hartcodieren. Wenn Sie jedoch ein Toolkit gegen ein anderes austauschen möchten, haben Sie viele Orte, an denen Sie Änderungen vornehmen können. Durch die Verwendung einer Factory reduzieren Sie die Menge an Code, die Sie ändern müssen.

4
Bryan Kyle

Static Factory bietet den Vorteil, dass diese API Objekte zurückgeben kann, ohne dass ihre Klassen öffentlich gemacht werden. Dies führt zu einer sehr kompakten API. In Java wird dies durch die Collections-Klasse erreicht, die etwa 32 Klassen verbirgt, was die Collection-API sehr kompakt macht.

3
Rakesh Chauhan

statisch

Ein Mitglied wurde mit dem Schlüsselwort 'static' deklariert.

fabrikmethoden

Methoden, die neue Objekte erstellen und zurückgeben.

in Java

Die Programmiersprache ist für die Bedeutung von 'statisch' relevant, nicht jedoch für die Definition von 'Fabrik'.

1
user207421

Eine statische Factory-Methode ist sinnvoll, wenn Sie sicherstellen möchten, dass nur eine einzige Instanz die zu verwendende konkrete Klasse zurückgibt.

In einer Datenbankverbindungsklasse möchten Sie beispielsweise, dass nur eine Klasse die Datenbankverbindung erstellt. Wenn Sie sich also für den Wechsel von Mysql zu Oracle entscheiden, können Sie einfach die Logik in einer Klasse ändern. Der Rest der Anwendung wird dies tun Verwenden Sie die neue Verbindung.

Wenn Sie das Datenbank-Pooling implementieren möchten, würde dies auch ohne Auswirkungen auf den Rest der Anwendung erfolgen.

Sie schützt den Rest der Anwendung vor Änderungen, die Sie an der Fabrik vornehmen können. Dies ist der Zweck.

Der Grund dafür, dass es statisch ist, ist, wenn Sie eine begrenzte Ressource (Anzahl der Socket-Verbindungen oder Dateikennungen) verfolgen möchten, dann kann diese Klasse nachverfolgen, wie viele übergeben und zurückgegeben wurden, damit Sie das nicht erschöpfen begrenzte Ressource.

1
James Black

Java-Implementierung enthält Dienstprogrammklassen Java.util.Arrays und Java.util.Collections Beide enthalten statische Factory-Methoden , Beispiele und Anleitungen:

Auch Java.lang.String haben solche statischen Factory-Methoden :

  • String.format(...), String.valueOf(..), String.copyValueOf(...)

Einer der Vorteile der statischen Factory-Methoden mit privatem Konstruktor (die Objekterstellung muss für externe Klassen eingeschränkt sein, um sicherzustellen, dass Instanzen nicht extern erstellt werden) besteht darin, dass Sie instanzgesteuerte Klassen erstellen können. Instanzgesteuerte Klassen garantieren, dass keine zwei gleich unterschiedlichen Instanzen existieren ( a.equals (b) wenn und nur wenn a == b ) während des Programmlaufs ausgeführt wird. Dies bedeutet, dass Sie die Gleichheit von Objekten mit = prüfen können = Operator anstelle von gleich Methode gemäß Effective Java.

Die Fähigkeit statischer Factory-Methoden, dasselbe Objekt aus .__ zurückzugeben. Wiederholte Aufrufe ermöglichen Klassen eine strikte Kontrolle über Welche Instanzen gibt es zu jeder Zeit? Klassen, die dies tun, werden als .__ bezeichnet. Instanzgesteuert. Es gibt mehrere Gründe, zu schreiben Instanzgesteuerte Klassen. Instanzsteuerung erlaubt es einer Klasse garantieren, dass es sich um ein Singleton (Element 3) oder nicht unveränderlich (Element 4) handelt. Außerdem kann eine unveränderliche Klasse (Punkt 15) die Garantie abgeben dass es keine zwei gleichen Instanzen gibt: a.equals (b) wenn und nur wenn a == b. Ob Wenn eine Klasse diese Garantie übernimmt, können ihre Clients den Operator == .__ verwenden. anstelle der Methode equals (Object), die zu einer Verbesserung von .__ führen kann. Performance. Aufzählungstypen (Artikel 30) geben diese Garantie ab.

Aus effektivem Java, Joshua Bloch (Artikel 1, Seite 6)

0