<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          學(xué)了這個,三歪再也不想寫各種setter了

          共 5614字,需瀏覽 12分鐘

           ·

          2020-07-16 11:10


          今天又來給大家吹一下逼。

          三歪在公司里邊也看了不少的系統(tǒng)了,看到結(jié)構(gòu)清晰、代碼清晰的系統(tǒng)時會贊嘆能寫出這種代碼的人是真的牛逼??吹絹y七八糟的代碼又不寫注釋的時候也會吐槽:“這寫的是啥啊”

          多看別人的代碼,總會有不同的發(fā)現(xiàn)和體會。

          最近看別人項目的時候,發(fā)現(xiàn)會有這種寫法:

          MessageTask?task?=?MessageTask.builder()
          ??.content("關(guān)注?Java3y?吧?>>?")
          ??.messageId(String.valueOf(ThreadLocalRandom.current().nextLong()))
          ??.taskId("3y")
          ??.taskName("一起來玩")
          ??.build();

          System.out.println(task.toString());

          看代碼其實很容易看出它在干嘛,就是在創(chuàng)建MessageTask這個對象。

          平時我們初學(xué)的時候,如果要創(chuàng)建這個對象會怎么寫?一般會有兩種方法:

          1. 將屬性配在構(gòu)造函數(shù)上,然后直接調(diào)構(gòu)造器,傳入?yún)?shù)
          2. 調(diào)用多個set方法
          //?構(gòu)造器傳入屬性
          MessageTask?messageTask?=?new?MessageTask("3y",?"關(guān)注?Java3y?吧?>>",?
          ??????????????????????????????????????????String.valueOf(ThreadLocalRandom.current().nextLong()),?"一起來玩");

          //?調(diào)用各種的set方法
          MessageTask?messageTask?=?new?MessageTask();
          messageTask.setTaskId("3y");
          messageTask.setContent("關(guān)注?Java3y?吧?>>");
          messageTask.setMessageId(String.valueOf(ThreadLocalRandom.current().nextLong()));
          messageTask.setTaskName("一起來玩");

          日常使用的話,應(yīng)該是多次調(diào)用set方法比較多的(應(yīng)該都是這樣的吧)。

          從代碼層面上,構(gòu)造器傳參的代碼是最簡短的,但在現(xiàn)實層面上我們很難每次都可以通過構(gòu)造器傳參的方式去完成對象的創(chuàng)建(更多的時候每個對象的屬性都是不一致的)。

          構(gòu)造器的代碼看起來非常短,但閱讀起來不太友好(我得去看每個參數(shù)是什么意思);

          set方法寫起來不太方便,如果對象的屬性較多,也會有一大串的set代碼。

          而文章最開始的builer鏈?zhǔn)?/strong>調(diào)用就很舒服,我一看這代碼就知道這肯定是哪種我不知道的設(shè)計模式。

          于是我一查,原來這就叫做建造者模式。

          怎么實現(xiàn)建造者模式?

          建造者模式更多的是寫法上的不同,從代碼結(jié)構(gòu)層面上其實沒有很大的區(qū)別,只是看起來會更清爽一些。

          那怎么實現(xiàn)建造者模式呢?其實也非常簡單:

          • 在domain類上創(chuàng)建一個靜態(tài)內(nèi)部類 Builder,Builder擁有domain所有的屬性
          • 在domain類上創(chuàng)建一個private的構(gòu)造函數(shù),參數(shù)為Builder類型,里邊將Builder的屬性賦值給domain的屬性
          • 在Builder內(nèi)部類創(chuàng)建domain屬性的賦值方法,返回值是Builder
          • Builder內(nèi)部類創(chuàng)建一個build方法,返回domain實例

          下面我們來實現(xiàn)一下吧,首先創(chuàng)建一個靜態(tài)內(nèi)部類Builder,并且內(nèi)部類Builder擁有domain的所有屬性:

          public?class?MessageTask?{

          ????private?String?taskId;
          ????private?String?content;
          ????private?String?messageId;
          ????private?String?taskName;
          ?
          ???//?創(chuàng)建內(nèi)部類
          ????public?static?class?Builder{
          ????????private?String?taskId;
          ????????private?String?content;
          ????????private?String?messageId;
          ????????private?String?taskName;
          ????}
          }

          在domain類上創(chuàng)建一個private的構(gòu)造函數(shù),參數(shù)為Builder類型,里邊是將Builder的屬性賦值給domain的屬性:

          public?class?MessageTask?{

          ????private?String?taskId;
          ????private?String?content;
          ????private?String?messageId;
          ????private?String?taskName;

          ???//?增加private構(gòu)造函數(shù)
          ????private?MessageTask(Builder?builder)?{
          ????????this.taskId?=?builder.taskId;
          ????????this.content?=?builder.content;
          ????????this.messageId?=?builder.messageId;
          ????????this.taskName?=?builder.taskName;
          ????}
          ????public?static?class?Builder{
          ????????private?String?taskId;
          ????????private?String?content;
          ????????private?String?messageId;
          ????????private?String?taskName;
          ????}
          }

          在Builder內(nèi)部類創(chuàng)建domain屬性的賦值方法,返回值是Builder

          public?class?MessageTask?{

          ????private?String?taskId;
          ????private?String?content;
          ????private?String?messageId;
          ????private?String?taskName;

          ????private?MessageTask(Builder?builder)?{
          ????????this.taskId?=?builder.taskId;
          ????????this.content?=?builder.content;
          ????????this.messageId?=?builder.messageId;
          ????????this.taskName?=?builder.taskName;
          ????}
          ????public?static?class?Builder{
          ????????private?String?taskId;
          ????????private?String?content;
          ????????private?String?messageId;
          ????????private?String?taskName;

          ????????//?賦值屬性的方法(返回的是Builder)
          ????????public?Builder?setTaskId(String?taskId)?{
          ????????????this.taskId?=?taskId;
          ????????????return?this;
          ????????}
          ????????public?Builder?setContent(String?content)?{
          ????????????this.content?=?content;
          ????????????return?this;

          ????????}
          ????????public?Builder?setMessageId(String?messageId)?{
          ????????????this.messageId?=?messageId;
          ????????????return?this;

          ????????}
          ????????public?Builder?setTaskName(String?taskName)?{
          ????????????this.taskName?=?taskName;
          ????????????return?this;
          ????????}
          ????}
          }

          在Builder內(nèi)部類創(chuàng)建一個builde方法,返回domain實例

          public?class?MessageTask?{

          ????private?String?taskId;
          ????private?String?content;
          ????private?String?messageId;
          ????private?String?taskName;

          ????private?MessageTask(Builder?builder)?{
          ????????this.taskId?=?builder.taskId;
          ????????this.content?=?builder.content;
          ????????this.messageId?=?builder.messageId;
          ????????this.taskName?=?builder.taskName;
          ????}
          ????public?static?class?Builder{
          ????????private?String?taskId;
          ????????private?String?content;
          ????????private?String?messageId;
          ????????private?String?taskName;
          ??????
          ????????public?Builder?setTaskId(String?taskId)?{
          ????????????this.taskId?=?taskId;
          ????????????return?this;
          ????????}
          ????????public?Builder?setContent(String?content)?{
          ????????????this.content?=?content;
          ????????????return?this;

          ????????}
          ????????public?Builder?setMessageId(String?messageId)?{
          ????????????this.messageId?=?messageId;
          ????????????return?this;

          ????????}
          ????????public?Builder?setTaskName(String?taskName)?{
          ????????????this.taskName?=?taskName;
          ????????????return?this;
          ????????}
          ??????
          ????//?創(chuàng)建build方法,返回實例
          ????????public?MessageTask?build()?{
          ????????????return?new?MessageTask(this);
          ????????}
          ????}
          }

          使用方式:先創(chuàng)建Builder對象,然后用Builder去賦值,最后再調(diào)用build()返回真正的實例:

          MessageTask.Builder?builder?=?new?MessageTask.Builder();
          MessageTask?task?=?builder.setContent("關(guān)注?Java3y?吧?>>")
          ??.setTaskId("3y")
          ??.setTaskName("一起來玩")
          ??.setMessageId(String.valueOf(ThreadLocalRandom.current().nextLong()))
          ??.build();

          借助工具使用建造者模式

          從使用的角度感覺是好用了,代碼也清爽了。其實可以發(fā)現(xiàn)的是,我們都把邏輯寫到了Domain類上,這寫起來肯定是需要花時間的。

          我第一印象是:這種這么通用的東西,肯定是有可以一鍵生成的方法的,于是我瞄準(zhǔn)了Lombok

          果不其然,我們?nèi)绻褂昧?code style="font-size:14px;background-color:rgba(27,31,35,.05);font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;color:rgb(40,202,113);">Lombok后,在類上加上一個注解@Builder就可以使用建造者模式的代碼了,非常方便

          @Builder
          @Data
          public?class?MessageTask?{
          ????private?String?taskId;
          ????private?String?content;
          ????private?String?messageId;
          ????private?String?taskName;

          }

          又想了一下,IDEA這么強大,感覺IDEA也有辦法去生成Builder,也果不其然:

          37b46b10e87fa277fdcbff6a8504ff95.webp

          做個小調(diào)查:

          • 如果你之前已經(jīng)了解過了建造者模式,你在項目中有用嗎?
          • 如果你看了這篇文章才了解到了建造者模式,你在以后會用嗎?

          我個人是看團(tuán)隊的代碼風(fēng)格的,如果原有已經(jīng)是各種set去構(gòu)造對象,那我就不會再修改了。如果是新寫的業(yè)務(wù),會使用建造者模式。


          各類知識點總結(jié)

          下面的文章都有對應(yīng)的原創(chuàng)精美PDF,在持續(xù)更新中,可以來找我催更~

          掃碼或者微信搜Java3y?免費領(lǐng)取原創(chuàng)思維導(dǎo)圖、精美PDF。在公眾號回復(fù)「888」領(lǐng)取,PDF內(nèi)容純手打有任何不懂歡迎來問我。


          原創(chuàng)電子書
          680d5a4055f0d7dda5ebc3b695c3ae2c.webp

          原創(chuàng)思維導(dǎo)圖

          74a29a7e157abf438d85d9237b382451.webp


          0f1845f2296ac4d6e521cda39fe02a0b.webp

          a166728a7ddb910a0d6e102a4612f79c.webp

          a166728a7ddb910a0d6e102a4612f79c.webp

          我是三歪,一個想要變強的男人,感謝大家的點贊收藏和轉(zhuǎn)發(fā),下期見。
          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  污污污污污网站 | 日韩美美少少妇在线观看 | 色情片在线播放 | 一级A片免费视频 | 久久久无码成人电影 |