9.建造者模式

文章目录


一、介绍

建造者模式旨在将一个复杂对象的构建过程 和其表示分离,以便同样的构建过程可以创建不同的表示。这种模式适用于构建对象的算法(构建过程)应该独立于对象的组成部分以及它们的装配方式的情景。

建造者模式通常包含以下角色:

  1. 产品(Product): 表示被构建的复杂对象。在建造者模式中,产品是由多个部件组成的。

  2. 抽象建造者(Builder): 声明了创建产品各个部件的抽象接口。通常包括创建和装配部件的方法。

  3. 具体建造者(Concrete Builder): 实现抽象建造者接口,负责具体部件的创建和装配。每个具体建造者都定义了自己的方式来构建产品。

  4. 指导者(Director): 负责使用建造者接口来构建产品对象。通常包含一个构建方法,该方法定义了构建产品的顺序。

二、代码

结构图

代码

java 复制代码
/**
 * 产品类,由多个部件构成
 */
public class Product {

    private List<String> parts = new ArrayList<>();

    public void add(String part) {
        parts.add(part);
    }

    public void show(){
        System.out.println("产品部件 --->");
        for (String part : parts) {
            System.out.print(part+" ");
        }
    }
}
java 复制代码
/**
 * 抽象建造者类,确定产品由两个部件构成,并声明一个得到产品的方法
 */
abstract class Builder{
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract Product getResult();
}
java 复制代码
class Builder1 extends Builder {

    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.add("部件a");
    }

    @Override
    public void buildPartB() {
        product.add("部件b");
    }

    @Override
    public Product getResult() {
        return product;
    }
}
java 复制代码
class Builder2 extends Builder {

    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.add("部件x");
    }

    @Override
    public void buildPartB() {
        product.add("部件y");
    }

    @Override
    public Product getResult() {
        return product;
    }
}
java 复制代码
/**
 * 指挥者类,用来指挥构建过程
 */
class Director {
    public Product Construct(Builder builder) {
        builder.buildPartA();
        builder.buildPartB();
        return builder.getResult();
    }
}
java 复制代码
public static void main(String[] args) {
    Director director = new Director();
    Builder1 builder1 = new Builder1();
    Builder2 builder2 = new Builder2();
    
    Product result1 = director.Construct(builder1);
    result1.show();

    Product result2 = director.Construct(builder2);
    result2.show();
}

三、实际使用

场景

假设我们要创建一个汽车对象,汽车有多个可选的配置,包括引擎类型、车身颜色、轮胎类型等。我们将使用建造者模式来实现汽车对象的配置灵活性。

代码

java 复制代码
// 产品类:汽车
class Car {
    private String engineType;
    private String bodyColor;
    private String tireType;

    // 构造方法私有化,只能通过建造者来构建对象
    private Car() {
    }

    public String getEngineType() {
        return engineType;
    }

    public String getBodyColor() {
        return bodyColor;
    }

    public String getTireType() {
        return tireType;
    }

    // 静态内部类作为具体建造者
    public static class Builder {
        private Car car;

        public Builder() {
            this.car = new Car();
        }

        public Builder setEngineType(String engineType) {
            car.engineType = engineType;
            return this;
        }

        public Builder setBodyColor(String bodyColor) {
            car.bodyColor = bodyColor;
            return this;
        }

        public Builder setTireType(String tireType) {
            car.tireType = tireType;
            return this;
        }

        // 构建汽车对象
        public Car build() {
            return car;
        }
    }
}

// 客户端
public class BuilderPatternFlexibilityExample {
    public static void main(String[] args) {
        // 使用建造者模式构建汽车对象,并灵活配置
        Car car1 = new Car.Builder()
                .setEngineType("V8")
                .setBodyColor("Red")
                .setTireType("Summer")
                .build();

        Car car2 = new Car.Builder()
                .setEngineType("Hybrid")
                .setBodyColor("Blue")
                .build();

        // 输出构建好的汽车对象
        System.out.println("Car 1 - Engine Type: " + car1.getEngineType() +
                ", Body Color: " + car1.getBodyColor() +
                ", Tire Type: " + car1.getTireType());

        System.out.println("Car 2 - Engine Type: " + car2.getEngineType() +
                ", Body Color: " + car2.getBodyColor() +
                ", Tire Type: " + car2.getTireType());
    }
}

上面的例子中,Car 是产品类,Car.Builder 是具体建造者。通过具体建造者,我们可以设置汽车的各个可选配置,最后通过 build 方法得到一个完整的汽车对象。客户端可以根据实际需求来选择设置不同的配置,实现了对象配置的灵活性。这种方式可以避免创建多个构造函数以应对各种配置组合的情况,使得代码更加简洁和可维护。

总结

上面的代码中,我们通过不同的具体建造者,同一个指挥者,获得了不一样的产品。在我们平时的情况中,以下的场景可以用到建造者模式

  1. 创建复杂对象: 当一个对象的构建过程比较复杂,涉及多个步骤、部件组合或配置选项时,建造者模式可以将构建过程与最终表示分离,使得代码更清晰、可维护。

  2. 对象的配置灵活性: 当需要创建的对象具有多个配置选项,而客户端希望能够以不同的方式组装对象时,建造者模式可以提供更灵活的配置选择,而无需创建大量的构造函数。

  3. 避免构造器参数过多: 当一个对象的构造函数参数过多,而且可能存在多个可选参数时,使用建造者模式可以避免创建过多的构造函数,使得代码更加清晰。

相关推荐
铲子Zzz24 分钟前
Java使用接口AES进行加密+微信小程序接收解密
java·开发语言·微信小程序
霖檬ing29 分钟前
K8s——配置管理(1)
java·贪心算法·kubernetes
小小小新人1212344 分钟前
C语言 ATM (4)
c语言·开发语言·算法
Two_brushes.1 小时前
【linux网络】网络编程全流程详解:从套接字基础到 UDP/TCP 通信实战
linux·开发语言·网络·tcp/udp
小白学大数据1 小时前
R语言爬虫实战:如何爬取分页链接并批量保存
开发语言·爬虫·信息可视化·r语言
争不过朝夕,又念着往昔1 小时前
Go语言反射机制详解
开发语言·后端·golang
Azxcc01 小时前
C++异步编程入门
开发语言·c++
Vic101011 小时前
Java 开发笔记:多线程查询逻辑的抽象与优化
java·服务器·笔记
Biaobiaone1 小时前
Java中的生产消费模型解析
java·开发语言
我命由我123451 小时前
前端开发问题:SyntaxError: “undefined“ is not valid JSON
开发语言·前端·javascript·vue.js·json·ecmascript·js