Programmers often face a soul-searching question: Are you dating someone? No, but I can get a new one!

public class GirlFriend { private String name; private int age; // omit getter & setter... public static void main(String[] args) { GirlFriend myGirlFriend = new GirlFriend(); MyGirlFriend. Elegantly-named setName (" small beautiful "); myGirlFriend.setAge(18); }}Copy the code

Sure thing, iron! But what if the object has too many attributes?

public class GirlFriend { private String name; private int age; private int bust; private int waist; private int hips; private Listhobby; private String birthday; private String address; private String mobile; private String email; private String hairColor; private Mapgift; // Etc etc... // omit getter & setter... public static void main(String[] args) { GirlFriend myGirlFriend = new GirlFriend(); MyGirlFriend. Elegantly-named setName (" small beautiful "); myGirlFriend.setAge(18); myGirlFriend.setBust(33); myGirlFriend.setWaist(23); myGirlFriend.setHips(33); myGirlFriend.setBirthday("2001-10-26"); MyGirlFriend. SetAddress (" Shanghai Pudong "); myGirlFriend.setMobile("18688888888"); myGirlFriend.setEmail("[email protected]"); MyGirlFriend. SetHairColor (" light ribbon point micro volume "); Listhobby = new ArrayList<>(); Hobby. Add (" shopping "); Hobby. Add (" shopping "); Hobby. Add (" Buy something "); myGirlFriend.setHobby(hobby); Mapgift = new HashMap<>(); Gift. Put (" Valentine's Day ", "LBR 1912 The Age of the Queen "); Gift. Put (" Birthday gift ", "Dior flame blue gold "); Gift. Put (" Anniversary gift ", "Armani red tube lip glaze "); myGirlFriend.setGift(gift); // Etc etc... }} GirlFriend{name='小美', age=18, bust=33, waist=23, hips=33, hobby=[shopping, shopping], birthday='2001-10-26', GirlFriend{name='小美', age=18, bust=33, waist=23, hips=33, hobby=[shopping, shopping], birthday='2001-10-26', Address =' Shanghai Pudong ', Mobile ='18688888888', email='[email protected]', hairColor=' light brown with dot micro volume ', gift={Valentine's Day gift= LBR Birthday gift = Dior Flame Blue gold, Anniversary gift = Armani red tube lip glaze}}Copy the code

GirlFriend is beautiful, but it’s too much trouble to write about.

Disadvantages: Separate instantiation and set properties, not easy to maintain; Repeat the variable name.

Don’t panic, see a magic weapon ~

Here is no more introduction to other Builder implementation methods, directly sacrifice the most practical general Builder:

It works with all classes, no modification of the original class, and no Lombok plug-in support is required.

First look at the posture:

Public class GirlFriend {// GirlFriend... // omit getter & setter... // For demonstration purposes, Public void addHobby(String Hobby) {this.hobby = option.ofNullable (this.hobby).orelse (new ArrayList<>()); this.hobby.add(hobby); } public void addGift(String day, String gift) { this.gift = Optional.ofNullable(this.gift).orElse(new HashMap<>()); this.gift.put(day, gift); } public void setVitalStatistics(int bust, int waist, int hips) { this.bust = bust; this.waist = waist; this.hips = hips; } public static void main(String[] args) { GirlFriend myGirlFriend = Builder.of(GirlFriend::new) With (GirlFriend: : elegantly-named setName, "small beautiful"), with (GirlFriend: : setAge, 18) with (GirlFriend: : setVitalStatistics, 33, 23, 33).with(GirlFriend::setBirthday, "2001-10-26").with(GirlFriend::setAddress, "Shanghai Pudong ").with(GirlFriend::setMobile, "18688888888") .with(GirlFriend::setEmail, "[email protected]") .with(GirlFriend::setHairColor, "Light brown with little curls "). With (GirlFriend: addHobby," shopping "). With (GirlFriend: addHobby, "shopping "). "Shopping "). With (GirlFriend: addGift, "LBR 1912 Queen's Day "). With (GirlFriend: addGift, "LBR 1912 Queen's Day ") With (GirlFriend: addGift, "Anniversary gift," "Armani red lip glaze ") // Blah blah blah... .build(); }}Copy the code

See?! Instantiation and property Settings are executed in the same statement, chain operation, dot dot dot, clean!

Talk is cheap, show me the code:

/** * A generic schema Builder ** @author: CipherCui * @since 2019/8/29 */ public class Builder<T> { private final Supplierinstantiator; private List<consumer> modifiers = new ArrayList<>(); public Builder(Supplierinstantiator){ this.instantiator = instantiator; } public staticBuilderof(Supplierinstantiator){ return new Builder<>(instantiator); } publicBuilderwith(Consumer1consumer, P1 p1){ Consumerc = instance -> consumer.accept(instance, p1); modifiers.add(c); return this; } publicBuilderwith(Consumer2consumer, P1 p1, P2 p2){ Consumerc = instance -> consumer.accept(instance, p1, p2); modifiers.add(c); return this; } publicBuilderwith(Consumer3consumer, P1 p1, P2 p2, P3 p3){ Consumerc = instance -> consumer.accept(instance, p1, p2, p3); modifiers.add(c); return this; } public T build() { T value = instantiator.get(); modifiers.forEach(modifier -> modifier.accept(value)); modifiers.clear(); return value; /** * 1 Consumer */ @functionalInterface public interface Consumer1<T, P1> {void accept(T T, P1 P1); Public interface Consumer2<T, P1, P2> {void accept(T T, P1 P1, P2 P2); } /** * 3 Consumer */ @functionalInterface public interface Consumer3<T, P1, P2, P3> {void accept(T T, P1 P1, P2 p2, P3 p3); }}Copy the code

This example supports up to three parameter setting property methods, which is perfectly adequate. If you want to extend it, it’s easy to follow suit and add multiple parameters for Consumer.

Build an object with your Builder

From: RRD. Me/gtQTp