工厂模式注重直接生产一个对象,而建造者模式 注重一个复杂对象是如何组成的(过程),在生产每个组件时,满足单一原则,实现了业务拆分。
设计模式,一定要敲代码理解
组件抽象
public interface Icomponent {
String position(); //材料分类 :地板 屋顶 门 窗
String type(); //具体材料 如 木窗 ,水泥屋顶
BigDecimal price(); //每平方米的价格
}
组件实现(部分展示)
- 平开窗
/**
* @author ggbond
* @date 2024年04月02日 09:37
* 平开窗
*/
public class CasementWindow implements Icomponent {
@Override
public String position() {
return "窗户";
}
@Override
public String type() {
return "平开窗";
}
@Override
public BigDecimal price() {
return new BigDecimal(120);
}
}
- 推拉窗
/**
* @author ggbond
* @date 2024年04月02日 09:37
* 推拉窗
*/
public class SlidingWindow implements Icomponent {
@Override
public String position() {
return "窗户";
}
@Override
public String type() {
return "旋转窗";
}
@Override
public BigDecimal price() {
return new BigDecimal(80);
}
}
- 瓦片屋顶
/**
* @author ggbond
* @date 2024年04月02日 09:36
* 瓦片屋顶
*/
public class TileRoof implements Icomponent {
@Override
public String position() {
return "屋顶";
}
@Override
public String type() {
return "瓦片屋顶";
}
@Override
public BigDecimal price() {
return new BigDecimal(60);
}
}
组件聚合抽象(需建造的对象)
public interface Ihouse {
Ihouse addDoor(Icomponent door);
Ihouse addFloor(Icomponent floor);
Ihouse addWindow(Icomponent window);
Ihouse addRoof(Icomponent roof);
String getInfo();
}
组件聚合实体
public class House implements Ihouse{
private HashMap<String,Icomponent> map;
private String name;
private BigDecimal area;
private BigDecimal prize=BigDecimal.ZERO;
private House(){};
public House(float area, String name){
map=new HashMap<>();
this.area=new BigDecimal(area);
this.name=name;
}
@Override
public Ihouse addDoor(Icomponent door) {
map.put("door",door);
prize=prize.add(door.price());
return this;
}
@Override
public Ihouse addFloor(Icomponent floor) {
map.put("floor", floor);
prize=prize.add(area.multiply(floor.price()));
return this;
}
@Override
public Ihouse addWindow(Icomponent window) {
map.put("window", window);
prize=prize.add(area.multiply(window.price()));
return this;
}
@Override
public Ihouse addRoof(Icomponent roof) {
map.put("roof", roof);
prize=prize.add(area.multiply(roof.price()));
return this;
}
@Override
public String getInfo(){
StringBuilder info=new StringBuilder(
"房子名称:"+name+"\r\n"+
"装修面积:"+area+"\r\n"+
"装修材料如下:"+"\r\n"+
map.get("door").type()+"\r\n"+
map.get("window").type()+"\r\n"+
map.get("roof").type()+"\r\n"+
map.get("floor").type()+"\r\n"+
"装修费用共计:"+prize+" 元"+"\r\n"+
"---------------------------"+"\r\n");
return info.toString();
}
}
建造者
负责封装实体对象
public class Builder {
public Ihouse type1(float area,String name){
return new House(area,name)
.addDoor(new WoodDoor())
.addFloor(new WoodFloor())
.addWindow(new SlidingWindow())
.addRoof(new TileRoof());
}
public Ihouse type2(float area,String name){
return new House(area,name)
.addDoor(new GlassDoor())
.addFloor(new MarbleFloor())
.addWindow(new CasementWindow())
.addRoof(new CementRoof());
}
}
测试
public class Main {
public static void main(String[] args) {
Builder builder=new Builder();
System.out.println(builder.type1(60f,"ggbond_house1").getInfo());
System.out.println(builder.type2(120f,"ggbond_house2").getInfo());
}
}
结果展示
房子名称:ggbond_house1
装修面积:60
装修材料如下:
木制门
旋转窗
瓦片屋顶
木质地板
装修费用共计:12460 元
---------------------------
房子名称:ggbond_house2
装修面积:120
装修材料如下:
玻璃门
平开窗
水泥屋顶
大理石地砖
装修费用共计:22930 元
---------------------------
总结
建造模式把一个复杂的对象或者流程进行逐个设计,使得各个部分职责划分明确。并对内部进行封装,结合上述代码使用者可以不知道house消息,即可通过builder进行生产不同对象实体。