Was sind statische Fabrikmethoden?

Was ist eine “statische Fabrik” -Methode?

Solutions Collecting From Web of "Was sind statische Fabrikmethoden?"

Wir vermeiden den direkten Zugriff auf databaseverbindungen, da sie ressourcenintensiv sind. Also verwenden wir eine statische Factory-Methode getDbConnection , die eine Verbindung herstellt, wenn wir unter dem Limit sind. Andernfalls versucht es eine “Ersatz” -Verbindung 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 availableConnections = new HashSet(); 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); //... } } 

Das statische Factory-Methodenmuster ist eine Möglichkeit, die Objekterstellung zu kapseln. Ohne eine Factory-Methode würden Sie einfach den Konstruktor der class 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 private gekennzeichnet, so dass sie nur innerhalb der class aufgerufen werden können, und die Factory-Methode ist als static markiert, sodass sie aufgerufen werden kann, ohne zuvor ein Objekt zu haben.

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 angeben, ohne eine möglicherweise komplexe classnhierarchie kennen oder verstehen zu müssen.

Ein weiterer Vorteil ist, wie Matthew und James gezeigt haben, der Zugriff auf eine begrenzte Ressource wie Verbindungen zu kontrollieren. Dies ist ein Weg, Pools wiederverwendbarer Objekte zu implementieren – anstatt ein Objekt zu bauen, zu benutzen und abzubauen, wenn die Konstruktion und Zerstörung kostspielige processe sind, könnte es sinnvoller sein, sie einmal zu bauen und zu recyceln. Die Factory-Methode kann ein vorhandenes, nicht verwendetes instanziiertes Objekt zurückgeben, wenn eines vorhanden ist, oder ein Konstrukt erstellen, wenn die Objektanzahl unter einem unteren Schwellenwert liegt, oder eine Ausnahme null oder null wenn sie über dem oberen Schwellenwert liegt.

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

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

und

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

Dies kann auch verwendet werden, um die Lesbarkeit zu verbessern, wie Rasmus bemerkt.

HINWEIS! “Die statische Fabrikmethode ist NICHT das selbe wie das Fabrikmethodenmuster ” (c) Wirksames Java, Joshua Bloch.

Factory-Methode: “Definieren Sie eine Schnittstelle zum Erstellen eines Objekts, aber lassen Sie die classn, die die Schnittstelle implementieren, entscheiden, welche class instanziiert werden soll. Die Factory-Methode lässt eine Instanziierung von classn auf Unterklassen” (c) GoF.

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

Der Unterschied:

Die Grundidee der statischen Factory-Methode besteht darin, Kontrolle über die Objekterstellung zu erlangen und sie vom Konstruktor an die statische Methode zu delegieren. Die Entscheidung des zu erstellenden Objekts ist wie in der abstrakten Fabrik außerhalb der Methode (im allgemeinen Fall, aber nicht immer). Während die Schlüssel (!) – Idee der Factory-Methode darin besteht, die Entscheidung darüber zu entscheiden, welche Instanz der class innerhalb der Factory-Methode erstellt werden soll. Zum Beispiel ist die klassische Singleton-Implementierung ein Spezialfall der statischen Fabrikmethode. Beispiel für häufig verwendete statische Factory-Methoden:

  • Wert von
  • bekomme Instanz
  • neueInstanz

Lesbarkeit kann durch statische Factory-Methoden verbessert werden:

Vergleichen

 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(); 
  • haben Namen, im Gegensatz zu Konstruktoren, die Code klären können.
  • Sie müssen bei jedem Aufruf kein neues Objekt erstellen. Objekte können bei Bedarf zwischengespeichert und wiederverwendet werden.
  • kann einen Subtyp ihres Rückgabetyps zurückgeben – insbesondere ein Objekt zurückgeben, dessen Implementierungsklasse dem Aufrufer unbekannt ist. Dies ist ein sehr nützliches und weit verbreitetes Merkmal in vielen Frameworks, die Schnittstellen als Rückgabetyp von statischen Fabrikmethoden verwenden.

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

