From 9d5c2ffc1a9037efe0a9e46f06feff0554ed87e6 Mon Sep 17 00:00:00 2001 From: TomXin <766781886@qq.com> Date: Sat, 29 Jan 2022 17:34:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EGenericBuilder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/builder/GenericBuilder.java | 252 ++++++++++++++++++ .../core/builder/GenericBuilderTest.java | 47 ++++ 2 files changed, 299 insertions(+) create mode 100644 hutool-core/src/main/java/cn/hutool/core/builder/GenericBuilder.java create mode 100644 hutool-core/src/test/java/cn/hutool/core/builder/GenericBuilderTest.java diff --git a/hutool-core/src/main/java/cn/hutool/core/builder/GenericBuilder.java b/hutool-core/src/main/java/cn/hutool/core/builder/GenericBuilder.java new file mode 100644 index 000000000..b8da21486 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/builder/GenericBuilder.java @@ -0,0 +1,252 @@ +package cn.hutool.core.builder; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + *

通用Builder

+ * 参考: 一看就会的java8通用Builder + *

使用方法如下:

+ *
+ * Box box = GenericBuilder
+ * 		      .of(Box::new)
+ * 		      .with(Box::setId, 1024L)
+ * 		      .with(Box::setTitle, "Hello World!")
+ * 		      .with(Box::setLength, 9)
+ * 		      .with(Box::setWidth, 8)
+ * 		      .with(Box::setHeight, 7)
+ * 		      .build();
+ *
+ * 
+ * + *

我们也可以对已创建的对象进行修改:

