建造者模式是一种创建型设计模式,它允许你创建复杂对象的过程与该对象的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式适用于以下情况:
1.创建复杂对象:当需要创建的对象比较复杂,包含多个部分或配置选项,并且这些部分之间存在依赖关系或者需要按照特定顺序组装时,建造者模式可以提供一种灵活的方式来构建对象。
2.创建不同表示的对象:当需要创建多种不同表示的对象,但是这些对象都共享相同的构建过程时,建造者模式可以帮助我们封装构建过程,并根据不同的需求创建不同表示的对象。
3.避免过多的构造器参数:当一个类拥有很多构造器参数时,代码可读性和可维护性会变差。建造者模式可以通过提供链式调用或者多个方法来设置参数,从而减少构造器参数的数量,使得代码更加清晰和易于理解。
4.对象的可变性:当需要创建不可变对象(Immutable Objects)时,可以使用建造者模式。通过在建造者模式中只提供设置对象属性的方法而不提供修改方法,可以确保对象的不可变性。
5.动态配置对象:当需要根据运行时的条件动态配置对象的属性时,建造者模式可以提供一种灵活的方式来构建对象,并根据不同的条件设置对象的属性。
总之,建造者模式适用于需要创建复杂对象、需要创建多种不同表示的对象、需要避免过多构造器参数、需要创建不可变对象以及需要动态配置对象属性的情况。通过使用建造者模式,可以将对象的构建过程与表示分离开来,提高代码的可读性、可维护性和灵活性。
直接上代码
首先假设我们的产品是电脑
// 产品类 - 电脑
class Computer {
private String cpu;
private String memory;
private String storage;
private String graphicsCard;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setStorage(String storage) {
this.storage = storage;
}
public void setGraphicsCard(String graphicsCard) {
this.graphicsCard = graphicsCard;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", memory='" + memory + '\'' +
", storage='" + storage + '\'' +
", graphicsCard='" + graphicsCard + '\'' +
'}';
}
}
然后我们给这个电脑一个建设者接口
// 建造者接口
interface ComputerBuilder {
void buildCpu();
void buildMemory();
void buildStorage();
void buildGraphicsCard();
Computer getResult();
}
我们还需要一个指挥者来组装这个接口数据
// 指挥者类
class ComputerDirector {
public Computer construct(ComputerBuilder builder) {
builder.buildCpu();
builder.buildMemory();
builder.buildStorage();
builder.buildGraphicsCard();
return builder.getResult();
}
}
有了上面三个我们就可以开始组装我们的电脑了
比如我需要组装一台游戏电脑
// 具体建造者类 - 游戏电脑
class GamingComputerBuilder implements ComputerBuilder {
private Computer computer = new Computer();
@Override
public void buildCpu() {
computer.setCpu("Intel Core i9");
}
@Override
public void buildMemory() {
computer.setMemory("32GB DDR4");
}
@Override
public void buildStorage() {
computer.setStorage("1TB SSD + 2TB HDD");
}
@Override
public void buildGraphicsCard() {
computer.setGraphicsCard("NVIDIA GeForce RTX 3080");
}
@Override
public Computer getResult() {
return computer;
}
}
我还要组装一台办公电脑
// 具体建造者类 - 办公电脑
class OfficeComputerBuilder implements ComputerBuilder {
private Computer computer = new Computer();
@Override
public void buildCpu() {
computer.setCpu("Intel Core i5");
}
@Override
public void buildMemory() {
computer.setMemory("16GB DDR4");
}
@Override
public void buildStorage() {
computer.setStorage("512GB SSD");
}
@Override
public void buildGraphicsCard() {
// 办公电脑不需要独立显卡
computer.setGraphicsCard("Integrated Graphics");
}
@Override
public Computer getResult() {
return computer;
}
}
测试一下
public class Test {
public static void main(String[] args) {
ComputerDirector director = new ComputerDirector();
// 构建游戏电脑
ComputerBuilder gamingBuilder = new GamingComputerBuilder();
Computer gamingComputer = director.construct(gamingBuilder);
System.out.println("Gaming Computer: " + gamingComputer);
// 构建办公电脑
ComputerBuilder officeBuilder = new OfficeComputerBuilder();
Computer officeComputer = director.construct(officeBuilder);
System.out.println("Office Computer: " + officeComputer);
}
}
运行结果
上面这个示例通过不同的建造者类来实现不同类型电脑的构建,如果对工厂方法模式熟悉的人会发现其实同样的我们用工厂方法模式也能实现上面这个需求
工厂方法模式中的产品:电脑(Computer)
工厂方法模式中的抽象工厂接口:电脑工厂(ComputerFactory)
工厂方法模式中的具体工厂类:游戏电脑工厂(GamingComputerFactory)、办公电脑工厂(OfficeComputerFactory)
具体工厂类实现了工厂接口,每个具体工厂类负责创建特定类型的产品(电脑),从而实现了对不同类型产品的创建。这样,客户端可以根据需要选择合适的具体工厂类来创建相应类型的产品。
与建造者模式相比,工厂方法模式更加注重对象的创建过程的封装和隔离,而不是对象的各个部分的构建顺序和方式。建造者模式适用于对象的构建过程比较复杂,需要灵活地构建对象的不同部分;而工厂方法模式适用于需要创建多种类型对象的情况,需要统一对象的创建接口。