[Read Effective Java] Kapitel 2 Punkt 1 "Betrachten Sie statische Factory-Methoden anstelle von Konstruktoren"

Einführung

Wenn Sie Ihr Verständnis von Java vertiefen möchten, lesen Sie dies, damit ich Effective Java lesen und es auf meine eigene Weise interpretieren kann. Ich lese die zweite Ausgabe, die ich gelesen habe. https://www.amazon.co.jp/EFFECTIVE-JAVA-Java-Joshua-Bloch/dp/4621066056/ref=pd_sbs_14_3/355-5139262-7829161?_encoding=UTF8&pd_rd_i=4621066056&pd_rd_r=ac861412-beae-43a8-872a-8b853aa69980&pd_rd_w=oIuWA&pd_rd_wg=nhmjU&pf_rd_p=7642417c-6494-4d06-a2b0-fcb0e0b3c563&pf_rd_r=HAEC02ASTQVJ4SPSM92Q&psc=1&refRID=HAEC02ASTQVJ4SPSM92Q

Betrachten Sie statische Factory-Methoden anstelle von Konstruktoren

Ich frage mich, ob es verschiedene Dinge gibt, die mich glücklich machen, wenn ich die mit dem Konstruktor implementierte Verarbeitung durch eine statische Factory-Methode ersetze.

Beispielcode

Beispiel 1



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

Beispiel 2



//Service Provider Framework
public interface Service{
    //Servicespezifische Methoden hier
}

//Service Provider-Schnittstelle
public interface Provider{
    Service newService();
}

//Nicht unveränderliche Klasse für die Registrierung und den Zugang von Diensten
public class Service{
    private Service(){} //Instanziierung unterdrücken (Punkt 4)

    //Verknüpfen Sie den Servicenamen mit dem Service
    private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();
    public static final String DEFAULT_PROVIDER_NAME = "<def>";

    //Anbieterregistrierungs-API
    public static void registerDefaultProvider(Provider p){
        registerProvider(DEFAULT_PROVIDER_NAME,p);
    }
    public static void registerProvider(String name,Provider p){
        providers.put(name,p);
    }

    //Service Access API
    public static Service newInstance(){
        return newInstance(DEFAULT_PROVIDER_NAME);
    }
    public static Service newInstance(String name){
        Provider p = providers.get(name);
        if (p == null)
            throw new IllegalArgumentException(
                    "Nn provider registered with name:" + name
            );
        return p.newService();
    }
    
}

Glossar

Konstrukteur

SampleClass instanceA = new SampleClass();

↑ Die Beschreibung von SampleClass () nach new ist der Aufruf des Konstruktors


public class SampleClass {
  //Konstrukteur
  public SampleClass(){
    System.out.println("Es ist ein Konstruktor");
  }
}

↑ Wenn dies neu ist, wird standardmäßig "Es ist ein Konstruktor" ausgegeben

static -Modifikatoren zum Erstellen instanzunabhängiger Methoden und Variablen

statische Fabrikmethode

Entwurfsmusterfabrikmethode

・ Obwohl der Name ähnlich ist, unterscheidet er sich von der statischen Factory-Methode. ・ Erklärung wird hier weggelassen

Schnittstelle

-Eine Schnittstelle ist eine Beschreibung einer "Variablen" oder eines "Methodentyps", ohne die spezifische Verarbeitung der Methode in die Klasse zu schreiben. -Die Bedingung ist, dass "alle Methoden abstrakte Methoden sind" und "im Grunde keine Felder haben".

4 Vor- und 2 Nachteile der statischen Fabrikmethode

Vorteil 1 Hat einen anderen Namen als der Konstruktor

-Der Konstruktor wird im Neuzustand ohne Erlaubnis ausgeführt. Wenn es sich jedoch um eine statische Factory-Methode handelt, erhält er einen schönen Namen, damit er besser lesbar ist.

Angenommen, es gibt einen Prozess, der eine BigInteger zurückgibt, die eine wahrscheinliche Primzahl ist.

-Wie schreibe ich in den Konstruktor

BigInteger(int, int, Random)

-Wie schreibe ich mit statischer Factory-Methode

BigInteger.probablePrime

… Welches ist leichter zu verstehen?

Vorteil 2 Im Gegensatz zum Konstruktor muss bei jedem Aufruf einer Methode kein neues Objekt erstellt werden.

・ Es ist natürlich, aber da es statisch ist, wird es zu nichts instanziiert. Muss neu sein, um den Konstruktor aufzurufen ・ Es ist nicht so gut, unnötig viele neue Objekte zu erstellen.

Vorteil 3 Im Gegensatz zum Konstruktor kann ein Objekt eines beliebigen Subtyps des Rückgabetyps der Methode zurückgegeben werden.

