Java构造器模式+泛型+lamda函数式编程=通用Builder

    xiaoxiao2022-05-29  195

    GitHub 直通车

    package pers.zuo.component; import java.util.Objects; /** * @author 左金剛 * @Title: Builder * @Description: This is a common builder to create a bean, * the generic type must have a default construct, * otherwise will throw a exception * @date 2019/5/20 18:59 */ public class Builder<T> { private Class<T> clazz; private Init<T> init; private ValidFields<T> validFields; private Builder(Class<T> clazz) { this.clazz = clazz; } public Builder(Class<T> clazz, Init<T> init) { this.clazz = clazz; this.init = init; } public Builder(Class<T> clazz, Init<T> init, ValidFields<T> validFields) { this.clazz = clazz; this.init = init; this.validFields = validFields; } public static <T> Builder<T> create(Class<T> clazz) { return new Builder<>(clazz); } public static <T> Builder<T> create(Class<T> clazz, Init<T> init) { return new Builder<>(clazz, init); } public static <T> Builder<T> create(Class<T> clazz, Init<T> init, ValidFields<T> validFields) { return new Builder<>(clazz, init, validFields); } public Builder<T> addValid(ValidFields<T> valid){ this.validFields = valid; return this; } public T build(FillField<T> fillField) { T instance = null; try { instance = this.clazz.newInstance(); if (Objects.nonNull(init)){ init.initialize(instance); } } catch (InstantiationException | IllegalAccessException e) { throw new RuntimeException(e.getMessage()); } fillField.fill(instance); if (Objects.isNull(validFields)){ return instance; } boolean validRet = this.validFields.valid(instance); if (validRet){ return instance; } throw new RuntimeException(String.format("instance fields valid error, Class is %s", instance.getClass().getName())); } public interface Init<T> { void initialize(T instanse); } public interface FillField<T> { void fill(T instance); } public interface ValidFields<T> { boolean valid(T instanse); } }

    使用方法:

    一、简单使用

    构造一个对象 A a = Builder.create(A.class).build(a -> { a.set...(); a.set...(); }); 或者 先构造一个builder,然后可以使用builder构造很多对象 Builder builder = Builder.create(A.class, initDto -> { return initDto.setAge(1); }); A a = builder.build(a -> { a.set...(); a.set...(); }); A a1 = builder.build(a -> { a.set...(); a.set...(); });

    二、有验证的构造对象(主要用在开发时,对于逻辑的简单校验) 1.别人传过来的值,我们在用来构造对象时,可适当做校验 2.开发过程中,我们一次实例化builder,而后可能需要使用该builder构造三五个甚至六七个对象,为了避免在过程中某次手误,我们可以在最开始实例化builder是添加检查,然后如果后面构造对象过程中有什么误写或漏写,我们便可以轻松发现。考虑到性能,在正式上线前可以将检查移除。如果更看重代码的准确性,也可以留着用于以后代码迭代的准则。

    一次实例化builder并添加valid,然后构造无数对象 Builder builder = Builder.create(A.class, initDto -> { return initDto.setAge(1); }, dto -> { return a.getB() > 10; }) A a = builder.build(a -> { a.set...(); a.set...(); }); A a1 = builder.build(a -> { a.set...(); a.set...(); }); 或者 某些对象构造时,不需要验证,某些需要有验证,某些需要有不同的验证 Builder builder = Builder.create(A.class, initDto -> { return initDto.setAge(1); }); A a = builder.build(a -> { a.set...(); a.set...(); }); builder.addValid( dto -> { return a.getB() > 10; }); A a1 = builder.build(a -> { a.set...(); a.set...(); });

    最新回复(0)