[JAVA] Eine Geschichte über das Erstellen eines Builders, der den Builder erbt

Einführung

Es ist natürlich, wenn Sie ruhig denken, aber ich habe einen Moment darüber nachgedacht, also als Memo ...

Mach einen Builder

Es gibt eine "Quadrat" -Klasse mit vertikalen und horizontalen Längen in den Feldern, wobei "Getetter" / "Setter" weggelassen wird.

Square.java


public class Square {
  private int width;
  private int height;
}

Wenn Sie es ermöglichen, den Wert mit "Builder" festzulegen und eine Klasse zu erstellen, die den Bereich am Ende zurückgibt, ist dies wie folgt.

SquareBuilder.java


public class SquareBuilder {

  public static class Builder {

    Square square = new Square();

    public Builder() {}

    public Builder width(int width) {
      square.setWidth(width);
      return this;
    }

    public Builder height(int height) {
      square.setHeight(height);
      return this;
    }

    public int build() {
      return square.getWidth() * square.getHeight();
    }
  }
}

Dann können Sie den Bereich wie diesen finden

Main.java


public class Main {
  public static void main(String[] args) {
    SquareBuilder.Builder squareBuilder = new SquareBuilder.Builder();
    System.out.println("Bereich ist:" + squareBuilder.width(5).height(10).build());
  }
}

Bisher gibt es kein besonderes Problem. : mild_smile:

Erstellen Sie einen Builder, der den Builder erbt

Erstellen Sie als Nächstes eine "Cube" -Klasse, die von "Square" erbt. (Lassen Sie Getter / Setter weg.)

Cube.java


public class Cube extends Square {
  private int depth;
}

Abgesehen davon, ob die Höhe "Tiefe" war ...: Küssen: Es erbt auch "Builder"

CubeBuilder.java


public class CubeBuilder extends SquareBuilder {

  public static class Builder extends SquareBuilder.Builder {

    private Cube cube = new Cube();

    public Builder() {}

    public Builder depth(int depth) {
      cube.setDepth(depth);
      return this;
    }

    @Override
    public int build() {
      return super.build() * cube.getDepth();
    }
  }
}

Dann können Sie die Lautstärke wie folgt finden.

Main.java


public class Main {
  public static void main(String[] args) {
    CubeBuilder.Builder cubeBuilder = new CubeBuilder.Builder();
    System.out.println("Lautstärke ist:" + cubeBuilder.depth(2).width(5).height(10).build());
  }
}

Dieser Code durchläuft die Kompilierung und erfordert Volumen, ist aber tatsächlich ein Problem. Sie müssen zuerst "depth ()" aufrufen, um das Volume zu finden. : besorgt:

Der Grund dafür ist, dass die Rückgabewerte von "width ()" und "height ()" vom Typ "SquareBuilder.Builder" sind. Sie können also nicht "depth ()" aufrufen, das nur in "CubeBuilder.Builder" definiert ist. ..

Wir werden hier Generika verwenden.

Referenz: Unterklasse einer Java Builder-Klasse

SquareBuilder.java


public class SquareBuilder {

  public static class Builder<T extends Builder<T>> {

    Square square = new Square();

    public Builder() {}

    public T width(int width) {
      square.setWidth(width);
      return (T) this;
    }

    public T height(int height) {
      square.setHeight(height);
      return (T) this;
    }

    public int build() {
      return square.getWidth() * square.getHeight();
    }
  }
}

CubeBuilder.java


public class CubeBuilder extends SquareBuilder {

  public static class Builder extends SquareBuilder.Builder<Builder> {

    private Cube cube = new Cube();

    public Builder() {}

    public Builder depth(int depth) {
      cube.setDepth(depth);
      return this;
    }

    @Override
    public int build() {
      return super.build() * cube.getDepth();
    }
  }
}

Infolgedessen ist der Rückgabetyp von "width ()" und "height ()" nicht "SquareBuilder.Builder", sondern eine Klasse, die "SquareBuilder.Builder" erbt. Daher muss zuerst "depth ()" aufgerufen werden. verlieren.

Main.java


public class Main {
  public static void main(String[] args) {
    SquareBuilder.Builder squareBuilder = new SquareBuilder.Builder();
    System.out.println("Bereich ist:" + squareBuilder.width(5).height(10).build());

    CubeBuilder.Builder cubeBuilder = new CubeBuilder.Builder();
    System.out.println("Lautstärke ist:" + cubeBuilder.width(5).height(10).depth(2).build());
  }
}

Ich fühle mich jedoch etwas unwohl, weil es eine Warnung gibt. : mask:

Hintergrund der Veröffentlichung

Es ist ein Programm, das Werte in POJO einfügt, das viele Felder enthält und diese im JSON-Format ausgibt. Daher wurde es schwierig, Werte einzeln in "Setter" einzufügen, und ich war süchtig nach "Builder".

Bonus

In diesem Beispiel kann die Fläche nicht berechnet werden, aber Sie können die Warnung beseitigen, indem Sie "SquareBuilder" zu einer abstrakten Klasse machen.

SquareBuilder.java


public class SquareBuilder {

  public abstract static class Builder<T extends Builder<T>> {

    Square square = new Square();

    public Builder() {}

    public abstract T getThis();

    public T width(int width) {
      square.setWidth(width);
      return getThis();
    }

