一 本质是什么
建造者模式就是把一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.
二 案例模拟
装修公司有不同的装修套餐,一般有欧式豪华/轻奢田园/现在简约等,这些套餐由不同的原料组合而成,在按照装修的面积给出一个整体的报价
2.1 项目结构
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ ├─demo
│ │ │ │ └─design
│ │ │ │ ├─builder
│ │ │ │ ├─decoration
│ │ │ │ ├─matter
│ │ │ │ │ ├─ceilling
│ │ │ │ │ ├─coat
│ │ │ │ │ ├─floor
│ │ │ │ │ └─tile
│ │ │ │ └─menu
2.2 物料接口
保证所有的装修材料都按照统一的标准进行获取
package com.demo.design.matter;
import java.math.BigDecimal;
/**
* com.demo.design.matter
* @create 2022-04-12 15:47
* @Description: 物料接口
**/
public interface Matter {
String scene();//场景;地板/地砖/涂料/吊顶
String brand();//品牌
String model();//型号
BigDecimal price();//价格
String desc();//描述
}
2.3 物料实现类
2.3.1 吊顶
package com.demo.design.matter.ceilling;
import com.demo.design.matter.Matter;
import java.math.BigDecimal;
/**
* com.demo.design.matter.ceilling
* @create 2022-04-12 15:51
* @Description: 一级顶
**/
public class LevelOneCeiling implements Matter {
@Override
public String scene() {
return "吊顶";
}
@Override
public String brand() {
return "装修公司自带";
}
@Override
public String model() {
return "一级顶";
}
@Override
public BigDecimal price() {
return new BigDecimal(260);
}
@Override
public String desc() {
return "造型只做一级,只有一个层次的吊顶,一般离顶120-150mm";
}
}
package com.demo.design.matter.ceilling;
import com.demo.design.matter.Matter;
import java.math.BigDecimal;
/**
* com.demo.design.matter.ceilling
* @create 2022-04-12 15:54
* @Description: 二级顶
**/
public class LevelTwoCeiling implements Matter {
@Override
public String scene() {
return "吊顶";
}
@Override
public String brand() {
return "装修公司自带";
}
@Override
public String model() {
return "二级顶";
}
@Override
public BigDecimal price() {
return new BigDecimal(850);
}
@Override
public String desc() {
return "两个层次的吊顶,二级吊顶高度一般就往下吊20cm,要是层高很高,也可增加每级的厚度";
}
}
2.3.2 涂料
package com.demo.design.matter.coat;
import com.demo.design.matter.Matter;
import java.math.BigDecimal;
/**
* com.demo.design.matter.coat
*
* @author ZhangMinging
* @create 2022-04-12 16:00
* @Description: 涂料:立邦
**/
public class LibangCoat implements Matter {
@Override
public String scene() {
return "涂料";
}
@Override
public String brand() {
return "立邦";
}
@Override
public String model() {
return "默认级别";
}
@Override
public BigDecimal price() {
return new BigDecimal(650);
}
@Override
public String desc() {
return "⽴邦始终以开发绿⾊产品、注᯿⾼科技、⾼品质为⽬标,以技术⼒量不断推进科研和开发,满⾜消费者需求。";
}
}
package com.demo.design.matter.coat;
import com.demo.design.matter.Matter;
import java.math.BigDecimal;
/**
* com.demo.design.matter.coat
* @create 2022-04-12 15:57
* @Description: 涂料一:多乐士
**/
public class DuluxCoat implements Matter {
@Override
public String scene() {
return "涂料";
}
@Override
public String brand() {
return "多乐士(Dulux)";
}
@Override
public String model() {
return "第二代";
}
@Override
public BigDecimal price() {
return new BigDecimal(719);
}
@Override
public String desc() {
return "多乐⼠是阿克苏诺⻉尔旗下的著名建筑装饰油漆品牌,产品畅销于全球100个国家,每年全球有5000万户家庭使⽤多乐⼠油漆。";
}
}
2.3.3 地板
package com.demo.design.matter.floor;
import com.demo.design.matter.Matter;
import java.math.BigDecimal;
/**
* com.demo.design.matter.floor
* @create 2022-04-12 16:02
* @Description: 地板:der
**/
public class DerFloor implements Matter {
@Override
public String scene() {
return "地板";
}
@Override
public String brand() {
return "德尔";
}
@Override
public String model() {
return "A+";
}
@Override
public BigDecimal price() {
return new BigDecimal(119);
}
@Override
public String desc() {
return "DER德尔集团是全球领先的专业⽊地板制造商,北京2008年奥运会家装和公装地板供应商";
}
}
package com.demo.design.matter.floor;
import com.demo.design.matter.Matter;
import java.math.BigDecimal;
/**
* com.demo.design.matter.floor
* @create 2022-04-12 16:04
* @Description: 地板:shengxiang
**/
public class ShengxiangFloor implements Matter {
@Override
public String scene() {
return "地板";
}
@Override
public String brand() {
return "圣象";
}
@Override
public String model() {
return "一级";
}
@Override
public BigDecimal price() {
return new BigDecimal(118);
}
@Override
public String desc() {
return "圣象地板是中国地板⾏业著名品牌。圣象地板拥有中国驰名商标、中国名牌、国\n" +
"家免检、中国环境标志认证等多项荣誉。";
}
}
2.3.4 地砖
package com.demo.design.matter.tile;
import com.demo.design.matter.Matter;
import java.math.BigDecimal;
/**
* com.demo.design.matter.tile
* @create 2022-04-12 16:07
* @Description: 地砖/dongpeng
**/
public class DongPengTile implements Matter {
@Override
public String scene() {
return "地砖";
}
@Override
public String brand() {
return "东鹏瓷砖";
}
@Override
public String model() {
return "10001";
}
@Override
public BigDecimal price() {
return new BigDecimal(102);
}
@Override
public String desc() {
return "东鹏瓷砖以品质铸就品牌,科技推动品牌,⼝碑传播品牌为宗旨,2014年品牌价值132.35亿元,位列建陶⾏业榜⾸。";
}
}
package com.demo.design.matter.tile;
import com.demo.design.matter.Matter;
import java.math.BigDecimal;
/**
* com.demo.design.matter.tile
* @create 2022-04-12 16:09
* @Description: 地砖:MarcoPolo
**/
public class MarcoPoloTile implements Matter {
@Override
public String scene() {
return "地砖";
}
@Override
public String brand() {
return "马可波罗";
}
@Override
public String model() {
return "缺省";
}
@Override
public BigDecimal price() {
return new BigDecimal(140);
}
@Override
public String desc() {
return "“⻢可波罗”品牌诞⽣于1996年,作为国内最早品牌化的建陶品牌,以“⽂化陶瓷”占领市场,享有“仿古砖⾄尊”的美誉。";
}
}
2.4 定义装修包接口
package com.demo.design.menu;
import com.demo.design.matter.Matter;
/**
* com.demo.design.menu
* @create 2022-04-12 16:17
* @Description: 定义装修包接口
**/
public interface IMenu {
IMenu appendCeiling(Matter matter);//吊顶
IMenu appendCoat(Matter matter);//涂料
IMenu appendFloor(Matter matter);//地板
IMenu appendTile(Matter matter);//地砖
String getDetail();//明细
}
2.5 装修包的实现
package com.demo.design.decoration;
import com.demo.design.matter.Matter;
import com.demo.design.menu.IMenu;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* com.demo.design.decoration
* @create 2022-04-12 16:16
* @Description: 由IMenu接口实现类,主要是承载建造过程中的填充器,相当于这是一套承载物料和创建者中间衔接的内容
**/
public class DecorationPackageMenu implements IMenu {
private List<Matter> list = new ArrayList<Matter>();//装修清单
private BigDecimal price = BigDecimal.ZERO;//装修价格
private BigDecimal area;//面积
private String grade;//装修等级,豪华欧式,轻奢田园,现代简约
private DecorationPackageMenu(){
}
public DecorationPackageMenu(Double area,String grade){
this.area = new BigDecimal(area);
this.grade = grade;
}
@Override
public IMenu appendCeiling(Matter matter) {
list.add(matter);
price = price.add(area.multiply(new BigDecimal("1.4")).multiply(matter.price()));
return this;
}
@Override
public IMenu appendCoat(Matter matter) {
list.add(matter);
price = price.add(area.multiply(matter.price()));
return this;
}
@Override
public IMenu appendFloor(Matter matter) {
list.add(matter);
price = price.add(area.multiply(matter.price()));
return this;
}
@Override
public IMenu appendTile(Matter matter) {
list.add(matter);
price = price.add(area.multiply(matter.price()));
return this;
}
@Override
public String getDetail() {
StringBuilder detail = new StringBuilder("\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();
}
}
2.6 建造者方法
package com.demo.design.builder;
import com.demo.design.matter.ceilling.LevelOneCeiling;
import com.demo.design.matter.ceilling.LevelTwoCeiling;
import com.demo.design.matter.coat.DuluxCoat;
import com.demo.design.matter.coat.LibangCoat;
import com.demo.design.decoration.DecorationPackageMenu;
import com.demo.design.matter.floor.ShengxiangFloor;
import com.demo.design.menu.IMenu;
import com.demo.design.matter.tile.DongPengTile;
import com.demo.design.matter.tile.MarcoPoloTile;
/**
* com.demo.design.builder
* @create 2022-04-12 16:15
* @Description: 建造者类具体的各种组装由此类实现(套餐类型)
**/
public class Builder {
/**
* 套餐一
* @param area
* @return
*/
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())
.appendFloor(new MarcoPoloTile());
}
/**
* 套餐三
*/
public IMenu levelThree(Double area){
return new DecorationPackageMenu(area,"现在简约")
.appendCeiling(new LevelOneCeiling())
.appendCoat(new LibangCoat())
.appendTile(new DongPengTile());
}
}
2.7 测试验证
import com.demo.design.builder.Builder;
import org.junit.Test;
/**
* PACKAGE_NAME
* @create 2022-04-13 14:15
* @Description: TODO
**/
public class testBuilder {
@Test
public void test_builder(){
Builder builder = new Builder();
System.out.println(builder.levelOne(132.52D).getDetail());
System.out.println(builder.levelTwo(98.52D).getDetail());
System.out.println(builder.levelThree(85D).getDetail());
}
}
2.8 结果
三 总结
- 什么时候会选择这样的设计模式,当一些基本的物料不会变,而其组合经常变化的时候,就可以选择建造者模式来构建代码