0
点赞
收藏
分享

微信扫一扫

CSS:九宫格布局

残北 2024-02-09 阅读 23

第六章_建造者模式

1.介绍

1.1定义

建造者模式,即==使用多个简单的对象一步一步构建成一个复杂的对象==

1.2解决的问题

1.3使用场景

1.4应用实例

1.5角色

image-20240207223953516

2.举例

2.1产品

// 产品类,定义产品的三个部分
public class Product {
    private Object part1;
    private Object part2;
    private Object part3;

    public void setPart1(Object part1) {
        this.part1 = part1;
    }

    public void setPart2(Object part2) {
        this.part2 = part2;
    }

    public void setPart3(Object part3) {
        this.part3 = part3;
    }

    @Override
    public String toString() {
        return "Product{" +
                "part1=" + part1 +
                ", part2=" + part2 +
                ", part3=" + part3 +
                '}';
    }
}

2.2抽象建造者

// 抽象建造者类,构建了一个产品对象,并定义了构建产品三个部分所需要的三个方法以及获取产品的方法
public abstract class Builder {
    protected Product product = new Product();

    public abstract void buildPart1();
    public abstract void buildPart2();
    public abstract void buildPart3();
    public abstract Product getProduct();
}

2.3具体建造者

// 具体建造者 1
public class ConcreteBuilder1 extends Builder{
    @Override
    public void buildPart1() {
        product.setPart1("builder 1 set part 1.");
    }

    @Override
    public void buildPart2() {
        product.setPart2("builder 1 set part 2.");
    }

    @Override
    public void buildPart3() {
        product.setPart3("builder 1 set part 3.");
    }

    @Override
    public Product getProduct() {
        System.out.println("builder 1 build product.");
        return product;
    }
}

// 具体建造者 2
public class ConcreteBuilder2 extends Builder {
    @Override
    public void buildPart1() {
        product.setPart1("builder 2 set part 1.");
    }

    @Override
    public void buildPart2() {
        product.setPart2("builder 2 set part 2.");
    }

    @Override
    public void buildPart3() {
        product.setPart3("builder 2 set part 3.");
    }

    @Override
    public Product getProduct() {
        System.out.println("builder 2 build product.");
        return product;
    }
}

2.4指挥者对象

// 指挥者对象
public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public Product construct() {
        builder.buildPart1();
        builder.buildPart2();
        builder.buildPart3();
        Product product = builder.getProduct();
        return product;
    }
}

2.5调用方

public static void main(String[] args) {
    //调用方通过调用指挥者(传入的建造者不同,则创建的过程不一样)来创建产品,屏蔽了创建产品的过程
    Director director1 = new Director(new ConcreteBuilder1());
    Product product1 = director1.construct();
    System.out.println(product1);
    System.out.println("==================================");

    Director director2 = new Director(new ConcreteBuilder2());
    Product product2 = director2.construct();
    System.out.println(product2);
}

2.6测试结果

builder 1 build product.
Product{part1=builder 1 set part 1., part2=builder 1 set part 2., part3=builder 1 set part 3.}
==================================
builder 2 build product.
Product{part1=builder 2 set part 1., part2=builder 2 set part 2., part3=builder 2 set part 3.}

3.实例

3.1产品

public class Car {
    private String brand;
    private String color;
    private String engineType;

    public Car(String brand, String color, String engineType) {
        this.brand = brand;
        this.color = color;
        this.engineType = engineType;
    }

    // 省略 getter 和 setter 方法
}

3.2抽象建造者

public abstract class CarBuilder {
    protected Car car;

    public void createCar() {
        car = new Car();
    }

    public abstract void buildBrand();
    public abstract void buildColor();
    public abstract void buildEngineType();

    public Car getCar() {
        return car;
    }
}

3.3具体建造者

public class SedanCarBuilder extends CarBuilder {
    @Override
    public void buildBrand() {
        car.setBrand("Sedan");
    }

    @Override
    public void buildColor() {
        car.setColor("Red");
    }

    @Override
    public void buildEngineType() {
        car.setEngineType("Gasoline");
    }
}

public class SUVCarBuilder extends CarBuilder {
    @Override
    public void buildBrand() {
        car.setBrand("SUV");
    }

    @Override
    public void buildColor() {
        car.setColor("Blue");
    }

    @Override
    public void buildEngineType() {
        car.setEngineType("Diesel");
    }
}

3.4指挥者对象

public class CarDirector {
    private CarBuilder carBuilder;

    public CarDirector(CarBuilder carBuilder) {
        this.carBuilder = carBuilder;
    }

    public void constructCar() {
        carBuilder.createCar();
        carBuilder.buildBrand();
        carBuilder.buildColor();
        carBuilder.buildEngineType();
    }