    public T height(int height) {
      square.setHeight(height);
      return getThis();
    }

    public int build() {
      return square.getWidth() * square.getHeight();
    }
  }
}

CubeBuilder.java


public class CubeBuilder extends SquareBuilder {

  public static class Builder extends SquareBuilder.Builder<Builder> {

    private Cube cube = new Cube();

    public Builder() {}

    @Override
    public Builder getThis() {
      return this;
    }

    public Builder depth(int depth) {
      cube.setDepth(depth);
      return this;
    }

    @Override
    public int build() {
      return super.build() * cube.getDepth();
    }
  }
}

Recommended Posts

Eine Geschichte über das Erstellen eines Builders, der den Builder erbt
Eine Geschichte über die Herstellung eines Taschenrechners zur Berechnung der Muschelhügelrate
Eine Geschichte über das JDK in der Java 11-Ära
Eine Geschichte über die Einführung von Evolutions in das Play Framework
Eine Geschichte darüber, wie catkin_make von Rosjava offline kompatibel gemacht wird
Eine Geschichte darüber, wie Spring + Hibernate + MySQL-Apps die Replikation unterstützen
Ein Murmeln über die Utility-Klasse
Eine Geschichte über das Erreichen der League Of Legends-API mit JAVA
Eine Geschichte, die mit der Einführung von Web Apple Pay zu kämpfen hatte
Die Geschichte, dass Tomcat in Eclipse unter einem Timeout-Fehler litt
Die Geschichte eines Othello-Spiels vom Kommunikationstyp mit Scala.
Die Geschichte, ein Projekt zu bauen, das Maven mit Ant gebaut hat
Die Geschichte eines Game Launcher mit automatischer Ladefunktion [Java]
Die Geschichte der Schaffung eines Dienstes, der die Geschichte des Portfolios erzählt, indem er sich allein entwickelt
Eine Geschichte über ein in Java geschriebenes Spring Boot-Projekt, das Kotlin unterstützt
Wie man IGV mit Socket-Kommunikation bedient und wie man einen Ruby Gem mit dieser Methode herstellt
[Java] Implementieren Sie eine Funktion, die eine im Builder-Muster implementierte Klasse verwendet
Eine Geschichte über das Senden einer Pull-Anfrage an MinGW, um die libgr-Version zu aktualisieren
Die Geschichte eines arithmetischen Überlaufs, der in Ruby nicht auftreten sollte
Die Geschichte einer Android-Anwendung, mit der die Abtastfrequenz des Beschleunigungssensors angepasst werden kann
Eine Geschichte über einen Super-Anfänger, der zum ersten Mal am AtCoder-Wettbewerb teilnimmt (AtCoder-Anfängerwettbewerb 140)
Shell-Skript zum Erstellen der Quelle von OpenJDK11
Eine Geschichte über die Java 11-Unterstützung für Webdienste
Eine Geschichte, die Geschäftslogik und Modell trennt
Eine Geschichte, die Zeit brauchte, um eine Verbindung herzustellen
Eine Geschichte darüber, wie eine vorhandene Docker-Datei mit der GPU kompatibel gemacht werden kann
Eine sehr nützliche Geschichte über Rubys Struct-Klasse
So erstellen Sie eine Klasse, die Klasseninformationen erbt
Die Geschichte, dass link_to tief ist (Ursache unbekannt)
Die Geschichte des Versuchs, JAVA File zu bedienen
Beschreibung, die es nur für Poster zugänglich macht
Über die echte Sommerzeit
Ein Memo über den Fluss von Rails und Vue
Die Geschichte eines neuen Ingenieurs, der einen leidenschaftlichen Programmierer liest
Eine Geschichte über das Erstellen eines Dienstes, der mithilfe einer API für maschinelles Lernen Verbesserungen an einer Website vorschlägt
Über die Methode
Über das Paket
Eine Geschichte über die Verwendung einer HTTP-Ablaufverfolgung mit Charles, um herauszufinden, welche Anforderungen die Java-Bibliothek an Slack stellt
[PHP] Geschichte der Ausgabe von PDF mit TCPDF + FPDI
Eine Geschichte über den Versuch, mit Mockito auszukommen
Eine Geschichte über das Bemühen, JAR-Dateien zu dekompilieren
Eine Geschichte über die Reduzierung des Speicherverbrauchs auf 1/100 mit find_in_batches
Builder-Muster, das eine Reihe erforderlicher Eigenschaften erzwingt
Über die Sache, dass hidden_field wahnsinnig benutzt werden kann
Ein Befehl, der die lokale Docker-Umgebung definitiv bereinigt
Eine Geschichte über die Entwicklung von ROS namens Rosjava mit Java
Über eine Doppelschleife, die eine For-Anweisung in eine For-Anweisung einfügt
Die Geschichte des Startens einer Java-bezogenen Lesesitzung für Neulinge
Die Geschichte, Dr. Orchid mit LINE BOT zu machen
Die Geschichte von dto, dao-like mit Java, SQLite
Die Geschichte, dass das erzwungene Update nicht implementiert werden konnte
Die Geschichte, dass .java auch in Unity 2018 erstellt wurde
Ein Memo des Programms, mit dem Sie feststellen können, dass die Wahrscheinlichkeit eines Würfelwurfs etwa 1/6 beträgt