type
status
date
slug
summary
tags
category
icon
password
一、定义

建造者模式指的是
一个复杂
对象,它是由多个简单
的对象组合,然后一步一步建构而成的二、示例:
模拟场景:
很多装修公司都会给出⾃家的套餐服务,⼀般有;欧式豪华、轻奢⽥园、现代简约等等,⽽这些套餐的后⾯是不同的商品的组合。例如;⼀级&⼆级吊顶、多乐⼠涂料、圣象地板、⻢可波罗地砖等等,按照不同的套餐的价格选取不同的品牌组合,最终再按照装修⾯积给出⼀个整体的报价。
这⾥我们就模拟装修公司想推出⼀些套餐装修服务,按照不同的价格设定品牌选择组合,以达到使⽤建造者模式的过程。
传统硬编码方式(都在一个类里面实现,多重if else嵌套使用)
装修风格类:
DecorationPackageController
package com.qf.design.create.builder.tradition; import com.qf.design.create.builder.entity.Matter; import com.qf.design.create.builder.entity.ceiling.LevelOneCeiling; import com.qf.design.create.builder.entity.ceiling.LevelTwoCeiling; import com.qf.design.create.builder.entity.coat.DuluxCoat; import com.qf.design.create.builder.entity.coat.LiBangCoat; import com.qf.design.create.builder.entity.floor.ShengXiangFloor; import com.qf.design.create.builder.entity.tile.DongPengTile; import com.qf.design.create.builder.entity.tile.MarcoPoloTile; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; public class DecorationPackageController { public String getMatterList(BigDecimal area, Integer level) { List<Matter> list = new ArrayList<Matter>(); // 装修清单 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); 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())); } StringBuilder detail = new StringBuilder("\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(); } }
测试:
ApiTest
package com.qf.design.create.builder.tradition; import java.math.BigDecimal; public class ApiTest { public static void main(String[] args) { DecorationPackageController controller=new DecorationPackageController(); String matterList = controller.getMatterList(new BigDecimal(125.6), 1); System.out.println(matterList); } }
建造者模式
任何的装修风格都是离不开基础的涂料、平层、瓷砖、吊顶。
抽象装修菜单接口:
IMenu
package com.qf.design.create.builder.design; import com.qf.design.create.builder.entity.Matter; public interface IMenu { /** * 吊顶 */ IMenu appendCeiling(Matter matter); /** * 涂料 */ IMenu appendCoat(Matter matter); /** * 平层 */ IMenu appendFloor(Matter matter); /** * 瓷砖 */ IMenu appendTile(Matter matter); /** * 获取价格 */ String getPrice(); }
规则实现:
DecoratePackageMenu
package com.qf.design.create.builder.design; import com.qf.design.create.builder.entity.Matter; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; public class DecoratePackageMenu implements IMenu { private List<Matter> list = new ArrayList<Matter>(); private BigDecimal area; private String grade; private BigDecimal price=BigDecimal.ZERO; public DecoratePackageMenu(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("0.2")).multiply(matter.price())); return this; } @Override public IMenu appendCoat(Matter matter) { list.add(matter); price=price.add(area.multiply(new BigDecimal("1.4")).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 getPrice() { 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(); } }
每一种装修风格对应的是一种装修方法,加入新的风格,只需要扩展新的方法:
Builder
package com.qf.design.create.builder.design; import com.qf.design.create.builder.entity.ceiling.LevelOneCeiling; import com.qf.design.create.builder.entity.ceiling.LevelTwoCeiling; import com.qf.design.create.builder.entity.coat.DuluxCoat; import com.qf.design.create.builder.entity.coat.LiBangCoat; import com.qf.design.create.builder.entity.floor.ShengXiangFloor; import com.qf.design.create.builder.entity.tile.DongPengTile; import com.qf.design.create.builder.entity.tile.MarcoPoloTile; public class Builder { /** * 一级品 * @param area * @return */ public IMenu levelOne(Double area){ return new DecoratePackageMenu(area,"豪华欧式") .appendCeiling(new LevelTwoCeiling()) .appendCeiling(new DuluxCoat()) .appendCeiling(new ShengXiangFloor()); } /** * 三级品 * @param area * @return */ public IMenu levelTwo(Double area){ return new DecoratePackageMenu(area,"轻奢田园") .appendCeiling(new LevelTwoCeiling()) .appendCeiling(new LiBangCoat()) .appendCeiling(new MarcoPoloTile()); } /** * 二级品 * @param area * @return */ public IMenu levelThree(Double area){ return new DecoratePackageMenu(area,"现代简约") .appendCeiling(new LevelOneCeiling()) .appendCeiling(new LiBangCoat()) .appendCeiling(new DongPengTile()); } }
总结:
通过上⾯对建造者模式的使⽤,已经可以摸索出⼀点⼼得。那就是什么时候会选择这样的设计模
式,当:
⼀些基本物料不会变
,⽽其组合经常变化
的时候 ,就可以选择这样的设计模式来构建代码。此设计模式满⾜了
单⼀职责
原则以及可复⽤的技术、建造者独⽴
、易扩展
、便于控制细节⻛险。但
同时当出现特别多的物料以及很多的组合后,类的不断扩展也会造成难以维护的问题。但这种设计
结构模型可以把᯿复的内容抽象到数据库中,按照需要配置。这样就可以减少代码中⼤量的复。- 作者:程序员小舟
- 链接:https://codezhou.top/article/JAVA%E3%80%90%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%91%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章