有人在我的構(gòu)造器文章下提了下面一個(gè)問(wèn)題:
二、探索老師,提一個(gè)問(wèn)題,在實(shí)際生活中遇到的 比如說(shuō)我寫(xiě)了一個(gè)發(fā)送消息的方法。比如說(shuō)有一個(gè)參數(shù)是 messageDTO,但是他有很多屬性,比如說(shuō) topic,tag,shadingKey,msg, delayTime 等等,但是我希望別人在使用這個(gè)方法的時(shí)候傳入 messageDTO 是我想要的,即我會(huì)將無(wú)參構(gòu)造方法私有化,因?yàn)槲也幌胱寗e人使用無(wú)參構(gòu)造new一個(gè)對(duì)象出來(lái),(因?yàn)樽约喝et可能某一些參數(shù)設(shè)置有遺漏),然后只限制了 幾種構(gòu)造函數(shù),或者使用靜態(tài)方法來(lái)創(chuàng)建對(duì)象。
然后對(duì)象的入?yún)⑹怯梢蟮摹1热缯f(shuō)你想法 普通消息,那么需要 topic和msg,發(fā)延遲消息,需要topic msg和delayTime,發(fā)順序消息需要額外再加一個(gè)shadingKey,請(qǐng)問(wèn)在這種情況下如何使用建造者模式。即只允許使用某一組參數(shù)來(lái)創(chuàng)建對(duì)象
每種設(shè)計(jì)模式(甚至任何技術(shù))都有自己適合的場(chǎng)景。
雖然我們學(xué)了建造者模式,未必一定要用建造者模式。
針對(duì)這種場(chǎng)景,有很多方法可以更優(yōu)雅地實(shí)現(xiàn):
- 可以使用工廠模式,通過(guò)函數(shù)名體現(xiàn)類(lèi)型。
- 可以通過(guò)繼承的方式通過(guò)類(lèi)名來(lái)體現(xiàn)類(lèi)型。
- Builder 模式變通。
2.1 靜態(tài)工廠
MessageFactory類(lèi)
構(gòu)造普通消息
public static MessageDTO buildCommonMsg(String topic, String msg) { // 直接 new 然后 set 或者用 builder都可以 }
構(gòu)造延時(shí)消息
public static MessageDTO buildDelayMsg(String topic, String msg,Long delayTime) { // 省略 }
順序消息類(lèi)似
public static MessageDTO buildOrderedMsg(String topic, String msg, String shadingKey) { // 省略 }
可以加上參數(shù)校驗(yàn)。
2.2 利用繼承來(lái)表意
普通消息 CommonMsgDTO
public class CommonMsgDTO{ private String topic; private String msg; // 提供全參構(gòu)造方法 }
延時(shí)消息 DelayMsg
public class DelayMsgDTO extends CommonMsgDTO{ private Long delayTime; // 提供全參構(gòu)造方法 }
順序消息 DelayMsg
public class OrderedMsgDTO extends CommonMsgDTO{ private String shadingKey; // 提供全參構(gòu)造方法 }
這樣構(gòu)造時(shí)只有全參數(shù)構(gòu)造函數(shù),就不容易傳錯(cuò),而且看名知意。
如果傳 null 可以報(bào)錯(cuò)。
2.3 builder模式活用
public static class Builder{ // 省略 public Builder(String topic, String msg){ // 省略 } // 其他屬性的set 方法 }
對(duì)普通的 builder 模式稍微改造下,將必備參數(shù)作為 Builder 的唯一構(gòu)造函數(shù)的參數(shù)。
這樣必備屬性必然會(huì)傳入。
但是如果必傳參數(shù)太多,不推薦使用這種方式。
哪怕是不同的 builder 模式,在 build時(shí)進(jìn)行參數(shù)校驗(yàn)。
可能還有很多解決方案,上面給出兩個(gè)比較簡(jiǎn)單且常見(jiàn)的方法。
在執(zhí)行發(fā)送消息的函數(shù)上加上參數(shù)校驗(yàn),這樣就不容易出錯(cuò)。
希望大家一定要破除 ”手里拿著錘子,看啥都像釘子“的心理。
在學(xué)習(xí)任何技術(shù)時(shí),思考其最適合的場(chǎng)景,為了解決什么問(wèn)題,局限是什么。
在解決問(wèn)題前想清楚問(wèn)題是什么?
比如這位同學(xué)核心是為了能讓使用者清晰地區(qū)分類(lèi)型,然后讓使用者知道不同類(lèi)型的參數(shù)差異。
然后再去思考怎樣更容易區(qū)分開(kāi)呢?必傳參數(shù)一定要早構(gòu)造的時(shí)候校驗(yàn)嗎?
慢慢地,問(wèn)題就明了了,就更容易得到更科學(xué)的答案。
總之,既要埋頭苦學(xué),又要抬頭看路。學(xué)而不思則罔!
如果想在開(kāi)發(fā)中少趟坑,感興趣可以看看我最近出的幾個(gè) GitChat:
- 《程序員進(jìn)階之排錯(cuò)和避坑方法論》
- 《CodeReview 的正確姿勢(shì)》
?
本文摘自 :https://blog.51cto.com/u