+ *
+ * Box boxModified = GenericBuilder
+ * 		      .of(() -> box)
+ * 		      .with(Box::setTitle, "Hello Friend!")
+ * 		      .with(Box::setLength, 3)
+ * 		      .with(Box::setWidth, 4)
+ * 		      .with(Box::setHeight, 5)
+ * 		      .build();
+ * 
+ * + * @author TomXin + * @since jdk1.8 + */ +public class GenericBuilder implements Builder { + + /** + * 实例化器 + */ + private final Supplier instantiator; + + /** + * 修改器集合 + */ + private final List> modifiers = new ArrayList<>(); + + /** + * 构造 + * + * @param instant 实例化器 + */ + public GenericBuilder(Supplier instant) { + this.instantiator = instant; + } + + /** + * 通过实例化器创建GenericBuilder + * + * @param instant 实例化器 + * @param 目标类型 + * @return GenericBuilder对象 + */ + public static GenericBuilder of(Supplier instant) { + return new GenericBuilder<>(instant); + } + + /** + * 调用1参数方法 + * + * @param consumer 1参数Consumer + * @param p1 参数一 + * @param 参数一类型 + * @return GenericBuilder对象 + */ + public GenericBuilder with(Consumer1 consumer, P1 p1) { + Consumer c = instance -> consumer.accept(instance, p1); + modifiers.add(c); + return this; + } + + /** + * 调用2参数方法 + * + * @param consumer 2参数Consumer + * @param p1 参数一 + * @param p2 参数二 + * @param 参数一类型 + * @param 参数二类型 + * @return GenericBuilder对象 + */ + public GenericBuilder with(Consumer2 consumer, P1 p1, P2 p2) { + Consumer c = instance -> consumer.accept(instance, p1, p2); + modifiers.add(c); + return this; + } + + /** + * 调用3参数方法 + * + * @param consumer 3参数Consumer + * @param p1 参数一 + * @param p2 参数二 + * @param p3 参数三 + * @param 参数一类型 + * @param 参数二类型 + * @param 参数三类型 + * @return GenericBuilder对象 + */ + public GenericBuilder with(Consumer3 consumer, P1 p1, P2 p2, P3 p3) { + Consumer c = instance -> consumer.accept(instance, p1, p2, p3); + modifiers.add(c); + return this; + } + + /** + * 调用4参数方法 + * + * @param consumer 4参数Consumer + * @param p1 参数一 + * @param p2 参数二 + * @param p3 参数三 + * @param p4 参数四 + * @param 参数一类型 + * @param 参数二类型 + * @param 参数三类型 + * @param 参数四类型 + * @return GenericBuilder对象 + */ + public GenericBuilder with(Consumer4 consumer, P1 p1, P2 p2, P3 p3, P4 p4) { + Consumer c = instance -> consumer.accept(instance, p1, p2, p3, p4); + modifiers.add(c); + return this; + } + + /** + * 调用5参数方法 + * + * @param consumer 5参数Consumer + * @param p1 参数一 + * @param p2 参数二 + * @param p3 参数三 + * @param p4 参数四 + * @param p5 参数五 + * @param 参数一类型 + * @param 参数二类型 + * @param 参数三类型 + * @param 参数四类型 + * @param 参数五类型 + * @return GenericBuilder对象 + */ + public GenericBuilder with(Consumer5 consumer, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { + Consumer c = instance -> consumer.accept(instance, p1, p2, p3, p4, p5); + modifiers.add(c); + return this; + } + + /** + * 构建 + * + * @return 目标对象 + */ + @Override + public T build() { + T value = instantiator.get(); + modifiers.forEach(modifier -> modifier.accept(value)); + modifiers.clear(); + return value; + } + + /** + * 1参数Consumer + */ + @FunctionalInterface + public interface Consumer1 { + /** + * 接收参数方法 + * + * @param t 对象 + * @param p1 参数二 + */ + void accept(T t, P1 p1); + } + + /** + * 2参数Consumer + */ + @FunctionalInterface + public interface Consumer2 { + /** + * 接收参数方法 + * + * @param t 对象 + * @param p1 参数一 + * @param p2 参数二 + */ + void accept(T t, P1 p1, P2 p2); + } + + /** + * 3参数Consumer + */ + @FunctionalInterface + public interface Consumer3 { + /** + * 接收参数方法 + * + * @param t 对象 + * @param p1 参数一 + * @param p2 参数二 + * @param p3 参数三 + */ + void accept(T t, P1 p1, P2 p2, P3 p3); + } + + /** + * 4参数Consumer + */ + @FunctionalInterface + public interface Consumer4 { + /** + * 接收参数方法 + * + * @param t 对象 + * @param p1 参数一 + * @param p2 参数二 + * @param p3 参数三 + * @param p4 参数四 + */ + void accept(T t, P1 p1, P2 p2, P3 p3, P4 p4); + } + + /** + * 5参数Consumer + */ + @FunctionalInterface + public interface Consumer5 { + /** + * 接收参数方法 + * + * @param t 对象 + * @param p1 参数一 + * @param p2 参数二 + * @param p3 参数三 + * @param p4 参数四 + * @param p5 参数五 + */ + void accept(T t, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5); + } +} diff --git a/hutool-core/src/test/java/cn/hutool/core/builder/GenericBuilderTest.java b/hutool-core/src/test/java/cn/hutool/core/builder/GenericBuilderTest.java new file mode 100644 index 000000000..0ac1cd728 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/builder/GenericBuilderTest.java @@ -0,0 +1,47 @@ +package cn.hutool.core.builder; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.junit.Test; + +/** + * {@link GenericBuilder} 单元测试类 + * + * @author TomXin + */ +public class GenericBuilderTest { + + @Test + public void test() { + Box box = GenericBuilder + .of(Box::new) + .with(Box::setId, 1024L) + .with(Box::setTitle, "Hello World!") + .with(Box::setLength, 9) + .with(Box::setWidth, 8) + .with(Box::setHeight, 7) + .build(); + System.out.println(box); + Box boxModified = GenericBuilder + .of(() -> box) + .with(Box::setTitle, "Hello Friend!") + .with(Box::setLength, 3) + .with(Box::setWidth, 4) + .with(Box::setHeight, 5) + .build(); + System.out.println(boxModified); + } + + @Getter + @Setter + @ToString + public static class Box { + private Long id; + private String title; + private Integer length; + private Integer width; + private Integer height; + } + +}