拯救強(qiáng)迫癥Android Builder模式
前言
Builder模式大家應(yīng)該不陌生,在我們的編碼生涯中,總會(huì)碰到它的身影。無(wú)論是Android開(kāi)發(fā)中的AlertDialog,還是網(wǎng)絡(luò)框架中的OkHttp和Retrofit,亦或是JavaPoet中,都有這哥們的身影。
之所以它這么受歡迎,除了它的上手難度比較低以外,還有一點(diǎn)就是它的的確確的解決了我們?nèi)粘i_(kāi)發(fā)中的一個(gè)難題,創(chuàng)建對(duì)象時(shí)需要的參數(shù)過(guò)多。
舉個(gè)小例子
過(guò)去幾年大家都流行炒幣,導(dǎo)致市面上一卡難求。隨著政府政策的出臺(tái),以及虛擬貨幣的崩盤(pán)。顯卡不再是有價(jià)無(wú)市的一種狀態(tài)。大學(xué)剛畢業(yè)的小龍開(kāi)了個(gè)電腦店,專(zhuān)門(mén)給人配電腦。最開(kāi)始的時(shí)候需求比較簡(jiǎn)單,只給人記錄電腦的CPU,GPU,硬盤(pán)等相關(guān)信息。
傳統(tǒng)的創(chuàng)建對(duì)象方式
// 電腦類(lèi) class Computer { private String mBroad; private String mCPU; private String mGPU; public Computer(String broad, String CPU, String GPU) { mBroad = broad; mCPU = CPU; mGPU = GPU; } @Override public String toString() { return "Computer{" + ", mBroad='" + mBroad + ''' + ", mCPU='" + mCPU + ''' + ", mGPU='" + mGPU + ''' + '}'; } }
這個(gè)時(shí)候創(chuàng)建一個(gè)Computer對(duì)象是這樣的:
Computer computer = new Computer("微星 B550M","INTEL I5","NV 3060TI");
隨著業(yè)務(wù)量的增大,客戶(hù)的要求也越來(lái)越多。對(duì)鼠標(biāo),鍵盤(pán),系統(tǒng)也有了相應(yīng)的需求。所以Computer類(lèi)也不得不有了相應(yīng)的改變。
static class Computer { private String mOS; private String mBroad; private String mKeyBoard; private String mMouse; private String mCPU; private String mGPU; public Computer(String OS, String broad, String keyBoard, String mouse, String CPU, String GPU) { mOS = OS; mBroad = broad; mKeyBoard = keyBoard; mMouse = mouse; mCPU = CPU; mGPU = GPU; } // 就寫(xiě)一個(gè)set方法否則文章太長(zhǎng),其他就不寫(xiě)了 public void setmBroad(String mBroad) { this.mBroad = mBroad; } @Override public String toString() { return "Computer{" + "mOS='" + mOS + ''' + ", mBroad='" + mBroad + ''' + ", mKeyBoard='" + mKeyBoard + ''' + ", mMouse='" + mMouse + ''' + ", mCPU='" + mCPU + ''' + ", mGPU='" + mGPU + ''' + '}'; } }
而創(chuàng)建Computer對(duì)象的參數(shù)也越來(lái)越長(zhǎng):
Computer computer = new Computer("MAC OS","微星 B550M","IQUNIX F97" ,"羅技 MX MASTER3","INTEL I5","NV 3060TI");
如果再有新的需求參數(shù),電源,機(jī)箱,散熱,內(nèi)存條,硬盤(pán)......簡(jiǎn)直不敢想象。
對(duì)象初始化參數(shù)問(wèn)題
此時(shí)我們面對(duì)的是編程中常見(jiàn)的一個(gè)問(wèn)題,對(duì)象中需求的參數(shù)過(guò)多,而都在構(gòu)造函數(shù)中傳遞,則構(gòu)造函數(shù)就會(huì)同例子中一樣,太長(zhǎng),要是用set方法來(lái)傳遞,則更為恐怖。
這個(gè)時(shí)候一個(gè)模式就應(yīng)運(yùn)而生,他就是建造者模式。
建造者模式處理方式
/** * @author:TianLong * @date:2022/10/17 19:58 * @detail:產(chǎn)品類(lèi) */ class Computer{ private String mOS; private String mBroad; private String mKeyBoard; private String mMouse; private String mCPU; private String mGPU; private Computer(String OS, String broad, String keyBoard, String mouse, String CPU, String GPU) { mOS = OS; mBroad = broad; mKeyBoard = keyBoard; mMouse = mouse; mCPU = CPU; mGPU = GPU; } public static ComputerBuilder createBuilder(){ return new ComputerBuilder(); } @Override public String toString() { return "Computer{" + "mOS='" + mOS + ''' + ", mBroad='" + mBroad + ''' + ", mKeyBoard='" + mKeyBoard + ''' + ", mMouse='" + mMouse + ''' + ", mCPU='" + mCPU + ''' + ", mGPU='" + mGPU + ''' + '}'; } /** * @author:TianLong * @date:2022/10/17 19:58 * @detail:產(chǎn)品建造者類(lèi) */ public static class ComputerBuilder{ private String mOS = "Windows"; private String mBroad= "微星 B550M"; private String mKeyBoard= "無(wú)"; private String mMouse= "無(wú)"; private String mCPU= "Intel I5"; private String mGPU= "AMD 6600XT"; public ComputerBuilder setOS(String OS) { mOS = OS; return this; } public ComputerBuilder setBroad(String broad) { mBroad = broad; return this; } public ComputerBuilder setKeyBoard(String keyBoard) { mKeyBoard = keyBoard; return this; } public ComputerBuilder setMouse(String mouse) { mMouse = mouse; return this; } public ComputerBuilder setCPU(String CPU) { mCPU = CPU; return this; } public ComputerBuilder setGPU(String GPU) { mGPU = GPU; return this; } public Computer build(){ // 可以在build方法中做一些校驗(yàn)等其他工作 if (mBroad.contains("技嘉")){ throw new RuntimeException("技嘉辱華,不支持技嘉主板"); } Computer computer = new Computer(mOS,mBroad,mKeyBoard,mMouse,mCPU,mGPU); return computer; } }
老版本和Builder版本創(chuàng)建對(duì)象
// 老版本的Computer對(duì)象創(chuàng)建 Computer computer = new Computer("MAC OS","微星 B550M","IQUNIX F97" ,"羅技 MX MASTER3","INTEL I5","NV 3060TI"); // Builder版本的Computer對(duì)象創(chuàng)建 Computer computer =Computer.createBuilder() .setCPU("AMD 5600X") .setGPU("NV 3060TI") .setMouse("羅技 MX MASTER3") .setKeyBoard("IQUNIX F97") .build();
兩個(gè)版本一對(duì)比就能體現(xiàn)出來(lái)優(yōu)勢(shì)。老版本構(gòu)造函數(shù)中的參數(shù)太多太長(zhǎng),同一個(gè)類(lèi)型的參數(shù)很容易傳錯(cuò)位,經(jīng)常傳參數(shù)的時(shí)候,還要看看第幾個(gè)參數(shù)應(yīng)該傳什么。
Builder模式的對(duì)象創(chuàng)建,簡(jiǎn)單明了,更容易理解,而且流式的調(diào)用更加美觀,不會(huì)出錯(cuò)。
從代碼中可以看到,Computer類(lèi)的構(gòu)造函數(shù)是私有的,保證了所有對(duì)象的創(chuàng)建都必須從ComputerBuilder這個(gè)類(lèi)來(lái)創(chuàng)建。且ComputerBuilder這個(gè)類(lèi)的build方法中,可以進(jìn)行校驗(yàn)或者其他操作。
同時(shí),Computer這個(gè)類(lèi)中是否存在Set方法,由你的實(shí)際應(yīng)用場(chǎng)景決定,反正我的使用場(chǎng)景里,沒(méi)有修改需求。
注意事項(xiàng)
- 上述代碼為常見(jiàn)寫(xiě)法,并非固定模板。只要能通過(guò)Builder類(lèi)創(chuàng)建目標(biāo)對(duì)象,都可以算是建造者模式。
- 建造者模式中的目標(biāo)對(duì)象的構(gòu)造函數(shù)必須是private修飾。否則可以直接創(chuàng)建對(duì)象。Builder類(lèi)就沒(méi)有意義了
- 建造者模式中的目標(biāo)對(duì)象是否需要Set方法,由具體需求決定。一般情況下沒(méi)有Set方法,可以避免對(duì)該對(duì)象中的參數(shù)進(jìn)行修改。
- Builder中的build方法,可以處理一些邏輯問(wèn)題,比如校驗(yàn)信息等
- 工廠(chǎng)模式注重的是同一類(lèi)型的對(duì)象中通過(guò)參數(shù)來(lái)控制具體創(chuàng)建哪個(gè)對(duì)象。Builder模式關(guān)注的是單一對(duì)象中的參數(shù)傳遞。
以上就是拯救強(qiáng)迫癥Android Builder模式的詳細(xì)內(nèi)容,更多關(guān)于Android Builder模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
BootStrapValidator與My97日期校驗(yàn)的實(shí)例代碼
這篇文章給大家介紹了bootstrapvalidator與my97日期校驗(yàn)的實(shí)例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-01-01Android開(kāi)發(fā)筆記 今天學(xué)到的一些屬性
離開(kāi)實(shí)驗(yàn)室之前再貼上今天下午自己學(xué)到的一些基礎(chǔ)知識(shí) 上午干嘛了呢,忙著數(shù)據(jù)恢復(fù)呢2012-11-11Android實(shí)現(xiàn)自定義的衛(wèi)星式菜單(弧形菜單)詳解
相信大家經(jīng)常在應(yīng)用中會(huì)看到衛(wèi)星菜單,那么這篇文章就來(lái)介紹在Android中如何實(shí)現(xiàn)自定義的衛(wèi)星式菜單(弧形菜單),有需要的可以參考學(xué)習(xí)。2016-08-08Android實(shí)現(xiàn)圖片滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圖片滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09Android利用SoundPool實(shí)現(xiàn)音樂(lè)池
這篇文章主要為大家詳細(xì)介紹了Android利用SoundPool實(shí)現(xiàn)音樂(lè)池,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11Android打開(kāi)手機(jī)相冊(cè)獲取圖片路徑
這篇文章主要為大家詳細(xì)介紹了Android打開(kāi)手機(jī)相冊(cè)獲取圖片路徑,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04Android中實(shí)現(xiàn)Runnable接口簡(jiǎn)單例子
這篇文章主要介紹了Android中實(shí)現(xiàn)Runnable接口簡(jiǎn)單例子,著重點(diǎn)在如何實(shí)現(xiàn)run()方法,需要的朋友可以參考下2014-06-06揭秘在ListView等AdapterView上動(dòng)態(tài)添加刪除項(xiàng)的陷阱
今天遇到這么個(gè)需求,需要在運(yùn)行時(shí)動(dòng)態(tài)添加ListView的item,看起來(lái)很簡(jiǎn)單,實(shí)際操作過(guò)程中卻遇到了麻煩,下面揭秘在ListView等AdapterView上動(dòng)態(tài)添加刪除項(xiàng)的陷阱2016-04-04android view實(shí)現(xiàn)橫向滑動(dòng)選擇
這篇文章主要為大家詳細(xì)介紹了android view實(shí)現(xiàn)橫向滑動(dòng)選擇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07