你还在 new 对象吗?Java8 通用 Builder 了解一下

共 12993字,需浏览 26分钟

 ·

2021-07-14 14:29



微信搜索逆锋起笔关注后回复编程pdf


领取编程大佬们所推荐的 23 种编程资料!


作者:cipher
www.ciphermagic.cn/java8-builder.html





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



没有,但我可以 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<StringString> 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<StringString> 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, 332333)


  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 建个对象吧~




逆锋起笔是一个专注于程序员圈子的技术平台,你可以收获最新技术动态最新内测资格BAT等大厂大佬的经验增长自身学习资料职业路线赚钱思维,微信搜索逆锋起笔关注!




Java 程序员常犯的 10 个 SQL 错误!


Java 全套视频教程


Java 初级和高级面试知识点准备


进阶必备!35 个 Java 代码优化细节


Java 9 到 16 新特性总结大全!




点赞是最大的支持 



浏览 49
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报