重学 Java 设计模式:实战建造者模式
作者:小傅哥
博客:bugstack.cn – 原创系列专题文章
堆积、分享、成长,让自己和他人都能有所收成!
一、前言
乱码七糟 [lun q b zo],我常常置疑这个成语是来描述程序猿的!
无论接受什么样I | I % K的需求d & D = T & 8 o,是不是身边总有那么几个人代码写的烂,但是却常常有检验小姐姐过来谈天(求改bug)、有产品小伙伴送S ~ L 3 s G ; f y吃的(求写需求)、有业务小妹妹陪着改代码(求上线),直至领导都以为他的作业很重要,而在周围的你只能蹭点吃的。
那你说,CRUD的代码还想让我怎么样?
这样的小伙伴,或许– o z I 3 g 8把代码写的很直接,U – ) h g ` H – Bifelse
多用g S o一点,满足于先暂时支撑一下,想着这也没什么的。并且这样的业务I % k需求要的急又都是增修改查的内容,真实不想做规划。而假设有人提到说好好规划下,或许也会被反对不要过渡规划。
贴膏药似的修修补补,一次比一次恐怖!
第一次结束产品需求真实是很快,x V x } & o U %但互联网的代码p # o不比传统企业。在传统作业或= z } } $ 2许一套代码能用十年,但在互联网高速的迭代下你的工程,一年就要改动几十次。假设从一开端就0 , 6 7 . ? u想着只需结束功用就可以,那么随之而来的是后续的需求难以接受,每次看着成片D X E 6 |成片的代码,真实不知怎么下手。
在s s =研制流程规范下实行,才华写出好程序!
一个项目的上线往往要履历业务需求
、产品规划
、研制结束
、v c 6 p u检验验证
、上线部署
到正式开量
,而这其间对研制十分Q a l重g x & C r e 4 9要的一换就是研制结束的进程,又可以包括为;架构选型
、M o ( Z功用规划
、规划鉴定
、代码结束
、代码鉴定
、单测覆盖率检查
、编写文档
、提交检验
。所以在一些流程规范下,其实很难让你随意开发代码。
开发代码的进程不是炫技
,就像盖房子假设不按照图纸来修建,回忆就在山墙上搭一个厨房卫浴!或许在实践场景中这很荒唐,但在功用开发( ] Y ? ( 1 ; P y中却总有这样的代码。
所以5 5 ^ P X v Z我们也需求} ( c *一些规划方式的规范思想,去制造+ B C Z E n e v o代码结构,提升全局把控才干。
二、开发环境l ! S c o 3 a { 4
- JDK 1.8
- Idea + Mave E Q s 4 S S x Len
- 触及工程三个,可以经过注重公众号:
bugstack虫洞栈
,回复源码下载
获取(翻开获D * } y 3 B )取的链接,找到序号18)
工程 | 描绘 |
---|---|
itstack-demo-design-3-00 | 场景仿照工程,仿照装修进程中的套餐K i v c a 选择(豪华、田园、精约) |
itstack-demo-design-3-01 | 运用一坨代码结束业务需求,也是对ifelse的运用 |
itstack-demo-desi3 | mgn-3-02 | 经过规划方式优化改造代码,发生比照性然后学习 |
三、制造者方式介绍

制造者方式所结束的内容就是经过将多个简略政策经过一步步的组装构建出一个凌乱政策的进程。
那么,哪里有这样的场景呢?
例如你玩王| / ) a o $者荣耀的时的r h f 5 I M j o F初始化界面;有三条路、有树木、有野怪、有守m / M + + .卫塔等等,甚至依赖于你的网络情况会操控明晰度。而当你换一个场景进行其他不同方式的选择时,相同会制造路程、树木、野怪等等,但是他们的摆放和大小都有不同。这儿就可以用到制造者方式来初始化游戏元素。
而这样的根据相同的物料[ 1 E ] 5 h , _
,不同的组装所发生出的具体的内容,就是制造者方式的毕竟目的,也就是;将一个凌乱的构建与其表明相M [ L B G分离,使得相同的构建进程可以创立不同的表明。
四、事例场景仿照T ; _ p n X %

这儿我们仿照装修公司关于d r / T规划出一些套餐装修服务的场景。
许多装修公司都会给出自家的套餐服务,一般有;欧式豪华、轻奢田园、现代精约等等,而这些套餐的后面是不同的产品的组合。例如;一级&二级吊顶、多乐士涂料、圣象地板、马可波罗地砖等等,按照不同的套餐的价格选取不同的品牌组合,毕竟再按照装修面积给出一个整体的报价。
这儿我们就仿照装修公司想推出一些套餐装修服务,按照不同的价格设定品牌选择组合,以抵达运用制造者方式的进程。
1. 场景仿照工程
itstack-demo-design-3-00
└── src
└── main
└── java
└e ( p } + f J D── org.itsta/ 1 Dck.demo.design
├── ceilling
│ ├── LevelOneCeiling.java
│ └── LevelTwoCeiling.java
├── coat
│ ├── Duluxa . O = X 3Coat.java
│ └── LiBangCoat.java
│ └── LevelTwoCeiling.java
├── floor
│ ├── DerFloor.java
│ └# c P & $ J y `── ShengXiangFloor.java
├── tile
│ ├── DongPengTI - ( - V L S d @ile.java
│ └── MarcoPoloTiler ) _ ^ ; j.java
└── Matter.javk S % ; sa
在仿照工程中供应了 [ R A ~ w E , I装修中所需求的物料;ceilling(吊顶)
、coat(涂料)
、floor(地板% C z)
、tile(地砖)
,这么四项内容。(实践的装修物料要比这个多的多)
2. 场景简述
2.13 r G @ 物料接口
public interface Matter {
SU d u L 8tring scene(); // 场景;地板、地砖、涂料、吊顶
String brand(); // 品牌? a , # B G
SQ y { - x 7 w 2 tring model(); // 类型
BigDecimal price(); // 价格
String desc(); // 描绘
}
- 物料接口供应了底子的信息,以确保一切的^ D ^ 0 c ` U d B装修材料都可以按照共同规范进行获取。
2.2 吊顶(ceiling)
一级顶
public class LevelOneCeiling implements Matter {
public String scene() {
r; $ 8 ] G Y d Deturn "吊顶";
}
pn ^ 9 * `ublic String brand() {
rF z - g +eturn "装修公司自带";
}
public String model() {
return "一级顶";
}
public BigDecim7 M , d 7 G xal pricL _ n q , y e() {
return new BigD= 4 V decimal(260);
}
public String desc() {
return "造型只做低一级,只有一个层次的吊顶,一般离顶120-150mm";
}
}
二级顶
publi] f ? O [ ^ [c class LevelTwoCeilR T ~ % i J ! 3ing implements Matter {
public String sL = / o $ s 2cene() {
return 8 K O p }"吊顶";
}
public String brand() {
returnL T i 9 t ! g | "装6 L g ^ N b ) D饰公司自带";
}
puN * D xblic String model() {
return "二级顶";
}
public BigDecimal price() {
return new BigDecimal(850);
}
public String desc() {
return "两个层次的吊顶,二级吊顶高度一般就往下吊20cm,要是层高很高,也可增加每级的厚度m Z - T Y M";
}
}
2.3 涂料(coat)
多乐士
public class DuluxCoat implements Matter {
public String scene() {
return "涂料";
}
public Str~ 8 = f 9 Oing brand() {
return "多乐士(Dulux)";
}
public String model() {
return "第二代";
}
public BigDecimal price() {
return new BigDecimal(719);
}
public String desc() {
return "多乐士是+ q 2 q [阿克苏诺贝尔旗下的著名修建装修油漆品牌,产品热销于全球100个国家,每年全球有5000万户家庭运用多乐士油漆。";
}
}
立邦
public class LiBangCoat implements Matter {
public String scene() {
return "涂料";
}
public String brand() {
return "立邦"s j 8 9 2 C;S - K t
}
public Stri2 X &ng model() {
return "默许P v + N O G 3等级"^ n d ? 6 o L;
}
public BigDecimal price() {
return new Big| y | a R 0 = n ]Decimd V z 9 L 9 :al(650);
}
public String{ m | / k a | s desc() {
return "立邦一向以开发绿色产品、注重高科技、高品质为政策,以技术力量不断推进科研和开发,满足顾客需求。";
}
}
2.4 地板(floor)
德尔
public class DerFloor implel @ 2 y _ Y ~ gments Matter {
public String scene() {
return "地板";
}
public String brand() {
return "德尔(Der)";
}
public String model() {n j 0 ) r -
return "A+";s $ ^ | 9 ? [ @
}
public BigDecimal price() {
return new BigDecima$ 3 ! 3 [ ! xl(119);
}
public String desc() {
return "DER德尔集团是全球抢先的专业木地板制造商,北京2008年奥运会家装和公装地板供货商R k ? x";
}
}
圣象
pub` @ u z j Glic class ShengXiangFloor implements Matter {
public String scene() {
return "地板";
}
public String brF 4 h G , o 5and() {
return "圣象";
}
public String model() {
return "一级";
}@ o d
public BigD[ z . 8 A t ] H vecimal price() {
return new BigDecimal(318t 6 B C 2 n e X);
}
public String desc() {
return "圣象地板是我国地板作业著名品2 % d j +牌。圣象地板具有我国驰名商标、我国名牌、国家免检、我国环境标志认证等多项荣誉。";
}
}
2.5 地砖(tile)
东鹏
public class DongPengTile implements Matter {
public String scene() {
return "地砖";
}
public Strinc R * ; ]g brandw & 8 V Y ^ , ~ P() {
return "东鹏瓷砖";
}
public String model() {
return "10001";
}
public BigDecimal price() {
return new BigDecimal(102);
}
public Strim 2 Ang dB Z _ { ! ; ~ &esc() {
return "$ 9 d I h L东鹏瓷砖以品质铸就品牌,科技推动品牌,口碑传达品牌为宗旨,2014年品牌价值132.? ^ y35亿元,位列建陶作业第一。";
}
}
马可波罗
public class MarcoPoloTile impleme8 l u : p G 0 unts Matter {
public String scene() {
return "地砖"| ` b o B X _;
}
public String braR e { X } h ^ Dnd() {
return "马可波罗(MARCO POLO)";
}
pu) : 3 ]blic String model() { s H : Z C L
return- 7 ] "缺省";
}
public BigDecimal pricT L P N 6 r g 8e() {
return new BigDecimal(140);
}
public String desc() {
return "“马可波罗”品牌诞生于1996年,作为国内最早品牌化的建陶品牌,以“文明陶瓷”占领市场,享有“仿古砖至尊s [ V m”的美誉。";
}
}
- 以上就是本次装修公司所供应的
装修装备单
,接下我们会经过事例去运用不同的物料组合出不同的套餐服务。
五、用一坨坨代码结束
讲道理没有ifelse处理不7 v [ W {了的逻辑,不行就在加一行!
每一个章节中我们都会运用这样很直白的+ 4 g y p { ^ c方法去把功用结束出来,在经过规划方式去优化完善。这样的代码结构也都是十分简略的,没有凌乱的类联络结构,都是直来直去的代码。除了我们常常着重的这样的代码不能很好的扩展外,做一些比方demo工程还是可以的。
1. 工程结构
itstack-demo-desi% [ ;gn-3-01
└── src
└── main
└── java
└── org.itstack.demo.design
└── DecorationPackaL g 8 $ $ f K 5geController.java
一个类几千行的代码你是否见i * =过,嚯?那今天就让你见识一下有这样潜质的类!
2. ifelse结束需求
public class DecorationPackageController {
publG ? K r -ic Strin[ ] !g getMatterList(BigDecimal area, Integer level) {
List<Matter> list = new ArrayList<Ma& 0 Stterf 2 E @ 4 3>(); // 装修清单
BigDecimal price = BigDecimal.ZERO; // 装修价格
// 豪华欧式
if (1 == level) {
LevelTwoCeilM ( J i O ]ing levelTwoCeilingL W H = newZ M 9 # * , D LevelTwoCeiling(); // 吊顶,二级顶
DuluxCoat duluxCoat = new DuluxCo? l Lat(); // 涂料,多乐士
ShengXiangFloor sm ` 6 $ - k H xhengXiangFloor = new ShengXiangFloor(); // 地板,圣象
list.add(levelTwoCeiling J ^ ~ Dg);
list.add(duluxCoa8 r ) Nt);
list.add(sheng! V M ( NXiangFlooC G ^ 4 ) O 0r);
price = price.add(area.multiply(new BigDecimal("0.2")).multiply(levelTwoCeiling.price()));
price = price.add(area.multiply(new BigDecimal("1.4")).multiply(duluxCoat.price) } f $ : l 0 ~()));
price = price.add(area.multiply(shengXiangFloor.price()));
}
// 轻u E u K奢田园
if (2 == level) {
Lej l A QvelTwoCeiling levelTwoCeiling = new LevelTwoCeiling(); // 吊顶,二级顶
LiBangCA o F O X ~oat liBangCoat = neY b m D Ww LiBang/ 7 ` H dCoat(); // 涂料,立邦
MarcoPoloTile marco3 , } p { ? L P SPoloTile = new MarcoPoloTile(); // 地砖,马可波罗
list.adF x 1 pd(levelTwoCeiling);
list.add(liBangCoat);
list.add(marcoPoloTile);
pricek / | J 1 y = price.add(area.multiply(new BigDecimal("0.2")).multiply(levelTwoCeiling.price()));
price = price.add(area.mu; r wltiply(new BigDecimal("1.4")).multiply(liBangCoat.price()));
price = price.add(area.multiply(marcoPoloT n a ] z %ile.price()));
}
// 现代精约
if (3 == level) {
LevelOneCe! m m f 5iling levelOneCeiling = new LevelOneCeiling(); // 吊顶,二级顶
LiBangCoat liBangCoat = new LiBangCoat(); // 涂料,立邦
DongPengTile dongPengTile = new DongPengTile(); // 地砖,东鹏
list.a, P ^ . R I m 6 Xdd(levelOneCeilingr l # _ | Y -);
list.add(liBangCoat);
list.add(dongPengTile);
price = price.addP D O(area.multiply(new BigDecimal("0.2")).multiply(levelOneCeiling.price()));
price = price.add(area.multiplY / t [ h d U / uy(new BigDecimal("1.4")).multiply(li! d 1 X yBangCoat.price()));
price = price.add(area.multiply(dongPengTile.price()));
}
StringBuilder detail = new StringBuilder("rn-------------------------------------------------------rn" +
"装修清单" + "rn" +
"套餐等级:" + leX c G a $ P | Rvel + "rn" +
"套餐价格:" + price.setScaleG [ A e s U G C |(2, BigDecimal.ROUND_HALF_UP) + " 元rn" +
"房子面积:"R : X + area.doubleValue() + " 平米rn" +
"材料@ _ H Q [ V a清单:rn");
fP s R 6or (G d 5 xMatter matter: list) {
detail.append(matter.scene()).append(":").append(matter.brandZ ^ , k Y C Y()).append("、").append(matter.model()).append("、平米价格:").append(matter.pi ? ! Qrice()).append(" 元。n");
}
return detail@ d H 7 2 0 L #.toString();
}
}
- 首要这段K v C v ~代码所要处理的问题就是接收入参;装修面积(area)、装修等级(le5 B 1 ) Q # ~ Yvel),根据不同类型的装修等级选择不同的材料。
- 其次在结束进程中可以看到每一段
if
块里,都包含着不通的材料(吊顶,D F = | g V + /二级顶、涂料,立邦、地砖,马可波罗),毕竟生成装修清单和装修成本。 - 毕竟供应获取装修具体信息的方法,回来给调用方,用于知道装修清单。
3. 检验验证
接下来我们经过junit单元检验的办X + 1 H 6法验证接口服务,着重日常编写好单测可以更好的进步系统的健壮度。+ ] p R y
编写检验类:
@Test
public void test_DecorationPackageController(){
DecorationPackageController decoration = new Decoz - p b $ Jra+ * S ; # [ } ttionPaM C : H e O nckageController();
// 豪华欧式
System.ou; : O ^ _ _ : `t.println(decoration.getMatterList(new BigDecimal("132.52"),1));
// 轻奢田. o 9 | g D w %园
Syste& Y v 1 d t a o Pm.out.I Y Z m 0 Z d L $println(decoration.getMatterLi_ * Sst(new BigDecimal("98.25"),2))6 [ O j G B * A m;
// 现代精约
System.out.println(decoration.getMatterList(new BigDecimH | v /al("85.43"),3));
}
效果:
-------------------------------------` G & ) C------------------
装修清单
套餐等级:1
套餐价格:198064.39 元
房子/ Q $ o A ? v o g面; Z { W n积:132.52 平米
材料清单:
吊顶:装修公司自带、二级顶、平米价格:850 元。
涂料:多乐士(Dulux)、第二代[ S W H @ v Z l Y、平米价格:719 元。
地板:圣象、一级、平米价格:318 元。
-------------------------------------------------------r r {
装修清单
套餐等级:2
套餐z = ^ v | Z F s价格:119865.00 元
房子面积:98.25~ w u 平米
材料清单:
吊顶:装修公司自带、二级顶、平米价格d 9 f I U:850 元。
涂料:立邦、x K默许等级、平米价格:650 元。
地砖:马可波罗(MARCO POLO)、缺省、平米价格:140 元。
-------------------------------------------------------
装修清单
套餐等级:3
套餐价格:90897.52 元
房子面积:85.43 平米
材料清单:
吊顶:装修公司自带、一级顶、平米价格:260 元。
涂料:立邦、默许等级、平米价格:650 元。
地砖:东鹏瓷砖、10001、平米价格:102 元。
Process finished with exit code 0
- 看7 P 9 [ i到输出的这个效果,现已很R e B m j有装修公司* ; & u X 5 n J供应报价单的感觉了。} , G / f M S . b以上这段运用
ifelse
方法结束的代码,现在现已满足的我们的或许功用。但随着老板对业务的快速展开要求,会供应许多的套餐针/ 1 Z Q w R 5对不同的户型。那么这段结束代码将敏捷扩增到几千行,甚至在修修改改中,现已像膏药相同难以维护。
六、制造者方式重构代码
接下来运用制造者方式来进行代码优化,也算是一次很小的重构。
制造者方式首要处理的问题是在软件系统中,有时分面临着”一个凌乱政策”的创立作业,其一般由各个部分的子政策用必定的进程构成;由于需求的改D 1 – g b变,这个凌乱政策的各个部分常常面临着c / 8严重的改动,但是将它们组合在一起的进程却相对安稳。
这儿我们会把构建的; [ T % L s 2 2进程交给创立者
类,而创立者经过运用我们的构建工具包
,去构建出不同的装修套餐
。
1. 工程结构
itstack-demo-design-3-02
└── src
├── main
│ └── java
│ └── org.itstack.demo.design
│ ├── Builder.java
│ ├── Decorati@ { ?onPackageMenu.java
│ └── IMenu.java
└── test
└── java
└── org.itstack.demo.dI g = f cesign.test
└── ApS v ? { 2 k e miTest.java
制$ 7 6作者模型结构

工程中有三个中心类和一个检验类,中心类是制造者方式的具体结束。与ifelse
结束方法比较,多出来了两个二外的类。具体功用如下;
-
Builderf [ ~ $ D & & /
,制造者类具体的各种组装由此类结束。 -
DecorationPackageMenu
,是IMenu
接口的结束类,首要是承载制o 3 O c w N f M 作进程中的填充器。相当于这是一套承载物料和创立者中间衔接的内容。
好,那么接下来会别离说明几个: w g y x { T 2类的具体+ s g *结束。
2. 代码结束
2.1 界说装修包接口
public interface IMenu {
IMenu appendCeiling(Matter matter); // 吊顶
IMenu appendCoat(Matter maa k C qtter); // 涂料
IMenu appendFloor(Matter matter); // 地板
IMenu appendTile(Matter matter); // 地砖
String getDet1 y n G X B 7 vail()2 ` Q J; // 明细
}
- 接口类中界说了填充各项物料的方法;~ Z E 9 g [ –
吊顶
、涂料
、地板
、地砖
,以及毕竟供应获取悉数明细的方法。
2.2 装修包结束
public class DecorationPackageMenu implements IMenu {
private List<Matter> list = new ArrayList<Matter&g, 1 Nt;(); // 装修清单
private BigDecimal price = BigDecic k , xmal.ZER@ . v eO; // 装修价格
private BigDecimal area; // 面积
private String grade; /T Y , & : { ? D/ 装修等级;豪华欧式、轻奢田园、现代精约
private DecorationPackageMenu() {Q G ^ ! ? | i Y
}
public DecorationN A Y oPackageMenu(Double area, String grade) {
this.area = new BigDeG 2 V I w dcimal(aI K v N c P l 2rea);. O + V , Z
this.grade = gc _ Q 9 Mrade;
}
public IMenu appeno L g ) b 1 ^dCeiling(Matter matter) {
list.add(matter);
price = prS $ g ) j @ Bice.add(area.multiply(new BigDecimal("0.2")).multiply(matter.p] 3 S m Krice()));
return this;
}
public IMenu appendC$ q toat(Matter matter) {
list.add(matter);
price = price.add(area.multiply(new BigDecimal("1.4")).multiply(matter.pr2 - ] 6ice()));
return this;
}
pq 9 $ ! u # g iublic IMq q , $ ] % G )enu apo + E {pendFloor(Matter matter) {
list.add(matter);
price = price.add(area.mul9 - N N - 3tiply(matter.price()));
return this;
}
publice , ; h Z k IMenu appendTile(Matt+ $ l } ) V ker ma5 9 5 = N s stter) {
list.add(matter);
price = price.add(ar3 ] e L Aea.multiply(matter.price()));
return this;
}
public String getDetail() {
StringBuilderb z Y detail = new Stringn H eBuilder("rn-------------------------------------------------------rn" +
"装修清单" + "rn"] Q a y R { +
"套餐等级:" + grade + ". 6 P +rX v v Q C 5 e ln" +
"套餐价格:" + price.setScale(2, BigDecimal.ROUND_HALF_UP) + " 元rn" +
"房子面积:" + area.doubleValue() + Y + J" 平米rn" +
"材料清单:rn");
for (Matter matter: list) {
detail.append(matter.scene()).append(":").append(matter.. j Lbr v ) lrand()).append("、").append(matter.mod} m [ / g Iel()).append("、平米价格:").append(matter.price()).append(" 元。n");
}
return detail.toString();
}
}
- 装修包的完– T f $ d结中每一个方法都会了
thip T . S e ; f Ls
,也就可以十分便利的用于连续填充各项物料。 - 同时在填充时也会根据物料核算平米数下的报价,吊顶和涂料按照平米数适量乘以常熟核算。
- 毕竟相同供应/ S T了共同的获取装修清单的明细方法。
2.3 制造者方法
public class Builder {
pu7 E 1 #blic IMenu levelOne(Do` a =uble area) {
return new DecoratioJ q f $ anPackageMenu(area, "豪华欧式")
.appendCeiling(new LevelTwoCeiling()) // 吊顶,二级顶
.appendCoat(new DuluxCoat()) /6 A s m - x o | K/ 涂料,多Y { C 2 d 7 % } .乐士
.appendFloor(new ShengXiangFloor()); // 地板,圣象
}
public IMenu levelTwo(Double area){
return ne1 y ] 7 ) = Ww D| + ~ B q x Xecoratl C , K V n QionPaO W f ? : PckageMenu(area, "轻奢田园")
.appendCeiling(new LevelTwoCeiling()) // 吊顶,二级顶
.appendCoat(new LiBa@ m / 2 l j )ngCoat()) // 涂料,立邦
.appendTile(new MarcoPoloTile(= W ^ Z _ :));d _ H 1 { 6 } // 地砖,马可波罗
}
public IMenu leve( D 9 ` d } ( 5lThree(Double area){
return new DecorationPac% V 8kageMenu(area, "现代, M }精约")
.appendCeiling(new LevelOneCeiling()) // 吊顶,二级顶
.appendCoat(new LiBangCoat()) // 涂料,# - z b立邦
.appendTile(new DongPengTile()); // 地砖,东鹏
}
}
- 制造者的运用中就现已十分简单了,共同的制G ; . G J p $作方法,经过不同物料填充出不同的装修风格;
豪华欧式
、轻奢田园
、现代精约
,假设将来业务扩展也可以将这部分内容装备到数据库主动生_ ( b $ 4成。但整体的思想还可以R q j运6 k D % m m 8用创立者方式进行树立。
3. 检验验证
编写检验类:U h / X l m
@Test
public void test_Builder(){
Builder builder = new Builder();
// 豪华欧式
System.out.# . . ) /println(builder.levelOne(132.52D).i 5 | . qgetDetail());
// 轻奢田园
System.out.println(buiV ? 9 o 5 ! Mlder.levelTwo(98.25D).getDetaw % ` - t P c hil());
// 现代精约
System.out.prink t Y 7 { D $ _tln(builder.levelThree(85.43D).getDetail());
}
效果:
-------------------------------------------------------
装修清单
套餐等级:豪华欧式
套餐价格:198064.39 元
房子面积:132.52 平米
材料清单:
吊顶:装修公司自带、二级顶、平米价格:850 元。
涂料:多乐士(Dulux)X / y 7 b h (、V T ^ ` % g第二代、平米价格:719 元。
地板:圣象、一级、平米价格:318 元。
-------------------------------------------------------
装修清单
套餐等级:轻奢田园
套餐价格:119865.00 元
房子面积:98.25 平米
材料G T w n # J l : U清单:
吊顶:装修公司自带、二级顶、平米价格:850 元。
涂料:立邦、默许等级、平米价格:650 元。
地砖:马可波罗(MARCO POLO)、缺省、平米价格:N J l 0 p140 元。
----------3 s r v W q 1 A---------------------------------------------
装修清单
套餐等级:d w Y ~ a s K , G现代精约
套餐价格:90897.52 元
房子面积:85.43 平米
材料M ? E t }清单:
吊顶:装修公司自带、一级顶、平米价格:260 元。
涂料:立邦、默许等级、平米价格:650 元。
地砖6 _ D m 2 W Z:东鹏瓷砖、10001、平米价格:102 元。
Process finished with exit code 0
- 检验效果是相同的,调用方法d v f ` & T也底子相似。但是现在的代码结构却可以让你很便利的很有调度的进行扩展业务开发。而不是以往相同把一切代码都写到
ifelse
里边。
七、总结
- 经过上面临制造者方式的运用,现已可以摸索出一点心得。那就是什么时分会选择这样的规划方式,当:
一些底子物料不会变,而其组合常常改动的时分
,就可以选择这样的规划方式来构建代码。 - 此规划方式满足了单一j Q = _ U责任准则以及可复用的技3 C U z e术、制造者独立、易扩展、便于0 + , O 4操控Q ? k }细节危险。但同时当出现特别多的物料以及许多的组合后,类% _ f的不断扩展也会造成难以维护的问题。但这种规划结构模型可以把重复的内容笼统到数据库中,按照需求装备。这样就可以减少代码中很多的重复。
- 规划方式能带给你的是一些思想,但在往常的开发中怎么样明晰的提炼出符合此| W T B m [ w ?思路的制造模块,是比较难的。需求经过一些练习和不断接受更多的项目,然后获得这部分阅历。有的时分你的代码写的好,往往是倒逼O d O的,凌乱的业务频频的改动,不断的挑战!
八、引荐阅读
重学 Java 规划方式:实战工厂方法方式
重学 Java 规划方式:实战笼统工厂方式
Java开发架构篇:初识领域驱动规划DDD落地
Java开发{ W ^ & / g架构篇:DDD模型领域层抉择计划规则树服务规划
Java开发架构篇:领域驱动规划架构基于SpringCloud树立微服务