设计模式-建造者模式

167 阅读2分钟

建造者模式用于创建过程稳定,但配置多变的对象,定义是:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

经典的建造者-指挥者模式已经不太常用了,现在建造者模式主要是用来通过链式调用生成不同的配置。比如我们要制作一杯珍珠奶茶,它的制作过程是非常稳定的,除了必须要知道奶茶的种类和规格外,是否加珍珠和是否加冰是可选的。使用建造者模式表示如下:

public class MilkTea {
    private final String type;
    private final String size;
    private final boolean pearl;
    private final boolean ice;

	private MilkTea() {}
	
    private MilkTea(Builder builder) {
        this.type = builder.type;
        this.size = builder.size;
        this.pearl = builder.pearl;
        this.ice = builder.ice;
    }

    public String getType() {
        return type;
    }

    public String getSize() {
        return size;
    }

    public boolean isPearl() {
        return pearl;
    }
    public boolean isIce() {
        return ice;
    }

    public static class Builder {

        private final String type;
        private String size = "中杯";
        private boolean pearl = true;
        private boolean ice = false;

        public Builder(String type) {
            this.type = type;
        }

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

        public Builder pearl(boolean pearl) {
            this.pearl = pearl;
            return this;
        }

        public Builder ice(boolean cold) {
            this.ice = cold;
            return this;
        }

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

可以看到,我们将MilkTea的构造方法设置为私有的,所以外部不能通过new构建出milkTea实例,只能通过Builder构建,对于必须配置的属性,通过Builder的构造方法传入,可选的属性通过Builder的链式调用方法传入,如果不配置,将使用默认的配置,也就是中杯,加珍珠,不加冰。根据不同的配置可以制作出不同的奶茶。

public class User {
    private void buyMilkTea() {
        MilkTea milkTea = new MilkTea.Builder("原味").build();
        show(milkTea);

        MilkTea chocolate =new MilkTea.Builder("巧克力味")
                .ice(false)
                .build();
        show(chocolate);
        
        MilkTea strawberry = new MilkTea.Builder("草莓味")
                .size("大杯")
                .pearl(false)
                .ice(true)
                .build();
        show(strawberry);
    }

    private void show(MilkTea milkTea) {
        String pearl;
        if (milkTea.isPearl())
            pearl = "加珍珠";
        else
            pearl = "不加珍珠";
        String ice;
        if (milkTea.isIce()) {
            ice = "加冰";
        } else {
            ice = "不加冰";
        }
        System.out.println("一份" + milkTea.getSize() + "、"
                + pearl + "、"
                + ice + "的"
                + milkTea.getType() + "奶茶");
    }
}

运行程序,输出如下:

一份中杯、加珍珠、不加冰的原味奶茶

一份中杯、加珍珠、不加冰的巧克力味奶茶

一份大杯、不加珍珠、加冰的草莓味奶茶

使用建造者模式的好处是不用担心忘了指定某个配置,保证了构建过程是稳定的,在OkHttp,Retrofit等著名框架的源码中都使用到了建造者模式。