设计模式-建造者模式

定义:

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

使用场景:

单单看介绍,其实我们还是不明白建造者模式到底是干什么的,简单来说:当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。

实现:

例如我们现在有一个计算机类Computer,其中cpu与ram是必填参数,而其他3个是可选参数,那么我们如何构造这个类的实例呢,通常有两种常用的方式:

1. 折叠构造函数模式(telescoping constructor pattern )
public class Computer {
     ...
    public Computer(String cpu, String ram) {
        this(cpu, ram, 0);
    }
    public Computer(String cpu, String ram, int usbCount) {
        this(cpu, ram, usbCount, "罗技键盘");
    }
    public Computer(String cpu, String ram, int usbCount, String keyboard) {
        this(cpu, ram, usbCount, keyboard, "三星显示器");
    }
    public Computer(String cpu, String ram, int usbCount, String keyboard, String display) {
        this.cpu = cpu;
        this.ram = ram;
        this.usbCount = usbCount;
        this.keyboard = keyboard;
        this.display = display;
    }
}
2. Javabean 模式
public class Computer {
        ...

    public String getCpu() {
        return cpu;
    }
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
    public String getRam() {
        return ram;
    }
    public void setRam(String ram) {
        this.ram = ram;
    }
    public int getUsbCount() {
        return usbCount;
    }
...
}

者两种方式都可以解决问题,但是我们现在要说的是第三种方式,建造者模式。

3. 建造者模式

在这里插入图片描述
builder模式有4个角色:

  • Product: 最终要生成的对象,例如 Computer实例。
  • Builder: 构建者的抽象基类(有时会使用接口代替)。其定义了构建Product的抽象步骤,其实体类需要实现这些步骤。其会包含一个用来返回最终产品的方法Product getProduct()。
  • ConcreteBuilder: Builder的实现类。
  • Director: 决定如何构建最终产品的算法. 其会包含一个负责组装的方法void Construct(Builder builder), 在这个方法中通过调用builder的方法,就可以设置builder,等设置完成后,就可以通过builder的 getProduct() 方法获得最终的产品。

1. 创建builder对象:

package com.example.pattern.designpattern.builder;

import lombok.Data;

/**
 * Product
 * cpu 和 ram 必填,其它选填
 *
 * @author liuyuan
 * @version Computer.java, v 0.1 2020-05-05 16:12
 */
@Data
public class Computer {

    private String cpu;

    private String ram;

    private int usbCount;

    private String keyboard;

    private String display;

    public Computer(String cpu, String ram) {
        this.cpu = cpu;
        this.ram = ram;
    }
} 

2. 构建者的抽象基类:

package com.example.pattern.designpattern.builder;

/**
 * 抽象构建者类 Builder
 *
 * @author liuyuan
 * @version AbstractComputerBuilder.java, v 0.1 2020-05-05 16:15
 */
public abstract class AbstractComputerBuilder {

    public abstract void setUsbCount();

    public abstract void setKeyboard();

    public abstract void setDisplay();

    public abstract Computer getComputer();
} 

3. Builder的实现类:

/**
 * ConcreteBuilder
 *
 * @author liuyuan
 * @version LenovoComputerBuilder.java, v 0.1 2020-05-05 16:18
 */
public class LenovoComputerBuilder extends AbstractComputerBuilder {

    private Computer computer;

    public LenovoComputerBuilder(String cpu, String ram) {
        computer = new Computer(cpu, ram);
    }

    @Override
    public void setUsbCount() {
        computer.setUsbCount(6);
    }

    @Override
    public void setKeyboard() {
        computer.setKeyboard("联想键盘~~");
    }

    @Override
    public void setDisplay() {
        computer.setDisplay("联想显示器~~");
    }

    @Override
    public Computer getComputer() {
        return computer;
    }
} 


/**
 * ConcreteBuilder
 *
 * @author liuyuan
 * @version MacComputerBuilder.java, v 0.1 2020-05-05 16:16
 */
public class MacComputerBuilder extends AbstractComputerBuilder {

    private Computer computer;

    public MacComputerBuilder(String cpu, String ram) {
        computer = new Computer(cpu, ram);
    }

    @Override
    public void setUsbCount() {
        computer.setUsbCount(4);
    }

    @Override
    public void setKeyboard() {
        computer.setKeyboard("苹果键盘~~");
    }

    @Override
    public void setDisplay() {
        computer.setDisplay("苹果显示器~~");
    }

    @Override
    public Computer getComputer() {
        return computer;
    }
}

4. Director,指导者类:

package com.example.pattern.designpattern.builder;

/**
 * 指导者 Director
 *
 * @author liuyuan
 * @version ComputerDirector.java, v 0.1 2020-05-05 16:18
 */
public class ComputerDirector {

    public void makeComputer(AbstractComputerBuilder builder) {

        builder.setUsbCount();

        builder.setDisplay();

        builder.setKeyboard();
    }
} 
  1. 测试:
/**
 * @author liuyuan
 * @version Test.java, v 0.1 2020-05-05 16:19
 */
public class Test {

    public static void main(String[] args) {

        ComputerDirector director = new ComputerDirector();
        AbstractComputerBuilder builder = new MacComputerBuilder("I5处理器", "三星125");
        director.makeComputer(builder);
        Computer macComputer = builder.getComputer();
        System.out.println("mac computer:" + macComputer.toString());

        AbstractComputerBuilder lenovoBuilder = new LenovoComputerBuilder("I7处理器", "海力士222");
        director.makeComputer(lenovoBuilder);
        Computer lenovoComputer = lenovoBuilder.getComputer();
        System.out.println("lenovo computer:" + lenovoComputer.toString());
    }
} 

到这里,经典的建造者模式基本说完了,相对还是比较复杂的,其实我们可以使用建造者模式的一种变种,Builder在Java中一种简化的使用方式:

4. 建造者拓展方式
package com.example.pattern.designpattern.builder;

import lombok.Data;

/**
 * @author liuyuan
 * @version ComputerBuild.java, v 0.1 2020-05-05 16:59
 */
@Data
public class ComputerBuild {

    private String cpu;
    private String ram;
    private int usbCount;
    private String keyboard;
    private String display;

    private ComputerBuild(Builder builder) {
        this.cpu = builder.cpu;
        this.ram = builder.ram;
        this.usbCount = builder.usbCount;
        this.keyboard = builder.keyboard;
        this.display = builder.display;
    }

    public static class Builder {
        private String cpu;
        private String ram;
        private int usbCount;
        private String keyboard;
        private String display;

        public Builder(String cup, String ram) {
            this.cpu = cup;
            this.ram = ram;
        }

        public Builder setUsbCount(int usbCount) {
            this.usbCount = usbCount;
            return this;
        }

        public Builder setKeyboard(String keyboard) {
            this.keyboard = keyboard;
            return this;
        }

        public Builder setDisplay(String display) {
            this.display = display;
            return this;
        }

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

直接通过链式调用,一步步把对象构建出来:

public static ComputerBuild test() {
        return new ComputerBuild.Builder("因特尔", "三星")
                .setDisplay("三星24寸")
                .setKeyboard("罗技")
                .setUsbCount(2)
                .build();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值