设计模式-建造者模式(Builder)

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/love905661433/article/details/84345985

建造者模式(Builder)

  • 定义 : 将一个复杂对象的构建与它的表示分离, 是的同样的构建过程可以创建不同的表示
  • 用户只需指定需要建造的类型就可以得到它们, 建造过程及细节不需要知道
  • 类型 : 创建型设计模式

适用场景

  • 一个对象有非常复杂的内部结构
  • 想把复杂对象的创建和使用分离

优点

  • 封装性好, 创建和使用分离
  • 扩展性好, 建造类之间独立, 一定程度上解耦

缺点

  • 产生多余的Builder对象
  • 产品内部发生变化, 建造者都要修改, 成本较大

模式角色

  • Builder : 为创建一个Product对象的各个部件指定抽象接口

  • ConcreteBuilder : Builder的实现类

    • 实现Builder的接口以构造和装配该产品的各个部件
    • 定义并明确它所创建的表示
    • 提供一个检索产品的接口
  • Director : 构造一个使用Builder接口的对象

  • Product : 被构造的对象

    • 表示被构造的复杂对象。ConcreteBuilder 创建该产品的内部表示并定义它的装配过程
    • 包含定义组成部件的类,包括将这些部件装配成最终产品的接口

代码演示

场景: 组装一台电脑, 场景中各个类对应的角色如下 :

  • Person,组装电脑的人, 对应Director
  • ComputerBuilder, 对应ConcreteBuilder
  • IComputerBuilder接口, 对应模式中的Builder
  • Computer, 对应Product

版本一

UML类图

在这里插入图片描述

IComputerBuilder构造者接口, 对应模式中Builder

/**
 * Builder接口
 * 可以使用接口或者抽象类
 * @author 七夜雪
 * @create 2018-11-22 16:53
 */
public interface IComputerBuilder {
    public void buildCpu(String cpu);
    public void buildMemory(String memory);
    public void buildMainboard(String mainboard);
    public void buildDisk(String disk);
    public Computer build();
}

ComputerBuilder构造者实现, 对应模式中ConcreteBuilder角色

/**
 * builder模式中的builder
 * @author 七夜雪
 * 2018/11/14 13:51
 */
public class ComputerBuilder implements IComputerBuilder{
    private Computer computer  = new Computer();


    @Override
    public Computer build() {
        return this.computer;
    }

    @Override
    public void buildCpu(String cpu){
        computer.setCpu(cpu);
    }

    @Override
    public void buildMemory(String memory){
        computer.setMemory(memory);
    }

    @Override
    public void buildMainboard(String mainboard){
        computer.setMainboard(mainboard);
    }

    @Override
    public void buildDisk(String disk){
        computer.setDisk(disk);
    }

}

Computer电脑类, 对应模式中Product角色

/**
 * 电脑类,Builder模式中的Product
 *
 * @author 七夜雪
 * 2018/11/14 13:48
 */
public class Computer {

    private String cpu;
    private String memory;
    private String mainboard;
    private String disk;

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public void setMemory(String memory) {
        this.memory = memory;
    }

    public void setMainboard(String mainboard) {
        this.mainboard = mainboard;
    }

    public void setDisk(String disk) {
        this.disk = disk;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", mainboard='" + mainboard + '\'' +
                ", disk='" + disk + '\'' +
                '}';
    }
}

Person类, 对应模式中的Director角色

/**
 * builder模式中的Director
 * @author 七夜雪
 * 2018/11/14 15:23
 */
public class Person {
    private ComputerBuilder builder;

    public Person(ComputerBuilder builder) {
        this.builder = builder;
    }

    public Computer excuteBuilder(String cpu, String memory, String disk, String mainboard){
        builder.buildCpu(cpu);
        builder.buildMemory(memory);
        builder.buildDisk(disk);
        builder.buildMainboard(mainboard);
        return builder.build();
    }

}

测试类, 对应模式中的Client角色

/**
 * builder模式测试类
 * @author 七夜雪
 * 2018/11/14 13:56
 */
public class Client {

    public static void main(String[] args) {
        ComputerBuilder builder = new ComputerBuilder();
        Person director = new Person(builder);
        Computer computer = director.excuteBuilder("酷睿I7", "金士顿 DDR4 16G", "三星512G SSD", "华硕X99");
        System.out.println(computer);
    }

}

版本二

版本一种, 如果product存在很多属性, 在执行director的excuteBuilder方法时要传入很多参数, 容易出现错误, 而且如果有些属性不需要的话, 也必须要传一个默认值, 所以更通用的一种写法, 就是讲Product和Builder写在一起, Builder作为Product类的内部类, 同时采用链式编程方式, 可以选择构造部分属性, 对于不需要的属性则不需要进行构造

UML 类图

在这里插入图片描述

代码如下:

/**
 * 电脑类,Builder模式中的Product
 *
 * @author 七夜雪
 * 2018/11/14 13:48
 */
public class Computer {

    public Computer(ComputerBuilder computerBuilder) {
        this.cpu = computerBuilder.cpu;
        this.memory = computerBuilder.memory;
        this.mainboard = computerBuilder.mainboard;
        this.disk = computerBuilder.disk;
    }

    private String cpu;
    private String memory;
    private String mainboard;
    private String disk;

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public void setMemory(String memory) {
        this.memory = memory;
    }

    public void setMainboard(String mainboard) {
        this.mainboard = mainboard;
    }

    public void setDisk(String disk) {
        this.disk = disk;
    }

    public static class ComputerBuilder {
        private String cpu;
        private String memory;
        private String mainboard;
        private String disk;

        public ComputerBuilder buildCPU(String cpu) {
            this.cpu = cpu;
            return this;
        }

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

        public ComputerBuilder buildMainboard(String mainboard){
            this.mainboard = mainboard;
            return this;
        }

        public ComputerBuilder buildDisk(String disk){
            this.disk = disk;
            return this;
        }

        public Computer build(){
            return new Computer(this);
        }
    }


    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", mainboard='" + mainboard + '\'' +
                ", disk='" + disk + '\'' +
                '}';
    }
}
/**
 * Builder第二版测试类
 *
 * @author 七夜雪
 * @create 2018-11-22 17:17
 */
public class ClientV2 {

    public static void main(String[] args) {
        Computer.ComputerBuilder builder = new Computer.ComputerBuilder();
        Computer computer = builder.buildCPU("酷睿I9-9900K")
                .buildMemory("海盗船 DDR4 64G")
                .buildMainboard("华硕Z390")
                .buildDisk("金士顿 1T SSD").build();
        System.out.println(computer);
    }

}

本文参考:
慕课网<java设计模式精讲 Debug 方式+内存分析>课程
四人帮<设计模式>

猜你喜欢

转载自blog.csdn.net/love905661433/article/details/84345985