「Java 开发工具」使用 Builder 构造对象(构造器模式)

153 阅读3分钟

废话不多说系列, 直接开整 ~

美女5.png

一、构造器工具类 [推荐]

(1)BuilderUtil 完整源码

JDK8 核心功能:新增对象的有一种方式(替换 new对象的另一种方式)

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 通用的 BuilderUtil 模式构建器
 *
 * @author zl
 * @create 2021-03-27 22:35
 */
public class BuilderUtil<T> {

    private Supplier<T> instance;

    private List<Consumer<T>> modifiers = new ArrayList<>();

    public BuilderUtil(Supplier<T> instance) {
        this.instance = instance;
    }

    public static <T> BuilderUtil<T> of(Supplier<T> instance) {
        return new BuilderUtil<>(instance);
    }

    public <P1> BuilderUtil<T> with(Consumer1<T, P1> consumer, P1 p1) {
        Consumer<T> c = instance -> consumer.accept(instance, p1);
        modifiers.add(c);
        return this;
    }

    public <P1, P2> BuilderUtil<T> with(Consumer2<T, P1, P2> consumer, P1 p1, P2 p2) {
        Consumer<T> c = instance -> consumer.accept(instance, p1, p2);
        modifiers.add(c);
        return this;
    }

    public <P1, P2, P3> BuilderUtil<T> with(Consumer3<T, P1, P2, P3> consumer, P1 p1, P2 p2, P3 p3) {
        Consumer<T> c = instance -> consumer.accept(instance, p1, p2, p3);
        modifiers.add(c);
        return this;
    }

    public T build() {
        T value = instance.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);
    }

    /**
     * 2 参数 Consumer
     */
    @FunctionalInterface
    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);
    }

}
(2)测试演示
① 准备一个实体类:GrilFriend.java
import edu.study.module.utils.BuilderUtil;
import java.util.*;

public class GirlFriend {
    private String name;
    private int age;
    private int bust;
    private int waist;
    private int hips;
    private String birthday;
    private String address;
    private String mobile;
    private String email;
    private String hairColor;
    private Set<String> hobby;
    private Map<String, String> gift;


    // 为了演示方便,加几个聚合方法 TODO 省略了 setter,getter,toString(),equals(),hashCode() 等方法。

    public void addHobby(String hobby) {
        this.hobby = Optional.ofNullable(this.hobby).orElse(new LinkedHashSet<>());
        this.hobby.add(hobby);
    }

    public void addHobbyArray(String... hobbies) {
        this.hobby = Optional.ofNullable(this.hobby).orElse(new LinkedHashSet<>());
        this.hobby.addAll(new ArrayList<>(Arrays.asList(hobbies)));
    }

    public void addHobbyList(List<String> hobbies) {
        this.hobby = Optional.ofNullable(this.hobby).orElse(new LinkedHashSet<>());
        this.hobby.addAll(hobbies);
    }

    public void addHobbySet(Set<String> hobbies) {
        this.hobby = Optional.ofNullable(this.hobby).orElse(new LinkedHashSet<>());
        this.hobby.addAll(hobbies);
    }

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

}
② BuilderUtil.java  使用方法
    public static void main(String[] args) {
        Set<String> hobbySet = new HashSet<>();
        hobbySet.add("足球");
        hobbySet.add("篮球");
        hobbySet.add("足球");

        GirlFriend myGirlFriend = BuilderUtil.of(GirlFriend::new)
                .with(GirlFriend::setName, "小美")
                .with(GirlFriend::setAge, 18)
                .with(GirlFriend::setVitalStatistics, 33, 23, 33)
                .with(GirlFriend::setBirthday, "2001-10-26")
                .with(GirlFriend::setAddress, "上海浦东")
                .with(GirlFriend::setMobile, "18688888888")
                .with(GirlFriend::setEmail, "xxxx@qq.com")
                .with(GirlFriend::setHairColor, "浅棕色带点微卷")
                .with(GirlFriend::addHobby, "逛街")
                .with(GirlFriend::addHobby, "购物")
                .with(GirlFriend::addHobby, "买东西")
                .with(GirlFriend::addHobbyArray, new String[]{"看电视", "看报纸",})
                .with(GirlFriend::addHobbyList, Arrays.asList("听音乐", "画画", "书法", "书法", "逛街"))
                .with(GirlFriend::addHobbySet, hobbySet)
                .with(GirlFriend::addGift, "情人节礼物", "LBR 1912女王时代")
                .with(GirlFriend::addGift, "生日礼物", "迪奥烈焰蓝金")
                .with(GirlFriend::addGift, "纪念日礼物", "阿玛尼红管唇釉")
                // 等等等等 ...
                .build();
        System.out.println(JSONObject.toJSONString(myGirlFriend));// fastjson
    }

结果显示:

image.png

二、每个类中书写构造器静态内部类

(1)实体类源码
import java.util.Date;

/**
 * 构造器模式
 */
public class BuilderDemo {

    private Integer id;
    private String name;
    private Date curTime;

    // 构造器Builder模式
    static class Builder {
        private BuilderDemo builderDemo;

        public Builder() { builderDemo = new BuilderDemo(); }

        public Builder setId(Integer id) {
            builderDemo.setId(id);
            return this;
        }

        public Builder setName(String name) {
            builderDemo.setName(name);
            return this;
        }

        public Builder setCurTime(Date date) {
            builderDemo.setCurTime(date);
            return this;
        }

        public BuilderDemo build() { return builderDemo; }
    }
	// getter 和 setter
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Date getCurTime() { return curTime; }
    public void setCurTime(Date curTime) { this.curTime = curTime; }

    @Override
    public String toString() {
        return "BuilderDemo{" + "id=" + id + ", name='" + name + '\'' + ", curTime=" + curTime + '}';
    }

    // 测试实例
    public static void main(String[] args) {
        BuilderDemo builderDemo = new BuilderDemo.Builder()
            .setId(1).setName("Drew").setCurTime(new Date())
            .build();
        System.out.println(builderDemo);
        BuilderDemo builderDemo1 = new BuilderDemo.Builder()
            .setId(2).setName("Drew")
            .build();
        System.out.println(builderDemo1);
    }

}
(2)测试演示

image.png

(3)Lombok 优化

🌹 温馨提示:使用 Lombok 插件有一个自带的注解可生成此类代码,简化编译的代码;如下图所示

image.png


🙏至此,感谢阅读🙏

美女5.png