文章优先发表在个人博客: https://www.xdx97.com/article/704350509187727360
1、引出建造者模式
根据说明写出代码
我们需要建造房子,房子的种类有多种,这里只要求两种:平房、高楼。建房的过程两个,打地基、盖房。(真实的房子种类和建造过程及其复杂,这里简化两种即可)
House
import lombok.Data;
@Data
public class House {
private String name;
}
BuildHouse 面向接口写代码
// 构建房子-抽象类
public interface BuildHouse {
// 打地基
void layFoundation();
// 盖房子
void houseBuilding();
// 返回房子
House getHouse();
}
Bungalow 平房
public class Bungalow implements BuildHouse{
@Override
public void layFoundation() {
System.out.println("平房 - 打地基");
}
@Override
public void houseBuilding() {
System.out.println("平房 - 盖房子");
}
@Override
public House getHouse() {
layFoundation();
houseBuilding();
House house = new House();
house.setName("平房");
return house;
}
}
TallBuilding 高楼
public class TallBuilding implements BuildHouse{
@Override
public void layFoundation() {
System.out.println("高楼 - 打地基");
}
@Override
public void houseBuilding() {
System.out.println("高楼 - 盖房子");
}
@Override
public House getHouse() {
layFoundation();
houseBuilding();
House house = new House();
house.setName("高楼");
return house;
}
}
总结
- 以上这样写的代码简单清晰好理解
- 问题是我们把产品和建造的过程封装到一起了,耦合性增强了。
- 我们使用建造者模式修改以上代码进行解耦。
Q: 可能小伙伴觉得,上面这么简单的代码如果进行解耦(使用建造者模式),那不是增加了代码的复杂性嘛?
A: 使用建造者模式的时候我们一般是去解决复杂的对象创建,上面的代码只是为了引出这个思考。如果实际代码真如上面这样简单,那我们的确无需使用建造者模式了。
2、建造者模式
建造者模式:将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方式,可以构造出不同的表现对象。
建造者模式允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道它们内部具体的构建细节。
2-1:建造者模式的四个角色
Product(产品角色) : 一个具体的产品对象。 (比如上面的房子)
Builder(抽象建造者) :创建一个Product对象的各个部件指定的 接口/抽象类
ConcreteBuilder(具体建造者) : 实现Builder接口,构建和装配各个部件。
Director(指挥者) : 它主要是用来创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。
2-2:使用建造者模式对上面代码进行重写
House (产品角色)
import lombok.Data;
@Data
public class House {
private String name;
}
BuildHouse (抽象建造者)
// 构建房子-抽象类
public interface BuildHouse {
// 打地基
void layFoundation();
// 盖房子
void houseBuilding();
// 返回房子
House getHouse();
}
Bungalow 具体建造者
public class Bungalow implements BuildHouse{
@Override
public void layFoundation() {
System.out.println("平房 - 打地基");
}
@Override
public void houseBuilding() {
System.out.println("平房 - 盖房子");
}
@Override
public House getHouse() {
House house = new House();
house.setName("平房");
return house;
}
}
TallBuilding 具体建造者
public class TallBuilding implements BuildHouse{
@Override
public void layFoundation() {
System.out.println("高楼 - 打地基");
}
@Override
public void houseBuilding() {
System.out.println("高楼 - 盖房子");
}
@Override
public House getHouse() {
House house = new House();
house.setName("高楼");
return house;
}
}
Director 指挥者
public class Director {
private BuildHouse buildHouse;
// 基于构造器注入
Director(BuildHouse buildHouse){
this.buildHouse = buildHouse;
}
// 基于set方法注入
public void setBuildHouse(BuildHouse buildHouse){
this.buildHouse = buildHouse;
}
// 具体的构建方法
public House Builder(){
buildHouse.layFoundation();
buildHouse.houseBuilding();
return buildHouse.getHouse();
}
}
注:这里之所以只用两种方式注入,就比如下面的测试,我们要使用这个 Director 去创建两个不同的产品,所以具体建造者需要改变。
测试
public class Main {
public static void main(String[] args) {
Bungalow bungalow = new Bungalow();
TallBuilding tallBuilding = new TallBuilding();
Director director = new Director(bungalow);
// 构建平房
director.Builder();
// 构建高楼
director.setBuildHouse(tallBuilding);
director.Builder();
}
}
2-3:抽象工厂模式和建造者模式的区别
- 抽象工厂模式是去创建一个家族的产品,可以有不同维度的产品。抽象工厂模式不关心创建的过程,只产品由那个工厂生产即可。
- 建造者模式创建的产品之间不能有太大的差异。它需要按照指定的蓝图去创建产品,主要目的是通过组装零配件而产生一个新产品。