一、前言
亂碼七糟 [luàn qī bā zāo],我時常懷疑這個成語是來形容程序猿的! 無論承接什么樣的需求,是不是身邊總有那么幾個人代碼寫的爛,但是卻時常有測試小姐姐過來聊天(_求改bug_)、有產品小伙伴送吃的(_求寫需求_)、有業務小妹妹陪著改代碼(_求上線_),直至領導都認為他的工作很重要,而在旁邊的你只能蹭點吃的。
那你說,CRUD的代碼還想讓我怎么樣?
這樣的小伙伴,可能把代碼寫的很直接,ifelse多用一點,滿足于先臨時支持一下,想著這也沒什么的。而且這樣的業務需求要的急又都是增刪改查的內容,實在不想做設計。而如果有人提到說好好設計下,可能也會被反對不要過度設計。
貼膏藥似的修修補補,一次比一次恐怖!
第一次完成產品需求實在是很快,但互聯網的代碼不比傳統企業。在傳統行業可能一套代碼能用十年,但在互聯網高速的迭代下你的工程,一年就要變動幾十次。如果從一開始就想著只要完成功能就可以,那么隨之而來的是后續的需求難以承接,每次看著成片成片的代碼,實在不知如何下手。
在研發流程規范下執行,才能寫出好程序!
一個項目的上線往往要經歷業務需求、產品設計、研發實現、測試驗證、上線部署到正式開量,而這其中對研發非常重要的一環就是研發實現的過程,又可以包括為;架構選型、功能設計、設計評審、代碼實現、代碼評審、單測覆蓋率檢查、編寫文檔、提交測試。所以在一些流程規范下,其實很難讓你隨意開發代碼。
開發代碼的過程不是炫技,就像蓋房子如果不按照圖紙來修建,回首就在山墻上搭一個廚房衛浴!可能在現實場景中這很荒唐,但在功能開發中卻總有這樣的代碼。
**所以我們也需要一些設計模式的標準思想,去建設代碼結構,提升全局把控能力。**
[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#%E4%BA%8C%E3%80%81%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83)二、開發環境
JDK 1.8
Idea + Maven
涉及工程三個,可以通過關注**公眾號**:[bugstack蟲洞棧(opens new window)](https://bugstack.cn/assets/images/qrcode.png),回復源碼下載獲取(打開獲取的鏈接,找到序號18)
工程
描述
itstack-demo-design-3-00
場景模擬工程,模擬裝修過程中的套餐選擇(豪華、田園、簡約)
itstack-demo-design-3-01
使用一坨代碼實現業務需求,也是對ifelse的使用
itstack-demo-design-3-02
通過設計模式優化改造代碼,產生對比性從而學習
[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#%E4%B8%89%E3%80%81%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E4%BB%8B%E7%BB%8D)三、建造者模式介紹

圖片來自:[https://refactoringguru.cn/design-patterns/builder(opens new window)](https://refactoringguru.cn/design-patterns/builder)
**建造者模式所完成的內容就是通過將多個簡單對象通過一步步的組裝構建出一個復雜對象的過程。**
那么,哪里有這樣的場景呢?
例如你玩王者榮耀的時的初始化界面;有三條路、有樹木、有野怪、有守衛塔等等,甚至依賴于你的網絡情況會控制清晰度。而當你換一個場景進行其他不同模式的選擇時,同樣會建設道路、樹木、野怪等等,但是他們的擺放和大小都有不同。這里就可以用到建造者模式來初始化游戲元素。
而這樣的根據相同的物料,不同的組裝所產生出的具體的內容,就是建造者模式的最終意圖,也就是;**將一個復雜的構建與其表示相分離,使得同樣的構建過程可以創建不同的表示。**
[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#%E5%9B%9B%E3%80%81%E6%A1%88%E4%BE%8B%E5%9C%BA%E6%99%AF%E6%A8%A1%E6%8B%9F)四、案例場景模擬

**這里我們模擬裝修公司對于設計出一些套餐裝修服務的場景。**
很多裝修公司都會給出自家的套餐服務,一般有;歐式豪華、輕奢田園、現代簡約等等,而這些套餐的后面是不同的商品的組合。例如;一級&二級吊頂、多樂士涂料、圣象地板、馬可波羅地磚等等,按照不同的套餐的價格選取不同的品牌組合,最終再按照裝修面積給出一個整體的報價。
這里我們就模擬裝修公司想推出一些套餐裝修服務,按照不同的價格設定品牌選擇組合,以達到使用建造者模式的過程。
[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#_1-%E5%9C%BA%E6%99%AF%E6%A8%A1%E6%8B%9F%E5%B7%A5%E7%A8%8B)1. 場景模擬工程
itstack-demo-design-3-00
└── src└── main└── java└── org.itstack.demo.design├── ceilling│ ├── LevelOneCeiling.java│ └── LevelTwoCeiling.java├── coat│ ├── DuluxCoat.java│ └── LiBangCoat.java│ └── LevelTwoCeiling.java├── floor│ ├── DerFloor.java│ └── ShengXiangFloor.java├── tile│ ├── DongPengTile.java│ └── MarcoPoloTile.java└── Matter.java@小傅哥: 代碼已經復制到剪貼板
在模擬工程中提供了裝修中所需要的物料;ceilling(吊頂)、coat(涂料)、floor(地板)、tile(地磚),這么四項內容。(_實際的裝修物料要比這個多的多_)
[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#_2-%E5%9C%BA%E6%99%AF%E7%AE%80%E8%BF%B0)2. 場景簡述
[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#_2-1-%E7%89%A9%E6%96%99%E6%8E%A5%E5%8F%A3)2.1 物料接口
public interface Matter {String scene(); // 場景;地板、地磚、涂料、吊頂String brand(); // 品牌String model(); // 型號BigDecimal price(); // 價格String desc(); // 描述}@小傅哥: 代碼已經復制到剪貼板
物料接口提供了基本的信息,以保證所有的裝修材料都可以按照統一標準進行獲取。
[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#_2-2-%E5%90%8A%E9%A1%B6-ceiling)2.2 吊頂(ceiling)
**一級頂**
public class LevelOneCeiling implements Matter {public String scene() {return "吊頂";}public String brand() {return "裝修公司自帶";}public String model() {return "一級頂";}public BigDecimal price() {return new BigDecimal(260);}public String desc() {return "造型只做低一級,只有一個層次的吊頂,一般離頂120-150mm";}
}
@小傅哥: 代碼已經復制到剪貼板
`**二級頂**`
public class LevelTwoCeiling implements Matter {
public String scene() {return "吊頂";
}public String brand() {return "裝修公司自帶";
}public String model() {return "二級頂";
}public BigDecimal price() {return new BigDecimal(850);
}public String desc() {return "兩個層次的吊頂,二級吊頂高度一般就往下吊20cm,要是層高很高,也可增加每級的厚度";
}
}
@小傅哥: 代碼已經復制到剪貼板
`1`#### `[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#_2-3-%E6%B6%82%E6%96%99-coat)2.3 涂料(coat)`
`**多樂士
23
**立邦地板(floor)``**德爾**`
public class DerFloor implements Matter {
public String scene() {return "地板";
}public String brand() {return "德爾(Der)";
}public String model() {return "A+";
}public BigDecimal price() {return new BigDecimal(119);
}public String desc() {return "DER德爾集團是全球領先的專業木地板制造商,北京2008年奧運會家裝和公裝地板供應商";
}
}
@小傅哥: 代碼已經復制到剪貼板
`**圣象**`
public class ShengXiangFloor implements Matter {
public String scene() {return "地板";
}public String brand() {return "圣象";
}public String model() {return "一級";
}public BigDecimal price() {return new BigDecimal(318);
}public String desc() {return "圣象地板是中國地板行業著名品牌。圣象地板擁有中國馳名商標、中國名牌、國家免檢、中國環境標志認證等多項榮譽。";
}
}
@小傅哥: 代碼已經復制到剪貼板
#### `[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#_2-5-%E5%9C%B0%E7%A0%96-tile)2.5 地磚(tile)`
`**東鵬**`
public class DongPengTile implements Matter {
public String scene() {return "地磚";
}public String brand() {return "東鵬瓷磚";
}public String model() {return "10001";
}public BigDecimal price() {return new BigDecimal(102);
}public String desc() {return "東鵬瓷磚以品質鑄就品牌,科技推動品牌,口碑傳播品牌為宗旨,2014年品牌價值132.35億元,位列建陶行業榜首。";
}
}
@小傅哥: 代碼已經復制到剪貼板
`**馬可波羅**`
public class MarcoPoloTile implements Matter {
public String scene() {return "地磚";
}public String brand() {return "馬可波羅(MARCO POLO)";
}public String model() {return "缺省";
}public BigDecimal price() {return new BigDecimal(140);
}public String desc() {return "“馬可波羅”品牌誕生于1996年,作為國內最早品牌化的建陶品牌,以“文化陶瓷”占領市場,享有“仿古磚至尊”的美譽。";
}
}
@小傅哥: 代碼已經復制到剪貼板
- `上就是本次裝修公司所提供的裝修配置單,接下我們會通過案例去使用不同的物料組合出不同的套餐服務。`
## `[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#%E4%BA%94%E3%80%81%E7%94%A8%E4%B8%80%E5%9D%A8%E5%9D%A8%E4%BB%A3%E7%A0%81%E5%AE%9E%E7%8E%B0)五、用一坨坨代碼實現`
`講道理沒有ifelse解決不了的邏輯,不行就在加一行!`
`每一個章節中我們都會使用這樣很直白的方式去把功能實現出來,在通過設計模式去優化完善。這樣的代碼結構也都是非常簡單的,沒有復雜的類關系結構,都是直來直去的代碼。除了我們經常強調的這樣的代碼不能很好的擴展外,做一些例子demo工程還是可以的。`
### `[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#_1-%E5%B7%A5%E7%A8%8B%E7%BB%93%E6%9E%84)1. 工程結構`
itstack-demo-design-3-01 └── src └── main └── java └── org.itstack.demo.design └── DecorationPackageController.java
@小傅哥: 代碼已經復制到剪貼板
``` 1
2
3
4
5
6
一個類幾千行的代碼你是否見過,嚯?那今天就讓你見識一下有這樣潛質的類!
**建造者模型結構**

工程中有三個核心類和一個測試類,核心類是建造者模式的具體實現。與ifelse實現方式相比,多出來了兩個二外的類。具體功能如下;
Builder,建造者類具體的各種組裝由此類實現。
DecorationPackageMenu,是IMenu接口的實現類,主要是承載建造過程中的填充器。相當于這是一套承載物料和創建者中間銜接的內容。
[#](https://bugstack.cn/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.html#%E4%B8%83%E3%80%81%E6%80%BB%E7%BB%93)七、總結
通過上面對建造者模式的使用,已經可以摸索出一點心得。那就是什么時候會選擇這樣的設計模式,當:一些基本物料不會變,而其組合經常變化的時候,就可以選擇這樣的設計模式來構建代碼。
此設計模式滿足了單一職責原則以及可復用的技術、建造者獨立、易擴展、便于控制細節風險。但同時當出現特別多的物料以及很多的組合后,類的不斷擴展也會造成難以維護的問題。但這種設計結構模型可以把重復的內容抽象到數據庫中,按照需要配置。這樣就可以減少代碼中大量的重復。
設計模式能帶給你的是一些思想,但在平時的開發中怎么樣清晰的提煉出符合此思路的建造模塊,是比較難的。需要經過一些鍛煉和不斷承接更多的項目,從而獲得這部分經驗。有的時候你的代碼寫的好,往往是倒逼的,復雜的業務頻繁的變化,不斷的挑戰!
本文由博客一文多發平臺 OpenWrite 發布!