在软件开发中,经常会遇到需要创建复杂对象的场景。这些对象往往由多个部分组成,且各部分的构建顺序和方式可能较为繁琐。建造者模式作为一种创建型设计模式,能够将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是指将一个复杂对象的构建过程拆分成多个简单部分的构建,然后一步一步地将这些简单部分组合起来,最终构建出复杂对象。简单来说,就是将复杂对象的构建和表示进行分离,让构建过程更加灵活,同时也能更方便地控制构建过程。
这种模式的核心在于 “拆分与组合”,通过不同的建造步骤和组合方式,可以得到不同的复杂对象。在实际开发中,比如创建一个包含多个组件的电脑对象、一个具有多种属性的文档对象等,都可以运用建造者模式。
建造者模式的核心原理是把复杂对象的构建过程分解为多个独立的步骤,每个步骤由专门的建造者负责,最后由指导者来协调这些步骤,完成复杂对象的构建。其结构包含以下关键角色:
(1)产品(Product):表示被构建的复杂对象,它包含多个组成部分,这些组成部分可能有不同的类型和结构。
(2)抽象建造者(Builder):声明了构建产品各个组成部分的抽象方法,以及返回构建完成的产品的方法。它为具体建造者提供了统一的接口规范。
(3)具体建造者(Concrete Builder):实现了抽象建造者接口,负责具体的构建步骤,同时记录了所构建的产品的组成情况。
(4)指导者(Director):负责调用具体建造者按照一定的顺序和方式执行构建步骤,它不直接参与产品的构建,而是控制构建过程的流程。
建造者模式的工作流程是:
指导者首先确定构建产品的步骤和顺序,然后调用具体建造者的相应方法来完成各个部分的构建,最后由具体建造者返回构建完成的产品。
建造者模式在软件开发中有着重要的作用,主要体现在以下几个方面:
(1)分离构建与表示:将复杂对象的构建过程和最终的表示分离开来,使得相同的构建过程可以创建出不同的表示。例如,用同样的步骤可以构建出配置不同的电脑,有的电脑配备高端显卡,有的配备普通显卡。
(2)便于控制构建过程:把复杂的构建过程分解成多个简单的步骤,每个步骤都由专门的方法负责,这样可以更清晰地控制每个步骤的执行,便于调试和修改。
(3)提高代码的复用性:不同的具体建造者可以复用相同的抽象建造者接口,同时,指导者所控制的构建流程也可以在不同的具体建造者中复用。
(4)更灵活地构建对象:通过更换具体建造者,就可以得到不同的产品,而无需修改指导者和其他相关代码,符合开闭原则,增加了系统的灵活性。
建造者模式的优点主要有:
(1)构建过程清晰可控:将复杂对象的构建步骤分解,每个步骤都有明确的方法,使得构建过程一目了然,便于理解和维护。
(2)扩展性好:如果需要创建新的产品,只需新增一个具体建造者实现抽象建造者接口即可,不需要修改原有的代码,符合开闭原则。
(3)便于定制化构建:可以根据不同的需求,通过不同的具体建造者和构建步骤组合,构建出满足特定需求的产品。
(4)隔离了复杂对象的构建和使用:客户端只需知道所需产品的具体建造者,无需了解构建的具体细节,降低了客户端与构建过程的耦合度。
其缺点主要为:
(1)增加了类的数量:引入了产品、抽象建造者、具体建造者和指导者等多个角色,会使系统中的类的数量增加,一定程度上增加了系统的复杂度。
(2)只适用于具有相似构建过程的产品:如果产品之间的构建过程差异很大,那么使用建造者模式会显得很繁琐,此时不适合采用该模式。
(3)可能存在冗余代码:不同的具体建造者可能会有一些重复的代码,如果处理不好,会导致代码冗余。
下面通过以构建一台电脑为例,来演示建造者模式的实现:
//产品类
public class Computer {
private String cpu;
private String memory;
private String hardDisk;
private String graphicsCard;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
}
public void setGraphicsCard(String graphicsCard) {
this.graphicsCard = graphicsCard;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", memory='" + memory + '\'' +
", hardDisk='" + hardDisk + '\'' +
", graphicsCard='" + graphicsCard + '\'' +
'}';
}
}
// 抽象建造者
public interface ComputerBuilder {
void buildCpu();
void buildMemory();
void buildHardDisk();
void buildGraphicsCard();
Computer getComputer();
}
// 具体建造者(游戏电脑)
public class GamingComputerBuilder implements ComputerBuilder {
private Computer computer;
public GamingComputerBuilder() {
computer = new Computer();
}
@Override
public void buildCpu() {
computer.setCpu("I7 15700K");
}
@Override
public void buildMemory() {
computer.setMemory("32GB DDR5内存");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("4TB 三星990pro");
}
@Override
public void buildGraphicsCard() {
computer.setGraphicsCard("RTX 5090");
}
@Override
public Computer getComputer() {
return computer;
}
}
// 具体建造者(办公电脑)
public class OfficeComputerBuilder implements ComputerBuilder {
private Computer computer;
public OfficeComputerBuilder() {
computer = new Computer();
}
@Override
public void buildCpu() {
computer.setCpu("I5 13500H");
}
@Override
public void buildMemory() {
computer.setMemory("16GB DDR5内存");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("2TB 三星980pro");
}
@Override
public void buildGraphicsCard() {
computer.setGraphicsCard("集成显卡");
}
@Override
public Computer getComputer() {
return computer;
}
}
// 指导者
public class Director {
public Computer construct(ComputerBuilder builder) {
builder.buildCpu();
builder.buildMemory();
builder.buildHardDisk();
builder.buildGraphicsCard();
return builder.getComputer();
}
}
//客户端
public class Client {
public static void main(String[] args) {
Director director = new Director();
// 构建游戏电脑
ComputerBuilder gamingBuilder = new GamingComputerBuilder();
Computer gamingComputer = director.construct(gamingBuilder);
System.out.println("游戏电脑配置:" + gamingComputer);
// 构建办公电脑
ComputerBuilder officeBuilder = new OfficeComputerBuilder();
Computer officeComputer = director.construct(officeBuilder);
System.out.println("办公电脑配置:" + officeComputer);
}
}
建造者模式通过将复杂对象的构建过程分解为多个步骤,由具体建造者负责每个步骤的实现,指导者负责协调步骤的执行,实现了构建过程与表示的分离。它在构建具有复杂结构且构建过程相似的对象时非常有效,能够提高代码的灵活性和可维护性。
在实际开发中,需要根据产品的特点和构建需求来决定是否使用建造者模式。当遇到需要创建的对象结构复杂、组成部分较多且构建过程有一定规律时,建造者模式会是一个不错的选择。合理运用建造者模式,可以让代码更加清晰、灵活,便于后续的扩展和维护。