持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
什么是建造者模式
- 建造者模式又叫生成器迷失,是一种对象构建模式,它可以将复杂对象的建造过程抽象出来,使整个抽象过程的不同实现方法可以构造出不同表现的对象。
- 建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建他们,也就是用户不用知道具体的构建细节。
建造者模式里面的四个角色
- 产品角色:具体的产品对象
- 抽象建造者:创建一个Product对象的各个部件指定的接口/抽象类。
- 具体建造者:实现接口,构建和装配各个部件
- 指挥者:构建一个使用 抽象建造者的对象,主要用于创建一个复杂的对象。隔离客户与对象的生产过程,负责控制产品对象
下面我们使用一个场景来使用 建造者模式
盖房子 :打地基,砌墙,封顶(普通房子,高楼,别墅等)
传统方式:应该先创建一抽象类 或者 接口 提取公共方法 再使用不同的实现类去实现每个类型的房子
准备抽象类
public abstract class AbstraHouse {
public abstract void buildbasic();
public abstract void buildWalls();
public abstract void roofed();
public void build(){
buildbasic();
buildWalls();
roofed();
}
}
创建普通房子继承
public class OrdinaryHouses extends AbstraHouse {
@Override
public void buildbasic() {
System.out.println("普通房子 打地基5米");
}
@Override
public void buildWalls() {
System.out.println("普通房子 砌墙");
}
@Override
public void roofed() {
System.out.println("普通房子 封顶");
}
}
调用创建
public class Client {
public static void main(String[] args) {
OrdinaryHouses tbShopping = new OrdinaryHouses();
tbShopping.build();
}
}
类图
这种方式比较好理解,且简单操作,结构简单没有设计缓存层对象,不利于程序的扩展和维护。这种设计方案,把产品和创建产品 封装在了一起,耦合性增强了。产品不应该和创建过程封装在一起
下面我们来看看建造者模式
类图
产品角色:House
@Data
public class House {
private String basic;
private String type;
}
抽象建造者:
public abstract class HouseBuilder {
protected House house= new House();
public abstract void buildbasic();
public abstract void buildWalls();
public abstract void roofed();
public abstract String basic();
public abstract String type();
//将创建的House返回
public House getHouse() {
house.setType(type());
house.setBasic(basic());
return house;
}
}
具体建造者:
public class OrdinaryHouses extends HouseBuilder{
@Override
public void buildbasic() {
System.out.println("普通房子 打地基5米");
}
@Override
public void buildWalls() {
System.out.println("普通房子 砌墙");
}
@Override
public void roofed() {
System.out.println("普通房子 封顶");
}
@Override
public String basic() {
return "5 m";
}
@Override
public String type() {
return "普通房子";
}
}
public class HighHouses extends HouseBuilder{
@Override
public void buildbasic() {
System.out.println("高楼 打地基20米");
}
@Override
public void buildWalls() {
System.out.println("高楼 砌墙");
}
@Override
public void roofed() {
System.out.println("高楼 封顶");
}
@Override
public String basic() {
return "20 m";
}
@Override
public String type() {
return "高楼";
}
}
指挥者:
public class HouseDirector {
HouseBuilder houseBuilder = null;
//通过set方法传入 抽象建造者的继承者 即就是具体建造者 当然这里也可以用构造器的方式传入 具体建造者
public void setHouseBuilder(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
//如何创建房子以及流程,指挥者来分配
public House createHouse(){
houseBuilder.buildbasic();
houseBuilder.buildWalls();
houseBuilder.roofed();
House house = houseBuilder.getHouse();
return house;
}
}
最后是调用测试:
public class Client {
public static void main(String[] args) {
OrdinaryHouses ordinaryHouses =new OrdinaryHouses();
HouseDirector houseDirector=new HouseDirector();
//创建普通房子
houseDirector.setHouseBuilder(ordinaryHouses);
House house = houseDirector.createHouse();
System.out.println("house = " + house);
HighHouses highHouses =new HighHouses();
houseDirector.setHouseBuilder(highHouses);
House house2 = houseDirector.createHouse();
System.out.println("house2 = " + house2);
}
}
输出结果:
普通房子 打地基5米
普通房子 砌墙
普通房子 封顶
house = House(basic=5 m, type=普通房子)
高楼 打地基20米
高楼 砌墙
高楼 封顶
house2 = House(basic=20 m, type=高楼)
建造模式总结
调用端不必知道产品内部是如何组成的细节,将产品本身与创建过程进行解耦,即同一个创建过程可以创建不同的传品对象。 每一个具体的创建者都是相对独立的,因此一个改动不会影响到其他具体的创建这个。可以更加精细的控制产品的控制过程。 指挥者类针对抽象建造者编程系统扩展更加方便 符合 开闭原则。如果产品之家的差异性很大,则不适合使用建造者模式。
实践是检验真理的唯一方法! 明天见🥰🥰🥰