设计模式之建造者模式

目录

1. 定义

2. 使用场景

3. 实现方式

3.1 传统的建造者模式

3.2 简化的建造者模式

4. 参考资料

1. 定义

将一个复杂对象的构建与其表示分离(将产品和创建产品的流程进行解耦),使得同样的构建过程可以创建不同的表示。

Product:待创建的对象。

Builder:抽象类,定义了创建Product对象前所需的环节。

ConcreteBuilder:Builder的实现类,实现了创建Product对象前所需的具体环节。

Director:控制Builder创建Product对象的流程。

2. 使用场景

1. 创建某个对象前,需要执行较多的初始化步骤,而客户端不需要知晓具体的创建流程。

2. 某类的构造函数参数较多,而且部分参数是可选时,就可以考虑使用建造者模式来创建对象。

3. 实现方式

3.1 传统的建造者模式

/**
 * 产品
 */
public class Bike {

    private String name = "unknown"; // 名称,可选参数

    private String frame; // 车架

    private String saddle; // 车座

    private String wheel; // 车轮

    private String basket; // 车篮,可选参数

    private String backseat; // 车后座,可选参数

    public Bike() {

    }

    public Bike(String frame, String saddle, String wheel) {
        this.frame = frame;
        this.saddle = saddle;
        this.wheel = wheel;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setFrame(String frame) {
        this.frame = frame;
    }

    public void setSaddle(String saddle) {
        this.saddle = saddle;
    }

    public void setWheel(String wheel) {
        this.wheel = wheel;
    }

    public void setBasket(String basket) {
        this.basket = basket;
    }

    public void setBackseat(String backseat) {
        this.backseat = backseat;
    }

    @Override
    public String toString() {
        return "Bike{" +
                "name='" + name + '\'' +
                ", frame='" + frame + '\'' +
                ", saddle='" + saddle + '\'' +
                ", wheel='" + wheel + '\'' +
                ", basket='" + basket + '\'' +
                ", backseat='" + backseat + '\'' +
                '}';
    }

}
/**
 * 抽象建造者,定义建造自行车的环节
 */
abstract class Builder {

    public abstract void setName();

    public abstract void setFrame();

    public abstract void setSaddle();

    public abstract void setWheel();

    public abstract void setBasket();

    public abstract void setBackseat();

    public abstract Bike build();

}
/**
 * 低级自行车建造者
 */
class LowerBuilder extends Builder {

    private Bike bike = new Bike();

    @Override
    public void setName() {
        this.bike.setName("低级自行车");
    }

    @Override
    public void setFrame() {
        this.bike.setFrame("低级车架");

    }

    @Override
    public void setSaddle() {
        this.bike.setSaddle("低级车座");
    }

    @Override
    public void setWheel() {
        this.bike.setWheel("低级车轮");
    }

    @Override
    public void setBasket() {
        this.bike.setBasket("无车篮");
    }

    @Override
    public void setBackseat() {
        this.bike.setBackseat("无后座");
    }

    @Override
    public Bike build() {
        return bike;
    }
    
}
/**
 * 高级自行车建造者
 */
class SeniorBuilder extends Builder {

    private Bike bike = new Bike();

    @Override
    public void setName() {
        this.bike.setName("高级自行车");
    }

    @Override
    public void setFrame() {
        this.bike.setFrame("高级车架");

    }

    @Override
    public void setSaddle() {
        this.bike.setSaddle("高级车座");
    }

    @Override
    public void setWheel() {
        this.bike.setWheel("高级车轮");
    }

    @Override
    public void setBasket() {
        this.bike.setBasket("有车篮");
    }

    @Override
    public void setBackseat() {
        this.bike.setBackseat("有后座");
    }

    @Override
    public Bike build() {
        return bike;
    }
    
}
/**
 * 指导者
 */
class Director {

    // 控制builder创建产品的流程
    public void buildBike(Builder builder) {
        builder.setName();
        builder.setFrame();
        builder.setWheel();
        builder.setSaddle();
        builder.setBasket();
        builder.setBackseat();
    }

}
class Test {

    public static void main(String[] args) {
        Director director = new Director();

        Builder lowerBuilder = new LowerBuilder();
        director.buildBike(lowerBuilder);
        Bike lowerBike = lowerBuilder.build();
        System.out.println(lowerBike);
        // Bike{name='低级自行车', frame='低级车架', saddle='低级车座', wheel='低级车轮', basket='无车篮', backseat='无后座'}

        Builder seniorBuilder = new SeniorBuilder();
        director.buildBike(seniorBuilder);
        Bike seniorBike = seniorBuilder.build();
        System.out.println(seniorBike);
        // Bike{name='高级自行车', frame='高级车架', saddle='高级车座', wheel='高级车轮', basket='有车篮', backseat='有后座'}
    }

}

传统的建造者模式解耦了产品和创建流程,ConcreteBuilder负责产品各环节,Director负责组装产品各环节。客户端只需知晓产品的具体建造者ConcreteBuilder,传递给Director便可获得最终产品,而无需知晓创建产品的具体细节。

当然,客户端也可以自己组装产品的创建流程,例如下面的代码:

/**
 * 抽象建造者,定义建造自行车的环节
 */
abstract class Builder {

