最新公告
  • 新注册用户请前往个人中心绑定邮箱以便接收相关凭证邮件!!!点击前往个人中心
  • 你还在new对象吗?Java8通用Builder了解一下?

    程序员经常会遇到灵魂拷问:你有对象吗?

    没有,但我可以 new 一个!

    1. public class GirlFriend {
    2.     private String name;
    3.     private int age;
    4.     // 省略 getter & setter …
    5.     public static void main(String[] args) {
    6.         GirlFriend myGirlFriend = new GirlFriend();
    7.         myGirlFriend.setName(“小美”);
    8.         myGirlFriend.setAge(18);
    9.     }
    10. }

    没问题,老铁!但如果对象的属性太多,咋办?

    1. public class GirlFriend {
    2.     private String name;
    3.     private int age;
    4.     private int bust;
    5.     private int waist;
    6.     private int hips;
    7.     private List<String> hobby;
    8.     private String birthday;
    9.     private String address;
    10.     private String mobile;
    11.     private String email;
    12.     private String hairColor;
    13.     private Map<String, String> gift;
    14.     // 等等等等 …
    15.     // 省略 getter & setter …
    16.     public static void main(String[] args) {
    17.         GirlFriend myGirlFriend = new GirlFriend();
    18.         myGirlFriend.setName(“小美”);
    19.         myGirlFriend.setAge(18);
    20.         myGirlFriend.setBust(33);
    21.         myGirlFriend.setWaist(23);
    22.         myGirlFriend.setHips(33);
    23.         myGirlFriend.setBirthday(“2001-10-26”);
    24.         myGirlFriend.setAddress(“上海浦东”);
    25.         myGirlFriend.setMobile(“18688888888”);
    26.         myGirlFriend.setEmail(“pretty-xiaomei@qq.com”);
    27.         myGirlFriend.setHairColor(“浅棕色带点微卷”);
    28.         List<String> hobby = new ArrayList<>();
    29.         hobby.add(“逛街”);
    30.         hobby.add(“购物”);
    31.         hobby.add(“买东西”);
    32.         myGirlFriend.setHobby(hobby);
    33.         Map<String, String> gift = new HashMap<>();
    34.         gift.put(“情人节礼物”, “LBR 1912女王时代”);
    35.         gift.put(“生日礼物”, “迪奥烈焰蓝金”);
    36.         gift.put(“纪念日礼物”, “阿玛尼红管唇釉”);
    37.         myGirlFriend.setGift(gift);
    38.         // 等等等等 …
    39.     }
    40. }
    GirlFriend
    1. GirlFriend{name=’小美’
    2. , age=18
    3. , bust=33
    4. , waist=23
    5. , hips=33
    6. , hobby=[逛街, 购物, 买东西]
    7. , birthday=’2001-10-26′
    8. , address=’上海浦东’
    9. , mobile=’18688888888′
    10. , email=’pretty-xiaomei@qq.com’
    11. , hairColor=’浅棕色带点微卷’
    12. , gift={情人节礼物=LBR 1912女王时代, 生日礼物=迪奥烈焰蓝金, 纪念日礼物=阿玛尼红管唇釉}
    13. }
    GirlFriend 是很美,但写起来也太麻烦了吧。
    说说缺点:实例化和设置属性分开,不好维护;变量名重复写。

    莫慌,看法宝~

    这里不再介绍其他 Builder 实现方式,直接祭出最实用的通用Builder:
    适用于所有类,不需要改造原来类,不需要 lombok 插件支持。
    先看看使用姿势:
    1. public class GirlFriend {
    2.     // 省略属性 …
    3.     // 省略 getter & setter …
    4.     // 为了演示方便,加几个聚合方法
    5.     public void addHobby(String hobby) {
    6.         this.hobby = Optional.ofNullable(this.hobby).orElse(new ArrayList<>());
    7.         this.hobby.add(hobby);
    8.     }
    9.     public void addGift(String day, String gift) {
    10.         this.gift = Optional.ofNullable(this.gift).orElse(new HashMap<>());
    11.         this.gift.put(day, gift);
    12.     }
    13.     public void setVitalStatistics(int bust, int waist, int hips) {
    14.         this.bust = bust;
    15.         this.waist = waist;
    16.         this.hips = hips;
    17.     }
    18.     public static void main(String[] args) {
    19.         GirlFriend myGirlFriend = Builder.of(GirlFriend::new)
    20.                 .with(GirlFriend::setName, “小美”)
    21.                 .with(GirlFriend::setAge, 18)
    22.                 .with(GirlFriend::setVitalStatistics, 33, 23, 33)
    23.                 .with(GirlFriend::setBirthday, “2001-10-26”)
    24.                 .with(GirlFriend::setAddress, “上海浦东”)
    25.                 .with(GirlFriend::setMobile, “18688888888”)
    26.                 .with(GirlFriend::setEmail, “pretty-xiaomei@qq.com”)
    27.                 .with(GirlFriend::setHairColor, “浅棕色带点微卷”)
    28.                 .with(GirlFriend::addHobby, “逛街”)
    29.                 .with(GirlFriend::addHobby, “购物”)
    30.                 .with(GirlFriend::addHobby, “买东西”)
    31.                 .with(GirlFriend::addGift, “情人节礼物”, “LBR 1912女王时代”)
    32.                 .with(GirlFriend::addGift, “生日礼物”, “迪奥烈焰蓝金”)
    33.                 .with(GirlFriend::addGift, “纪念日礼物”, “阿玛尼红管唇釉”)
    34.                 // 等等等等 …
    35.                 .build();
    36.     }
    37. }
    看到了吗!实例化和属性设置在同一条语句执行,链式操作,一路点点点,清爽!

    Talk is cheap, show me the code:

    1. /**
    2.  * 通用的 Builder 模式构建器
    3.  *
    4.  * @author: CipherCui
    5.  * @since 2019/8/29
    6.  */
    7. public class Builder<T> {
    8.     private final Supplier<T> instantiator;
    9.     private List<Consumer<T>> modifiers = new ArrayList<>();
    10.     public Builder(Supplier<T> instantiator) {
    11.         this.instantiator = instantiator;
    12.     }
    13.     public static <T> Builder<T> of(Supplier<T> instantiator) {
    14.         return new Builder<>(instantiator);
    15.     }
    16.     public <P1> Builder<T> with(Consumer1<T, P1> consumer, P1 p1) {
    17.         Consumer<T> c = instance -> consumer.accept(instance, p1);
    18.         modifiers.add(c);
    19.         return this;
    20.     }
    21.     public <P1, P2> Builder<T> with(Consumer2<T, P1, P2> consumer, P1 p1, P2 p2) {
    22.         Consumer<T> c = instance -> consumer.accept(instance, p1, p2);
    23.         modifiers.add(c);
    24.         return this;
    25.     }
    26.     public <P1, P2, P3> Builder<T> with(Consumer3<T, P1, P2, P3> consumer, P1 p1, P2 p2, P3 p3) {
    27.         Consumer<T> c = instance -> consumer.accept(instance, p1, p2, p3);
    28.         modifiers.add(c);
    29.         return this;
    30.     }
    31.     public T build() {
    32.         T value = instantiator.get();
    33.         modifiers.forEach(modifier -> modifier.accept(value));
    34.         modifiers.clear();
    35.         return value;
    36.     }
    37.     /**
    38.      * 1 参数 Consumer
    39.      */
    40.     @FunctionalInterface
    41.     public interface Consumer1<T, P1> {
    42.         void accept(T t, P1 p1);
    43.     }
    44.     /**
    45.      * 2 参数 Consumer
    46.      */
    47.     @FunctionalInterface
    48.     public interface Consumer2<T, P1, P2> {
    49.         void accept(T t, P1 p1, P2 p2);
    50.     }
    51.     /**
    52.      * 3 参数 Consumer
    53.      */
    54.     @FunctionalInterface
    55.     public interface Consumer3<T, P1, P2, P3> {
    56.         void accept(T t, P1 p1, P2 p2, P3 p3);
    57.     }
    58. }
    这个示例最多支持三个参数的设置属性方法,也完全够用了。如果要扩展也很容易,依葫芦画瓢,添加多个参数的Consumer。

    快用你的 Builder 建个对象吧~

    本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
    极客文库 » 你还在new对象吗?Java8通用Builder了解一下?

    常见问题FAQ

    如果资源链接失效了怎么办?
    本站用户分享的所有资源都有自动备份机制,如果资源链接失效,请联系本站客服QQ:2580505920更新资源地址。
    如果用户分享的资源与描述不符怎么办?
    可以联系客服QQ:2580505920,如果要求合理可以安排退款或者退赞助积分。
    如何分享个人资源获取赞助积分或其他奖励?
    本站用户可以分享自己的资源,但是必须保证资源没有侵权行为。点击个人中心,根据操作填写并上传即可。资源所获收益完全归属上传者,每周可申请提现一次。
    如果您发现了本资源有侵权行为怎么办?
    及时联系客服QQ:2580505920,核实予以删除。

    参与讨论

    • 211会员总数(位)
    • 3737资源总数(个)
    • 0本周发布(个)
    • 0 今日发布(个)
    • 869稳定运行(天)

    欢迎加入「极客文库」,成为原创作者从这里开始!

    立即加入 了解更多
    成为赞助用户享有更多特权立即升级