    public Car getCar() {
        return carBuilder.getCar();
    }
}

3.5调用方

public class Main {
    public static void main(String[] args) {
        CarBuilder sedanCarBuilder = new SedanCarBuilder();
        CarDirector sedanCarDirector = new CarDirector(sedanCarBuilder);
        sedanCarDirector.constructCar();
        Car sedanCar = sedanCarDirector.getCar();
        System.out.println(sedanCar);

        CarBuilder suvCarBuilder = new SUVCarBuilder();
        CarDirector suvCarDirector = new CarDirector(suvCarBuilder);
        suvCarDirector.constructCar();
        Car suvCar = suvCarDirector.getCar();
        System.out.println(suvCar);
    }
}

3.6测试结果

Car{brand='Sedan', color='Red', engineType='Gasoline'}
Car{brand='SUV', color='Blue', engineType='Diesel'}

4.源码应用

4.1StringBuilder类

JDK 中的建造者模式使用最多的就是 StringBuilder 类

StringBuilder 继承自 AbstractStringBuilder,而我们每次在调用 append 方法的时候就是在往 AbstractStringBuilder 类中变量 value 中追加字符

所以此时 AbstractStringBuilder 就对应抽象建造者StringBuilder 就是具体的建造者String 对象就是我们所需要的产品。但是此时我们并没有发现 Director,其实此时的 StringBuilder 类同时也充当着 Director 的角色,其 toString() 方法就是返回最终 String 对象。

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;

    /**
     * The count is the number of characters used.
     */
    int count;
    
    ……
        
    @Override
    public AbstractStringBuilder append(char c) {
        ensureCapacityInternal(count + 1);
        value[count++] = c;
        return this;
    }
    ……
}
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
    ……

    @Override
    public StringBuilder append(char c) {
        super.append(c);
        return this;
    }

    }
    
    ……
    @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }
}

4.2Lombook中的@Bulider

我们在使用 Lombok 时有个基础注解叫 @Builder,使用该注解的类就不用再 new 对象,直接赋值然后调用 build() 方法便能构建对象。其原理就是在使用该注解的类中生成一个静态的内部 Builder类,然后通过调用该内部类的方法给生成的类对象赋值。我们以 Computer 类为例,代码如下:

@Builder
public class Computer {
    private String CPU;
    private String GPU;
    private String memory;
    private String motherboard;
    private String hardDisk;

}

对代码进行编译后,再看最后生成的代码如下:

public class Computer {
    private String CPU;
    private String GPU;
    private String memory;
    private String motherboard;
    private String hardDisk;

    Computer(String CPU, String GPU, String memory, String motherboard, String hardDisk) {
        this.CPU = CPU;
        this.GPU = GPU;
        this.memory = memory;
        this.motherboard = motherboard;
        this.hardDisk = hardDisk;
    }

    public static Computer.ComputerBuilder builder() {
        return new Computer.ComputerBuilder();
    }

    public static class ComputerBuilder {
        private String CPU;
        private String GPU;
        private String memory;
        private String motherboard;
        private String hardDisk;

        ComputerBuilder() {
        }

        public Computer.ComputerBuilder CPU(String CPU) {
            this.CPU = CPU;
            return this;
        }

        public Computer.ComputerBuilder GPU(String GPU) {
            this.GPU = GPU;
            return this;
        }

        public Computer.ComputerBuilder memory(String memory) {
            this.memory = memory;
            return this;
        }

        public Computer.ComputerBuilder motherboard(String motherboard) {
            this.motherboard = motherboard;
            return this;
        }

        public Computer.ComputerBuilder hardDisk(String hardDisk) {
            this.hardDisk = hardDisk;
            return this;
        }

        public Computer build() {
            return new Computer(this.CPU, this.GPU, this.memory, this.motherboard, this.hardDisk);
        }

        public String toString() {
            return "Computer.ComputerBuilder(CPU=" + this.CPU + ", GPU=" + this.GPU + ", memory=" + this.memory + ", motherboard=" + this.motherboard + ", hardDisk=" + this.hardDisk + ")";
        }
    }
}

5.与工厂模式对比

建造者模式将对象的创建过程和表现分离,并且调用方通过指挥者调用方法对对象进行构建,使得调用方不再关心对象构建过程,构建对象的具体过程可以根据传入类型的不同而改变。通常在实际开发应用中通常会对建造者模式的角色进行阉割,往往只保留真正构建对象的过程。那么有的人就可能会有疑问了,构建者模式最终是获取一个对象,工厂模式也是获取一个对象,这两种模式有什么区别呢?这两种模式都是属于创建型模式,而这两种模式的侧重点不太一样:

6.优缺点

优点:

缺点:

7.参考文章

举报

相关推荐

0 条评论