《重学Java设计模式》之 建造者模式
建造者模式所完成的内容就是通过将多个简单对象通过一步步的组装构建出一个复杂对象的过程
模拟装修公司对于设计出一些套餐装修服务的场景。
很多装修公司都会给出自家的套餐服务,一般有;豪华、轻奢、简约等,这些套餐的后面是不同的商品的组合。按照不同的套餐的价格选取不同的品牌组合,最终再按照装修面积给出一个整体的报价。
这里模拟装修公司想推出一些套餐装修服务,按照不同的价格设定品牌选择组合,以达到使用建造者模式的过程
工程结构
物料接口
public interface IMaterial {
String name(); // 名称;地板、地砖、涂料、吊顶
String brand(); // 品牌
String model(); // 型号
BigDecimal price(); // 价格
String desc(); // 描述
}
德尔(Der)地板
@Service
public class DerFloorImpl implements IMaterial {
@Override
public String name() {
return "地板";
}
@Override
public String brand() {
return "德尔(Der)";
}
@Override
public String model() {
return "A+";
}
@Override
public BigDecimal price() {
return new BigDecimal(119);
}
@Override
public String desc() {
return "DER德尔集团是全球领先的专业木地板制造商,北京2008年奥运会家装和公装地板供应商";
}
}
圣象地板
@Service
public class ShengxiangFloorImpl implements IMaterial {
@Override
public String name() {
return "地板";
}
@Override
public String brand() {
return "圣象";
}
@Override
public String model() {
return "一级";
}
@Override
public BigDecimal price() {
return new BigDecimal(119);
}
@Override
public String desc() {
return "圣象地板是中国地板行业著名品牌。圣象地板拥有中国驰名商标、中国名牌、国家免检、中国环境标志认证等多项荣誉。";
}
}
东鹏地砖
@Service
public class DongPengTileImpl implements IMaterial {
@Override
public String name() {
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亿元,位列建陶行业榜首。";
}
}
马可波罗地砖
@Service
public class MarcoPoloTileImpl implements IMaterial {
@Override
public String name() {
return "地砖";
}
@Override
public String brand() {
return "马可波罗(MARCO POLO)";
}
@Override
public String model() {
return "缺省";
}
@Override
public BigDecimal price() {
return new BigDecimal(140);
}
@Override
public String desc() {
return "“马可波罗”品牌诞生于1996年,作为国内最早品牌化的建陶品牌,以“文化陶瓷”占领市场,享有“仿古砖至尊”的美誉。";
}
}
一级吊顶
@Service
public class LevelOneCeilingImpl implements IMaterial {
@Override
public String name() {
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";
}
}
二级吊顶
@Service
public class LevelTwoCeilingImpl implements IMaterial {
@Override
public String name() {
return "吊顶";
}
@Override
public String brand() {
return "装修公司自带";
}
@Override
public String model() {
return "二级顶";
}
@Override
public BigDecimal price() {
return new BigDecimal(600);
}
@Override
public String desc() {
return "两个层次的吊顶,二级吊顶高度一般就往下吊20cm,要是层高很高,也可增加每级的厚度";
}
}
建造接口
public interface IMenu {
IMenu appendCeiling(IMaterial material); // 吊顶
IMenu appendFloor(IMaterial material); // 地板
IMenu appendTile(IMaterial material); // 地砖
String getDetail(); // 明细
}
具体建造包
public class DecorationPackageMenu implements IMenu {
private List<IMaterial> list = new ArrayList<IMaterial>(); // 装修清单
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(IMaterial material) {
list.add(material);
price = price.add(area.multiply(new BigDecimal("0.2")).multiply(material.price()));
return this;
}
@Override
public IMenu appendFloor(IMaterial material) {
list.add(material);
price = price.add(area.multiply(new BigDecimal("1.5")).multiply(material.price()));
return this;
}
@Override
public IMenu appendTile(IMaterial material) {
list.add(material);
price = price.add(area.multiply(new BigDecimal("1.8")).multiply(material.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 (IMaterial matter: list) {
detail.append(matter.brand()).append("、").append(matter.model()).append("、平米价格:").append(matter.price()).append(" 元。\n");
}
return detail.toString();
}
}
建造者
@Component
public class Builder {
public IMenu getLeveOne(Double area){
DecorationPackageMenu menu = new DecorationPackageMenu(area, "豪华");
return menu.appendCeiling(new LevelOneCeilingImpl())
.appendFloor(new DerFloorImpl())
.appendTile(new DongPengTileImpl());
}
public IMenu getLeveTwo(Double area){
DecorationPackageMenu menu = new DecorationPackageMenu(area, "豪华");
return menu.appendCeiling(new LevelTwoCeilingImpl())
.appendFloor(new ShengxiangFloorImpl())
.appendTile(new MarcoPoloTileImpl());
}
}
测试
public Result<?> mockChange1() {
IMenu leveOne = builder.getLeveOne(100.0);
IMenu leveTwo = builder.getLeveTwo(100.5);
log.info("leveOne:{}",leveOne.getDetail());
log.info("leveTwo:{}",leveTwo.getDetail());
return Result.ok();
}