--Nous avons créé et publié un outil ** qui peut générer automatiquement le code source Java de l'un des modèles de conception "** Builder pattern **" sur le ** Web **.
L'application est la suivante
https://riversun.github.io/java-builder/
(Je n'utilise pas le serveur car il est fait uniquement avec HTML / CSS / JS)
Comme indiqué ci-dessous, si vous énumérez "** type nom de variable **" dans la définition, il sera reflété en ** temps réel ** dans le code de droite.
Lorsque vous avez terminé, appuyez sur ** Copier dans le presse-papiers ** pour copier le code et le coller dans votre IDE ou votre éditeur.
Voici des exemples de génération de divers modèles Builder.
Voici le contenu saisi pour générer le code (nom de classe, type, nom de variable, etc.)
Si vous entrez ** type nom ** dans la zone de texte dans Définition et énumérez avec des sauts de ligne comme indiqué ci-dessous, le code sera automatiquement généré sur le côté droit en temps réel.
package org.example
class Person
@NotNull String name
int age
String sex
List<String> hobby
** @ </ span> NotNull ** Si vous placez une annotation au début de la ligne de définition, cette propriété sera une propriété obligatoire et du code sera généré pour vérifier la valeur null lors de la construction.
Person.java(Généré automatiquement par l'outil)
package org.example;
import java.util.ArrayList;
import java.util.List;
public class Person {
private String name;
private int age;
private String sex;
private List<String> hobby;
public static class Builder {
private String name;
private int age;
private String sex;
private List<String> hobby = new ArrayList<String>();
public Builder() {
}
Builder(String name, int age, String sex, List<String> hobby) {
this.name = name;
this.age = age;
this.sex = sex;
this.hobby = hobby;
}
public Builder name(String name){
this.name = name;
return Builder.this;
}
public Builder age(int age){
this.age = age;
return Builder.this;
}
public Builder sex(String sex){
this.sex = sex;
return Builder.this;
}
public Builder hobby(List<String> hobby){
this.hobby = hobby;
return Builder.this;
}
public Builder addHobby(String hobby){
this.hobby.add(hobby);
return Builder.this;
}
public Person build() {
if(this.name == null){
throw new NullPointerException("The property \"name\" is null. "
+ "Please set the value by \"name()\". "
+ "The property \"name\" is required.");
}
return new Person(this);
}
}
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.sex = builder.sex;
this.hobby = builder.hobby;
}
public void doSomething() {
// do something
}
}
Lorsque vous l'utilisez, faites-le comme ceci
AppMain.java
public class AppMain {
public static void main(String[] args) {
new Person.Builder()
.name("Tom")
.age(18)
.sex("male")
.addHobby("programming")
.addHobby("skiing")
.build().doSomething();
}
}
Le modèle GoF Builder contient quelques caractères supplémentaires et plusieurs classes sont générées. Il génère également ** AppMain.java **, qui est le principal équivalent. La modification principale sera ** Director.java **, qui détermine les conditions réelles de construction.
Person.java(Généré automatiquement)
package org.example;
import java.util.ArrayList;
import java.util.List;
public class Person {
private String name;
private int age;
private String sex;
private List<String> hobby = new ArrayList<String>();
public Person() {
}
public Person(String name, int age, String sex, List<String> hobby) {
this.name = name;
this.age = age;
this.sex = sex;
this.hobby = hobby;
}
public Person setName(String name){
this.name = name;
return Person.this;
}
public String getName(){
return this.name;
}
public Person setAge(int age){
this.age = age;
return Person.this;
}
public int getAge(){
return this.age;
}
public Person setSex(String sex){
this.sex = sex;
return Person.this;
}
public String getSex(){
return this.sex;
}
public Person setHobby(List<String> hobby){
this.hobby = hobby;
return Person.this;
}
public Person addHobby(String hobby){
this.hobby.add(hobby);
return Person.this;
}
public List<String> getHobby(){
return this.hobby;
}
public void doSomething(){
System.out.println("Person's properties");
System.out.println("name="+name);
System.out.println("age="+age);
System.out.println("sex="+sex);
System.out.println("hobby="+hobby);
}
}
Builder.java(Généré automatiquement)
package org.example;
import java.util.List;
public interface Builder {
public void name(String name);
public void age(int age);
public void sex(String sex);
public void hobby(List<String> hobby);
Person getResult();
}
PersonBuilder.java(Généré automatiquement)
package org.example;
import java.util.List;
public class PersonBuilder implements Builder {
private Person person;
public PersonBuilder() {
this.person = new Person();
}
@Override
public void name(String name) {
this.person.setName(name);
}
@Override
public void age(int age) {
this.person.setAge(age);
}
@Override
public void sex(String sex) {
this.person.setSex(sex);
}
@Override
public void hobby(List<String> hobby) {
this.person.setHobby(hobby);
}
@Override
public Person getResult() {
if(this.person.getName() == null){
throw new NullPointerException("The property \"name\" is null. "
+ "Please set the value by \"builder.name()\" at Director class. "
+ "The property \"name\" is required.");
}
return this.person;
}
}
Director.java(Généré automatiquement)
package org.example;
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void construct() {
builder.name("something"); // required property
builder.age(0); // optional property
builder.sex("something"); // optional property
//builder.hobby(new ArrayList<>());
}
}
AppMain.java(Généré automatiquement)
package org.example;
public class AppMain {
public static void main(String[] args) {
Builder builder = new PersonBuilder();
Director director = new Director(builder);
director.construct();
Person person = builder.getResult();
person.doSomething();
}
}
Je ne pense pas que ce soit un ** modèle Builder **, mais c'est un modèle très courant qui prend plusieurs arguments au constructeur lors de la création d'un objet.
(À mesure que le nombre d'arguments augmente, les perspectives se détériorent, donc le ** modèle Builder ** entre en jeu.)
Person.java
package org.example;
import java.util.ArrayList;
import java.util.List;
public class Person {
private String name;
private int age;
private String sex;
private List<String> hobby = new ArrayList<String>();
public Person() {
}
public Person(String name, int age, String sex, List<String> hobby) {
this.name = name;
this.age = age;
this.sex = sex;
this.hobby = hobby;
}
public Person setName(String name) {
this.name = name;
return Person.this;
}
public String getName() {
return this.name;
}
public Person setAge(int age) {
this.age = age;
return Person.this;
}
public int getAge() {
return this.age;
}
public Person setSex(String sex) {
this.sex = sex;
return Person.this;
}
public String getSex() {
return this.sex;
}
public Person setHobby(List<String> hobby) {
this.hobby = hobby;
return Person.this;
}
public Person addHobby(String hobby){
this.hobby.add(hobby);
return Person.this;
}
public List<String> getHobby() {
return this.hobby;
}
}
Avec cet outil, vous pouvez générer le même code qui est automatiquement généré lorsque vous annotez Lombok avec ** @ </ span> Builder **.
Person.java(Généré automatiquement)
package org.example;
import java.util.ArrayList;
import java.util.List;
public class Person {
private String name;
private int age;
private String sex;
private List<String> hobby;
Person(String name, int age, String sex, List<String> hobby) {
if(name == null){
throw new NullPointerException("The property \"name\" is null. "
+ "Please set the value by \"name()\". "
+ "The property \"name\" is required.");
}
this.name = name;
this.age = age;
this.sex = sex;
this.hobby = hobby;
}
public static PersonBuilder builder(){
return new PersonBuilder();
}
public static class PersonBuilder {
private String name;
private int age;
private String sex;
private List<String> hobby = new ArrayList<String>();
PersonBuilder() {
}
public PersonBuilder name(String name){
this.name = name;
return PersonBuilder.this;
}
public PersonBuilder age(int age){
this.age = age;
return PersonBuilder.this;
}
public PersonBuilder sex(String sex){
this.sex = sex;
return PersonBuilder.this;
}
public PersonBuilder hobby(List<String> hobby){
this.hobby = hobby;
return PersonBuilder.this;
}
public PersonBuilder addHobby(String hobby){
this.hobby.add(hobby);
return PersonBuilder.this;
}
public Person build() {
return new Person(this.name, this.age, this.sex, this.hobby);
}
@Override
public String toString() {
return "Person.PersonBuilder(name=" + this.name + ", age=" + this.age + ", sex=" + this.sex + ", hobby=" + this.hobby + ")";
}
}
@Override
public String toString() {
return "Person(name=" + this.name + ", age=" + this.age + ", sex=" + this.sex + ", hobby=" + this.hobby + ")";
}
public void doSomething() {
// do something
}
}
Lorsque vous utilisez le modèle Lombok Builder, faites quelque chose comme ceci
AppMain.java
public class AppMain {
public static void main(String[] args) {
System.out.println(Person.builder().name("Tom").age(12).sex("male").build());
}
}
Résultat d'exécution
Person(name=Tom, age=12, sex=male, hobby=[])
Les mesures suivantes ont été prises dans le but de produire une sortie de code typique afin que le code généré puisse être utilisé tel quel sans définir de paramètres de génération détaillés.
List <String> hobby;
, initialisation avec new ArrayList ();
et comme ```add Hobby (String hobby) `` J'ai également créé une méthode qui vous permet d'ajouter des éléments individuellement.
-Le code de vérification nul n'est pas généré pour les variables de type primitif telles que ** int **. public void construct() {
builder.name("something");
builder.age(0);
builder.sex("something");
//builder.hobby(new ArrayList<>());
}
Person setName (name) '' au lieu de
void setName (name) '' comme les Java Beans d'origine.(Il y a encore place à l'amélioration ~)