Alles läuft auf Wartbarkeit hinaus. Der beste Weg, dies zu tun, ist, wenn Sie das new Schlüsselwort verwenden, um ein Objekt zu erstellen, Sie koppeln den Code, den Sie schreiben, an eine Implementierung.

Das Factory-Muster lässt Sie unterscheiden, wie Sie ein Objekt von dem erstellen, was Sie mit dem Objekt tun. Wenn Sie alle Ihre Objekte mithilfe von Konstruktoren erstellen, verketten Sie im Wesentlichen den Code, der das Objekt für diese Implementierung verwendet. Der Code, der Ihr Objekt verwendet, ist “abhängig” von diesem Objekt. Das scheint auf der Oberfläche nicht viel her zu sein, aber wenn sich das Objekt ändert (denken Sie daran, die Signatur des Konstruktors zu ändern oder das Objekt zu unterklassifizieren), müssen Sie zurückgehen und die Dinge überall neu verdrahten.

Heutzutage sind die Fabriken weitgehend zugunsten der Verwendung von Dependency Injection verdrängt worden, da sie eine große Anzahl von Kesseln erfordern, die sich als etwas schwierig zu halten erweisen. Dependency Injection ist im Wesentlichen äquivalent zu Factories, erlaubt Ihnen jedoch anzugeben, wie Ihre Objekte deklarativ verdrahtet werden (durch Konfiguration oder Anmerkungen).

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

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

Wir können kein Objekt für die obige class von außerhalb erstellen. Sie können also nicht von außerhalb der class auf x, y zugreifen. Was nutzt diese class dann?
Hier ist die Antwort: FACTORY- Methode.
Fügen Sie die folgende Methode in der obigen class hinzu

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

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

 Test t = Test.getObject(); 

Daher wird eine statische Methode, die das Objekt der class durch Ausführen ihres privaten Konstruktors zurückgibt, als FACTORY- Methode bezeichnet
.

Ich dachte, ich werde etwas Licht zu diesem Beitrag hinzufügen, was ich weiß. Wir haben diese Technik in unserem recent android project ausführlich genutzt. Anstatt creating objects using new operator Sie auch die static method , um eine class zu instanziieren. Code-Liste:

 //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 konditionaler Objekte : Jedes Mal, wenn Sie einen Konstruktor aufrufen, wird ein Objekt erstellt, aber das möchten Sie möglicherweise nicht. Angenommen, Sie möchten nur eine Bedingung überprüfen, dann möchten Sie ein neues Objekt erstellen. Sie würden nicht jedes Mal eine neue Instanz von Vinoth erstellen, es sei denn, Ihre Bedingung ist erfüllt.

Ein weiteres Beispiel aus Effective Java .

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

Diese Methode übersetzt einen booleschen Grundelementwert in eine Boolesche Objektreferenz. Die Methode Boolean.valueOf(boolean) zeigt uns, dass sie niemals ein Objekt erzeugt. Die Fähigkeit von static factory methods , dasselbe Objekt von wiederholten invocations ermöglicht es den classn, jederzeit eine strikte Kontrolle darüber zu haben, welche Instanzen existieren.

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

Calendar.getInstance () ist ein großartiges Beispiel für das Obige. Es erstellt abhängig vom Gebietsschema einen BuddhistCalendar , JapaneseImperialCalendar oder standardmäßig einen Georgian .

Ein anderes Beispiel, das ich denken könnte, ist das Singleton pattern , bei dem Sie Ihre Konstruktoren dazu bringen, eine eigene getInstance Methode zu erstellen, bei 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; } } 

Eine Factory-Methode Eine Methode, die die Instanziierung eines Objekts abstrahiert. Im Allgemeinen sind Factories hilfreich, wenn Sie wissen, dass Sie eine neue Instanz einer class benötigen, die eine Schnittstelle implementiert, die Implementierungsklasse jedoch nicht.