-Der Konstruktor gibt keinen Rückgabewert zurück, aber die statische Factory-Methode ist nur eine Methode, sodass sie zurückgegeben werden kann und somit flexibel ist. ・ Ein Dienstanbieter-Framework wie Beispiel 2 (den Inhalt ausgeblendet und als API verwendet) wird ebenfalls erstellt.

Vorteil 4 Reduziert den Aufwand für die Instanziierung parametrisierter Typen

・ Vereinfachtes Schreiben Zum Beispiel im Fall eines Konstruktors, was ich so schreiben musste

Map<String, List<String>> m =
  new HashMap<String, List<String>>();

Sie können dies als statische Factory-Methode schreiben

Map<String, List<String>> m = HashMap.newInstance();

Es ist einfach, nicht wahr?

Natürlich wird hinter den Kulissen die statische Factory-Methode so implementiert

public static <K, V> HashMap<K, V> newInstance() {
  return new HashMap<K. V>;
}

Nachteil 1 Es kann keine Unterklasse einer Klasse erstellt werden, die keinen öffentlichen oder geschützten Konstruktor hat

Nachteil 2 Sie sind nicht leicht von anderen statischen Methoden zu unterscheiden

Generischer Name für die statische Factory-Methode

Name Rolle
valueOf Gibt eine Instanz mit demselben Wert wie der Parameter zurück. Es handelt sich im Wesentlichen um eine Typkonvertierungsmethode.
of Alternative zu valueOf. Eine prägnantere.
getInstance Gibt die durch den Parameter angegebene Instanz zurück, hat jedoch nicht denselben Wert. Bei Singletons akzeptiert getInstance keine Argumente und gibt die einzige Instanz zurück.
newInstance Ähnlich wie getInstance, außer dass die einzelnen von newInstance zurückgegebenen Instanzen separate Instanzen sind.
getType Ähnlich wie getInstance, wird jedoch verwendet, wenn sich die Factory-Methode in einer anderen Klasse als die Zielklasse befindet. Typ gibt den Objekttyp an, der von der Factory-Methode zurückgegeben wird.
newType Ähnlich wie newInstance, wird jedoch verwendet, wenn sich die Factory-Methode in einer anderen Klasse als die Zielklasse befindet. Typ gibt den Objekttyp an, der von der Factory-Methode zurückgegeben wird.

Fortsetzen

[Read Effective Java] Kapitel 2 Punkt 2 "Betrachten Sie einen Builder, wenn Sie mit einer großen Anzahl von Konstruktorparametern konfrontiert werden." https://qiita.com/Natsukii/items/eb8fec0d8cae567f6647

Recommended Posts

[Read Effective Java] Kapitel 2 Punkt 1 "Betrachten Sie statische Factory-Methoden anstelle von Konstruktoren"
[Read Effective Java] Kapitel 3 Punkt 12 "Berücksichtigung der Implementierung von Comparable"
[Read Effective Java] Kapitel 2 Punkt 7 "Vermeiden Sie Finalizer"
[Read Effective Java] Kapitel 2 Punkt 5 "Vermeiden Sie die Erstellung unnötiger Objekte"
[Read Effective Java] Kapitel 3 Punkt 10 "Immer toString überschreiben"
[Read Effective Java] Kapitel 2 Punkt 2 "Betrachten Sie einen Builder, wenn Sie mit einer großen Anzahl von Konstruktorparametern konfrontiert werden."
[Read Effective Java] Kapitel 2 Punkt 6 "Veraltete Objektreferenzen entfernen"
Effektive Java 3rd Edition Kapitel 8 Methoden
[Read Effective Java] Kapitel 2 Punkt 4 "Unmöglichkeit der Instanziierung mit privatem Konstruktor erzwingen"
[Read Effective Java] Kapitel 3 Punkt 9 "Wenn Sie equals überschreiben, überschreiben Sie immer hashCode"
[Read Effective Java] Kapitel 3 Punkt 8 "Wenn Sie gleich überschreiben, befolgen Sie den allgemeinen Vertrag"
Effektives Java Kapitel 2
Punkt 90: Betrachten Sie Serialisierungs-Proxys anstelle von serialisierten Instanzen
Effektives Java Kapitel 6 34-35
Methodenname der statischen Factory-Methode, die aus Java 8 gelernt wurde
Effektives Java Kapitel 4 15-22
Effektives Java Kapitel 3
[Read Effective Java] Kapitel 2 Punkt 3 "Singleton-Eigenschaften mit privatem Konstruktor oder Aufzählungstyp erzwingen"
Effektive Java 3rd Edition Kapitel 3 Allen Objekten gemeinsame Methoden
[Java] Klassen, Konstruktoren, statische Elemente
Vorteile der statischen Java-Methode