建造者模式介绍
将多个简单的对象 , 一步步组装构建出一个复杂对象的过程. 根据相同的 物料 ,不同的组装所产⽣出的具体的内容,就是建造者模式的最终意图,也就是: 将⼀个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
建造者实战场景: 装修都需要吊顶, 涂料, 地板和地砖等. 不同级别的装修, 是不同的吊顶, 涂料, 地板和地砖组合.
创建tutorials-6.0-0项目, 创建吊顶, 涂料, 地板和地砖 pom如下
4.0.0
tutorials-6.0-0
org.example
1.0-SNAPSHOT
定义Matter接口
public interface Matter {
/**
* 场景: 地板 地砖 涂料 吊顶
* @return
*/
String scene();
/**
* 品牌
* @return
*/
String brand();
/**
* 型号
* @return
*/
String model();
/**
* 平米报价
* @return
*/
BigDecimal price();
/**
* 描述
* @return
*/
String desc();
}
定义DongPengTile 瓷砖
package com.thc.demo.tile;
import com.thc.demo.Matter;
import java.math.BigDecimal;
/**
* 类名称:DongPengTile
* 创建时间:2022/3/17 16:46
*/
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 "东鹏瓷砖就是好";
}
}
定义MarcoPoloTile 瓷砖
package com.thc.demo.tile;
import com.thc.demo.Matter;
import java.math.BigDecimal;
/**
* 类名称:MarcoPoloTile
* 创建时间:2022/3/17 16:47
*/
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 "马可波罗瓷砖 大品牌 值得信赖 !";
}
}
定义DerFloor 地板类
package com.thc.demo.floor;
import com.thc.demo.Matter;
import java.math.BigDecimal;
/**
* 类名称:DerFloor
* @author: taohongchao
* 创建时间:2022/3/17 16:50
*/
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 地板 奥运会供应商!";
}
}
定义ShengXiangFloor 地板类
package com.thc.demo.floor;
import com.thc.demo.Matter;
import java.math.BigDecimal;
/**
* 类名称:ShengXiangFloor
* 类描述: 圣象地板
*
* @author: taohongchao
* 创建时间:2022/3/17 17:12
*/
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 "圣象地板中国驰名商标!";
}
}
定义DuluxCoat 涂料
package com.thc.demo.coat;
import com.thc.demo.Matter;
import java.math.BigDecimal;
/**
* 类名称:DuluxCoat
* 类描述: 多乐士涂料
* @author: taohongchao
* 创建时间:2022/3/17 17:14
*/
public class DuluxCoat implements Matter {
public String scene() {
return "涂料";
}
public String brand() {
return "多乐士(Dulux)";
}
public String model() {
return "第二代";
}
public BigDecimal price() {
return new BigDecimal(719);
}
public String desc() {
return "多乐士是阿克苏诺贝尔旗下的著名建筑装饰油漆品牌,产品畅销于全球100个国家,每年全球有5000万户家庭使用多乐士油漆。";
}
}
定义LiBangCoat 涂料
package com.thc.demo.coat;
import com.thc.demo.Matter;
import java.math.BigDecimal;
/**
* 类名称:LiBangCoat 立邦涂料
* @author: taohongchao
* 创建时间:2022/3/17 17:15
*/
public class LiBangCoat implements Matter {
public String scene() {
return "涂料";
}
public String brand() {
return "立邦";
}
public String model() {
return "默认型号";
}
public BigDecimal price() {
return new BigDecimal(650);
}
public String desc() {
return "立邦漆 绿色环保";
}
}
定义LevelOneCeiling吊顶
package com.thc.demo.ceiling;
import com.thc.demo.Matter;
import java.math.BigDecimal;
/**
* 类名称:LevelTwoCeilling
* @author: taohongchao
* 创建时间:2022/3/17 17:22
*/
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";
}
}
定义LevelTwoCeiling吊顶
package com.thc.demo.ceiling;
import com.thc.demo.Matter;
import java.math.BigDecimal;
/**
* 类名称:LevelTwoCeilling
* @author: taohongchao
* 创建时间:2022/3/17 17:22
*/
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 要是层高很高 可增加每级厚度";
}
}
不使用设计模式
不用设计模式 ,实现不同级别的装修 创建tutorials-6.0-1模块, 其pom如下
mydesign-study
org.example
1.0-SNAPSHOT
4.0.0
tutorials-6.0-1
tutorials-6.0-0
org.example
1.0-SNAPSHOT
junit
junit
4.12
test
创建DecorationPackageController类, 实现不同级别的装修
package com.thc.design;
import com.thc.demo.Matter;
import com.thc.demo.ceiling.LevelOneCeiling;
import com.thc.demo.ceiling.LevelTwoCeiling;
import com.thc.demo.coat.DuluxCoat;
import com.thc.demo.coat.LiBangCoat;
import com.thc.demo.floor.ShengXiangFloor;
import com.thc.demo.tile.DongPengTile;
import com.thc.demo.tile.MarcoPoloTile;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 类名称:DecorationPackageController
* 类描述: 装修控制器
*
* 创建时间:2022/3/17 17:36
*/
public class DecorationPackageController {
public String getMatterList(BigDecimal area, Integer level) {
// 装修清单
List list = new ArrayList();
// 装修价格
BigDecimal price = BigDecimal.ZERO;
// 欧式豪华装修
if (1 == level) {
// 吊顶 二级顶
LevelTwoCeiling levelTwoCeiling = new LevelTwoCeiling();
// 涂料 多乐士
DuluxCoat duluxCoat = new DuluxCoat();
// 地板 圣象
ShengXiangFloor shengXiangFloor = new ShengXiangFloor();
list.add(levelTwoCeiling);
list.add(duluxCoat);
list.add(shengXiangFloor);
// 吊顶价格 每平米0.2元
price = price.add(area.multiply(new BigDecimal("0.2")).multiply(levelTwoCeiling.price()));
// 涂料价格
price = price.add(area.multiply(new BigDecimal("1.4")).multiply(duluxCoat.price()));
// 地板价格
price = price.add(area.multiply(shengXiangFloor.price()));
}
// 轻奢田园风
if (2 == level) {
// 吊顶 二级顶
LevelTwoCeiling levelTwoCeiling = new LevelTwoCeiling();
// 涂料 立邦
LiBangCoat liBangCoat = new LiBangCoat();
// 地砖 马可波罗
MarcoPoloTile marcoPoloTile = new MarcoPoloTile();
list.add(levelTwoCeiling);
list.add(liBangCoat);
list.add(marcoPoloTile);
price = price.add(area.multiply(new BigDecimal("0.2")).multiply(levelTwoCeiling.price()));
price = price.add(area.multiply(new BigDecimal("1.4")).multiply(liBangCoat.price()));
price = price.add(area.multiply(marcoPoloTile.price()));
}
// 现代简约风
if (3 == level) {
LevelOneCeiling levelOneCeiling = new LevelOneCeiling(); // 吊顶,二级顶
LiBangCoat liBangCoat = new LiBangCoat(); // 涂料,立邦
DongPengTile dongPengTile = new DongPengTile(); // 地砖,东鹏
list.add(levelOneCeiling);
list.add(liBangCoat);
list.add(dongPengTile);
price = price.add(area.multiply(new BigDecimal("0.2")).multiply(levelOneCeiling.price()));
price = price.add(area.multiply(new BigDecimal("1.4")).multiply(liBangCoat.price()));
price = price.add(area.multiply(dongPengTile.price()));
}
StringBuffer detail = new StringBuffer("\r\n ----------------------\r\n" +
"装修清单" + "\r\n" +
"套餐等级" + level + "\r\n" +
"套餐价格" + price.setScale(2, BigDecimal.ROUND_HALF_UP) + " 元\r\n" +
"房屋面积: " + area.doubleValue() + " 平米\r\n"+
"材料清单: \r\n");
for (Matter matter : list) {
detail.append(matter.scene()).append(": ").append(matter.brand()).append(". ")
.append(matter.model()).append(" 平米价格: ").append(matter.price()).append(" 元 \n");
}
return detail.toString();
}
}
测试类
package com.thc.test;
import com.thc.design.DecorationPackageController;
import org.junit.Test;
import java.math.BigDecimal;
/**
* 类名称:ApiTest
* @author: taohongchao
* 创建时间:2022/3/17 20:00
*/
public class ApiTest {
@Test
public void test_DecorationPackageController() {
DecorationPackageController decoration = new DecorationPackageController();
// 欧式豪华
System.out.println(decoration.getMatterList(new BigDecimal("132.52"), 1));
// 轻奢田园
System.out.println(decoration.getMatterList(new BigDecimal("98.25"), 2));
// 现代简约
System.out.println(decoration.getMatterList(new BigDecimal("85.43"), 3));
}
}
控制台打印如下 :
----------------------
装修清单
套餐等级1
套餐价格198064.39 元
房屋面积: 132.52 平米
材料清单:
吊顶: 装修公司自带. 二级顶 平米价格: 850 元
涂料: 多乐士(Dulux). 第二代 平米价格: 719 元
地板: 圣象. 一级 平米价格: 318 元
----------------------
装修清单
套餐等级2
套餐价格119865.00 元
房屋面积: 98.25 平米
材料清单:
吊顶: 装修公司自带. 二级顶 平米价格: 850 元
涂料: 立邦. 默认型号 平米价格: 650 元
地砖: 马可波罗 (marco polo). 通用型号 平米价格: 140 元
----------------------
装修清单
套餐等级3
套餐价格90897.52 元
房屋面积: 85.43 平米
材料清单:
吊顶: 装修公司自带. 一级顶 平米价格: 260 元
涂料: 立邦. 默认型号 平米价格: 650 元
地砖: 东鹏瓷砖. 10001 平米价格: 102 元
Process finished with exit code 0
使用建造者模式优化
创建tutorials-6.0-2模块
mydesign-study
org.example
1.0-SNAPSHOT
4.0.0
tutorials-6.0-2
tutorials-6.0-0
org.example
1.0-SNAPSHOT
junit
junit
4.12
test
创建IMenu 接口
package com.thc.design;
import com.thc.demo.Matter;
/**
* 类名称:IMenu
* @author: 定义装修包接口
* 创建时间:2022/3/17 20:19
*/
public interface IMenu {
/**
* 吊顶
*/
IMenu appendCeiling(Matter matter);
/**
* 涂料
*/
IMenu appendCoat(Matter matter);
/**
* 地板
*/
IMenu appendFloor(Matter matter);
/**
* 地砖
*/
IMenu appendTile(Matter matter);
/**
* 明细
*/
String getDetail();
}
定义DecorationPackageMenu 实现IMenu接口
package com.thc.design;
import com.thc.demo.Matter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 类名称:DecorationPackageMenu
* 装修包
* 创建时间:2022/3/17 20:23
*/
public class DecorationPackageMenu implements IMenu {
// 装修清单
private List list = new ArrayList();
// 装修价格
private BigDecimal price = BigDecimal.ZERO;
// 装修面积
private BigDecimal area ;
// 装修等级
private String grade;
public DecorationPackageMenu() {
}
public DecorationPackageMenu(Double area, String grade) {
this.area = new BigDecimal(area);
this.grade = grade;
}
public IMenu appendCeiling(Matter matter) {
// 计算吊顶的价格
list.add(matter);
price = price.add(area.multiply(new BigDecimal("0.2")).multiply(matter.price()));
return this;
}
public IMenu appendCoat(Matter matter) {
list.add(matter);
price = price.add(area.multiply(new BigDecimal("1.4")).multiply(matter.price()));
return this;
}
public IMenu appendFloor(Matter matter) {
list.add(matter);
price = price.add(area.multiply(matter.price()));
return this;
}
public IMenu appendTile(Matter matter) {
list.add(matter);
price = price.add(area.multiply(matter.price()));
return this;
}
public String getDetail() {
StringBuffer detail = new StringBuffer("\r\n ----------------------\r\n" +
"装修清单" + "\r\n" +
"套餐等级" + grade + "\r\n" +
"套餐价格" + price.setScale(2, BigDecimal.ROUND_HALF_UP) + " 元\r\n" +
"房屋面积: " + area.doubleValue() + " 平米\r\n"+
"材料清单: \r\n");
for (Matter matter : list) {
detail.append(matter.scene()).append(": ").append(matter.brand()).append(". ")
.append(matter.model()).append(" 平米价格: ").append(matter.price()).append(" 元 \n");
}
return detail.toString();
}
}
定义DecorationBuilder, 实现不同级别的装修.
package com.thc.design;
import com.thc.demo.ceiling.LevelOneCeiling;
import com.thc.demo.ceiling.LevelTwoCeiling;
import com.thc.demo.coat.DuluxCoat;
import com.thc.demo.coat.LiBangCoat;
import com.thc.demo.floor.ShengXiangFloor;
import com.thc.demo.tile.DongPengTile;
import com.thc.demo.tile.MarcoPoloTile;
/**
* 类名称:DecorationBuilder
* 创建时间:2022/3/17 20:31
*/
public class DecorationBuilder {
public IMenu levelOne(Double area) {
return new DecorationPackageMenu(area, "豪华欧式")
.appendCeiling(new LevelTwoCeiling())
.appendCoat(new DuluxCoat())
.appendFloor(new ShengXiangFloor());
}
public IMenu levelTwo(Double area) {
return new DecorationPackageMenu(area, "轻奢田园")
.appendCeiling(new LevelTwoCeiling())
.appendCoat(new LiBangCoat())
.appendTile(new MarcoPoloTile());
}
public IMenu levelThree(Double area) {
return new DecorationPackageMenu(area, "现代简约")
.appendCeiling(new LevelOneCeiling())
.appendCoat(new LiBangCoat())
.appendTile(new DongPengTile());
}
}
测试类
import com.thc.design.DecorationBuilder;
import org.junit.Test;
/**
* 类名称:ApiTest
* 创建时间:2022/3/17 21:00
*/
public class ApiTest {
@Test
public void test_Builder() {
DecorationBuilder builder = new DecorationBuilder();
// 豪华欧式
System.out.println(builder.levelOne(132.54D).getDetail());
// 轻奢田园
System.out.println(builder.levelTwo(98.52D).getDetail());
//现代简约
System.out.println(builder.levelThree(85.85D).getDetail());
}
}
控制台打印如下
装修清单
套餐等级豪华欧式
套餐价格198094.28 元
房屋面积: 132.54 平米
材料清单:
吊顶: 装修公司自带. 二级顶 平米价格: 850 元
涂料: 多乐士(Dulux). 第二代 平米价格: 719 元
地板: 圣象. 一级 平米价格: 318 元
----------------------
装修清单
套餐等级轻奢田园
套餐价格120194.40 元
房屋面积: 98.52 平米
材料清单:
吊顶: 装修公司自带. 二级顶 平米价格: 850 元
涂料: 立邦. 默认型号 平米价格: 650 元
地砖: 马可波罗 (marco polo). 通用型号 平米价格: 140 元
----------------------
装修清单
套餐等级现代简约
套餐价格91344.40 元
房屋面积: 85.85 平米
材料清单:
吊顶: 装修公司自带. 一级顶 平米价格: 260 元
涂料: 立邦. 默认型号 平米价格: 650 元
地砖: 东鹏瓷砖. 10001 平米价格: 102 元
Process finished with exit code 0
Spring中的建造者模式
Spring-web模块中UriComponentsBuilder , 用于构建UriComponents