Dies ist nützlich, wenn Sie mit Hierarchien verwandter classn arbeiten, ein gutes Beispiel hierfür wäre ein GUI-Toolkit. Sie könnten einfach Aufrufe an die Konstruktoren für konkrete Implementierungen jedes Widgets programmieren, aber wenn Sie schon immer ein Toolkit gegen ein anderes austauschen wollten, müssten Sie viele Stellen ändern. Indem Sie eine Fabrik verwenden, reduzieren Sie die Menge an Code, die Sie ändern müssten.

Einer der Vorteile von Static factory besteht darin, dass diese API Objekte zurückgeben kann, ohne ihre classn öffentlich zu machen. Dies führte zu einer sehr kompakten API. In Java wird dies durch die Collections-class erreicht, die rund 32 classn versteckt, was die Collection-API sehr kompakt macht.

Eine statische Factory-Methode ist gut, wenn Sie sicherstellen möchten, dass nur eine einzelne Instanz die konkrete class zurückgibt, die verwendet werden soll.

In einer databaseverbindungsklasse möchten Sie beispielsweise möglicherweise nur eine class zum Erstellen der databaseverbindung verwenden. Wenn Sie sich für einen Wechsel von Mysql zu Oracle entscheiden, können Sie einfach die Logik in einer class ändern, und der Rest der Anwendung wird dies tun Verwenden Sie die neue Verbindung.

Wenn Sie das database-Pooling implementieren möchten, würden Sie dies auch tun, ohne den Rest der Anwendung zu beeinflussen.

Sie schützt den Rest der Anwendung vor Änderungen, die Sie möglicherweise an der Fabrik vornehmen.

Der Grund dafür, dass es statisch ist, ist, wenn Sie eine beschränkte Ressource (Anzahl von Socket-Verbindungen oder Datei-Handles) verfolgen wollen, dann kann diese class verfolgen, wie viele verteilt und zurückgegeben wurden, so dass Sie die begrenzte Ressource.

statisch

Ein Mitglied, das mit dem Schlüsselwort ‘statisch’ deklariert wurde.

Fabrikmethoden

Methoden, die neue Objekte erstellen und zurückgeben.

in Java

Die Programmiersprache ist relevant für die Bedeutung von “statisch”, nicht aber für die Definition von “Fabrik”.

Die Java-Implementierung enthält die Dienstklassen java.util.Arrays und java.util.Collections, die beide statische Factory-Methoden , Beispiele dafür und die folgenden Methoden enthalten :

  • Arrays.asList("1","2","3")

  • Collections.synchronizedList(..), Collections.emptyList(), Collections.unmodifiableList(...) (Nur einige Beispiele, könnte Javadocs für mehr Methoden Beispiele https://docs.oracle.com/javase/8/docs/ überprüfen api / java / util / Sammlungen.html )

Auch die class java.lang.String hat 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 classn eingeschränkt sein, um sicherzustellen, dass Instanzen nicht extern erstellt werden) besteht darin, dass Sie instanzgesteuerte classn erstellen können. Und instanzgesteuerte classn garantieren, dass keine zwei gleichen unterschiedlichen Instanzen existieren ( a.equals (b) genau dann, wenn a == b ) während der Ausführung Ihres Programms, dh Sie können die Gleichheit von Objekten mit == operator anstelle der equals- Methode überprüfen , nach Effektivem Java.

Die Fähigkeit von statischen Factory-Methoden, dasselbe Objekt von wiederholten Aufrufen zurückzugeben, ermöglicht es den classn, jederzeit eine strikte Kontrolle darüber zu haben, welche Instanzen existieren. classn, die dies tun, werden als instanzgesteuert bezeichnet. Es gibt mehrere Gründe, instanzgesteuerte classn zu schreiben. Instanzkontrolle ermöglicht einer class zu garantieren, dass es ein Singleton (Item 3) oder nicht instantiable (Item 4) ist. Außerdem erlaubt es einer unveränderlichen class (Item 15), die Garantie zu geben, dass keine zwei gleichen Instanzen existieren: a.equals (b) genau dann, wenn a == b. Wenn eine class diese Garantie übernimmt, können ihre Clients den Operator == anstelle der Methode equals (Object) verwenden, was zu einer verbesserten performance führen kann. Enum-Typen (Artikel 30) bieten diese Garantie.

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