[JAVA] Une histoire sur la création d'un Builder qui hérite du Builder

introduction

C'est naturel si vous réfléchissez calmement, mais j'y ai pensé un instant, donc comme mémo ...

Faire un constructeur

Il existe une classe Square qui a des longueurs verticales et horizontales dans les champs, en omettant Getetter / Setter.

Square.java


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

Si vous permettez de définir la valeur à l'aide de Builder et de créer une classe qui renvoie la zone à la fin, ce sera comme suit.

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();
    }
  }
}

Ensuite, vous pouvez trouver la zone comme celle-ci

Main.java


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

Il n'y a pas de problème particulier pour l'instant. : léger_sourire:

Créer un générateur qui hérite du générateur

Ensuite, créez une classe Cube qui hérite de Square. (Omettez Getter / Setter.)

Cube.java


public class Cube extends Square {
  private int depth;
}

Mis à part si la hauteur était `` profondeur '' ...: baisers: Il hérite également de 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();
    }
  }
}

Ensuite, vous pouvez trouver le volume comme celui-ci.

Main.java


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

Ce code passe par la compilation et nécessite du volume, mais c'est en fait un problème. Vous devez d'abord appeler depth () pour trouver le volume. : inquiet:

La raison est que les valeurs de retour de «width ()» et «height ()» sont de type «SquareBuilder.Builder», vous ne pouvez donc pas appeler «depth ()», qui est défini uniquement dans «CubeBuilder.Builder». ..

Nous utiliserons ici des génériques.

Référence: Sous-classification d'une classe Java Builder

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();
    }
  }
}

En conséquence, le type de retour de width () et height () sera une classe qui hérite deSquareBuilder.Builder au lieu de SquareBuilder.Builder, il est donc nécessaire d'appeler depth () en premier. perdre.

Main.java


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

    CubeBuilder.Builder cubeBuilder = new CubeBuilder.Builder();
    System.out.println("Le volume est:" + cubeBuilder.width(5).height(10).depth(2).build());
  }
}

Cependant, je me sens un peu mal à l'aise car il y a un avertissement. : masque:

Contexte de l'affichage

C'est un programme qui met des valeurs dans POJO qui a beaucoup de champs et qui les affiche au format JSON, il est donc devenu difficile de mettre les valeurs dans Setter une par une, et j'étais accro à l'utilisation de Builder.

prime

Dans cet exemple, la zone ne peut pas être calculée, mais Warning peut être éliminé en faisant de SquareBuilder une classe abstraite.

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

Une histoire sur la création d'un Builder qui hérite du Builder
Une histoire sur la fabrication d'une calculatrice pour calculer le taux de monticule d'obus
Une histoire sur le JDK à l'ère de Java 11
Une histoire sur l'introduction d'Evolutions dans le cadre de jeu
Une histoire de rendre catkin_make de rosjava compatible hors ligne
Une histoire sur la prise en charge de la réplication par les applications Spring + Hibernate + MySQL
Un murmure sur la classe utilitaire
Une histoire sur l'utilisation de l'API League Of Legends avec JAVA
Une histoire qui a eu du mal avec l'introduction de Web Apple Pay
L'histoire que Tomcat a souffert d'une erreur de timeout dans Eclipse
L'histoire de la création d'un jeu d'Othello de type communication avec Scala.
L'histoire de rendre possible la construction d'un projet qui a été construit par Maven avec Ant
L'histoire de la création d'un lanceur de jeu avec une fonction de chargement automatique [Java]
L'histoire de la création d'un service qui raconte l'histoire du portfolio en se développant seul
Une histoire sur un projet Spring Boot écrit en Java qui prend en charge Kotlin
Comment faire fonctionner IGV en utilisant la communication par socket, et l'histoire de la création d'un Ruby Gem en utilisant cette méthode
[Java] Implémenter une fonction qui utilise une classe implémentée dans le modèle Builder
Une histoire sur l'envoi d'une pull request à MinGW pour mettre à jour la version libgr
L'histoire de la rencontre d'un débordement arithmétique qui ne devrait pas être rencontré dans Ruby
L'histoire de la création d'une application Android capable d'ajuster la fréquence d'échantillonnage du capteur d'accélération
L'histoire d'un super débutant participant pour la première fois au concours AtCoder (AtCoder Beginner Contest 140)
Script Shell pour construire la source d'OpenJDK11
Une histoire sur la prise en charge de Java 11 pour les services Web
Une histoire qui sépare la logique métier et le modèle
Une histoire qui a mis du temps à établir une connexion
Une histoire sur la compatibilité d'un Dockerfile existant avec le GPU
Une histoire très utile sur la classe Struct de Ruby
Comment créer une classe qui hérite des informations de classe
L'histoire que link_to est profonde (cause inconnue)
Histoire d'essayer de faire fonctionner le fichier JAVA
Description qui le rend accessible uniquement aux affiches
À propos de l'heure d'été réelle
Un mémo sur le flux de Rails et Vue
L'histoire d'un nouvel ingénieur lisant un programmeur passionné
Une histoire sur la création d'un service qui propose des améliorations à un site Web à l'aide d'une API d'apprentissage automatique
À propos de la méthode
À propos du paquet
Une histoire de prise d'une trace HTTP à l'aide de Charles pour savoir quelles demandes la bibliothèque Java fait à Slack
[PHP] Histoire de la sortie de PDF avec TCPDF + FPDI
Une histoire d'essayer de s'entendre avec Mockito
Une histoire sur l'effort de décompiler les fichiers JAR
Une histoire sur la réduction de la consommation de mémoire à 1/100 avec find_in_batches
Modèle de générateur qui force un ensemble de propriétés requises
À propos du problème que hidden_field peut être utilisé de manière insensée
Une commande qui nettoie définitivement l'environnement docker local
Une histoire sur le développement de ROS appelé rosjava avec java
À propos d'une double boucle qui place une instruction For dans une instruction For
L'histoire du démarrage d'une session de lecture sur Java pour les nouveaux arrivants
L'histoire de la création de Dr.Orchid avec LINE BOT
L'histoire de la création de DTO, semblable à Dao avec Java, SQLite
L'histoire selon laquelle la mise à jour forcée n'a pas pu être mise en œuvre
L'histoire que .java est également construite dans Unity 2018
Un mémo du programme que vous pouvez réaliser que la probabilité de lancer des dés est d'environ 1/6