    public abstract Builder setName();

    public abstract Builder setFrame();

    public abstract Builder setSaddle();

    public abstract Builder setWheel();

    public abstract Builder setBasket();

    public abstract Builder setBackseat();

    public abstract Bike build();

}
/**
 * 低级自行车建造者
 */
class LowerBuilder extends Builder {

    private Bike bike = new Bike();

    @Override
    public Builder setName() {
        this.bike.setName("低级自行车");
        return this;
    }

    @Override
    public Builder setFrame() {
        this.bike.setFrame("低级车架");
        return this;
    }

    @Override
    public Builder setSaddle() {
        this.bike.setSaddle("低级车座");
        return this;
    }

    @Override
    public Builder setWheel() {
        this.bike.setWheel("低级车轮");
        return this;
    }

    @Override
    public Builder setBasket() {
        this.bike.setBasket("无车篮");
        return this;
    }

    @Override
    public Builder setBackseat() {
        this.bike.setBackseat("无后座");
        return this;
    }

    @Override
    public Bike build() {
        return bike;
    }

}
class Test {

    public static void main(String[] args) {
        Builder lowerBuilder = new LowerBuilder();
        lowerBuilder.setName().setFrame().setSaddle().setWheel().setBasket().setBackseat();
        Bike lowerBike = lowerBuilder.build();
        lowerBuilder.build();
        System.out.println(lowerBike);
        // Bike{name='低级自行车', frame='低级车架', saddle='低级车座', wheel='低级车轮', basket='无车篮', backseat='无后座'}
    }

}

上面的代码,去掉了Director,客户端直接通过ConcreteBuilder链式调用,组织创建产品的流程并获取最终产品。

3.2 简化的建造者模式

建造者模式还有一个重要用途,某类的构造函数参数较多,而且部分参数是可选时,就可以考虑使用建造者模式来创建对象。

public class Bike {

    private String name = "unknown"; // 名称,可选参数

    private String frame; // 车架

    private String saddle; // 车座

    private String wheel; // 车轮

    private String basket; // 车篮,可选参数

    private String backseat; // 车后座,可选参数

    private Bike(Builder builder) {
        this.name = builder.name;
        this.frame = builder.frame;
        this.saddle = builder.saddle;
        this.wheel = builder.wheel;
        this.basket = builder.basket;
        this.backseat = builder.backseat;
    }

    public static class Builder {

        private String name = "unknown"; // 名称,可选参数

        private String frame; // 车架

        private String saddle; // 车座

        private String wheel; // 车轮

        private String basket; // 车篮,可选参数

        private String backseat; // 车后座,可选参数

        // 此构造函数包含必须的参数
        public Builder(String frame, String saddle, String wheel) {
            this.frame = frame;
            this.saddle = saddle;
            this.wheel = wheel;
        }

        // 提供可选参数的set方法,并返回当前对象,用于后续链式调用
        public Builder setName(String name) {
            this.name = name;
            return this;
        }

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

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

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

    }

    public void setName(String name) {
        this.name = name;
    }

    public void setFrame(String frame) {
        this.frame = frame;
    }

    public void setSaddle(String saddle) {
        this.saddle = saddle;
    }

    public void setWheel(String wheel) {
        this.wheel = wheel;
    }

    public void setBasket(String basket) {
        this.basket = basket;
    }

    public void setBackseat(String backseat) {
        this.backseat = backseat;
    }

    @Override
    public String toString() {
        return "Bike{" +
                "name='" + name + '\'' +
                ", frame='" + frame + '\'' +
                ", saddle='" + saddle + '\'' +
                ", wheel='" + wheel + '\'' +
                ", basket='" + basket + '\'' +
                ", backseat='" + backseat + '\'' +
                '}';
    }

}
class Test {

    public static void main(String[] args) {
        Bike bike = new Bike.Builder("低级车架", "低级车座", "低级车轮")
                        .setName("低级自行车")
                        .setBasket("无车篮")
                        .setBackseat("无后座")
                        .build();
        System.out.println(bike);
        // Bike{name='低级自行车', frame='低级车架', saddle='低级车座', wheel='低级车轮', basket='无车篮', backseat='无后座'}
    }

}

上面是简化后的建造者模式,与传统建造者模式相比,不仅去掉了Director,而且Builder移到了Product内部,客户端通过Builder链式调用来创建对象,代码可读性更好。

4. 参考资料

建造者模式(全)

彻底理解建造者模式

秒懂设计模式之建造者模式(Builder pattern)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值