【设计模式系列】9.建造者模式

目录

一、建造者模式特点

二、建造者模式结构分析

三、举例1 —— 生产不同的包装饮料

四、举例2 —— 优化:链式调用


一、建造者模式特点

  • 属于创建型模式,是一种将 复杂对象的建造它的表示 分开,使得一样的建造过程可以创造不同的表示。因此,建造对象时只需要指定建造的类型,而不需要关心内部的建造过程。
  • 创建型模式的最大的特点就是 链式调用 和 多变的构造方法,后面举例说明。

二、建造者模式结构分析

该模式有四个角色,类图如下:

  • Product(产品类):需要被构建的复杂对象;
  • Builder(抽象建造者):规范产品的组建,一般是由子类实现具体的过程;
  • ConcreteBuilder(具体建造者):实现抽象接口,构建复杂对象;
  • Director(指挥者):构造一个使用Builder接口的对象。

注意事项:

  • Builder接口中buildPartA()、buildPartB()、buildPartC()的顺序不同,可能会产生不同的结果,需要注意组装时的顺序性;
  • 用不同的ConcreteBuilder类构建对象时,会产生不同的结果;

三、举例1 —— 生产不同的包装饮料

  • 创建Builder(公共接口,定义通用行为)
public interface DrinkBuilder {
    // 生产饮料需要的原材料
    void bottleBody(String body);

    void water(String water);

    void bottleCap(String cap);

    void label(String label);

    String creatDrink();
}
  • 创建ConcreteBuilder1(可口可乐,实现接口父类)
public class BuilderCocaCola implements DrinkBuilder {
    // 饮料名称
    private String drinkName = "饮料名称为:";

    @Override
    public void bottleBody(String bodyCocaCola) {
        drinkName += bodyCocaCola;
    }

    @Override
    public void water(String waterCocaCola) {
        drinkName += waterCocaCola;
    }

    @Override
    public void bottleCap(String capCocaCola) {
        drinkName += capCocaCola;
    }

    @Override
    public void label(String labelCocaCola) {
        drinkName += labelCocaCola;
    }

    @Override
    public String creatDrink() {
        return drinkName;
    }
}
  • 创建ConcreteBuilder2(旺仔牛奶,实现接口父类)
public class BuilderWWCMilk implements DrinkBuilder {
    // 饮料名称
    private String drinkName = "饮料名称为:";

    @Override
    public void bottleBody(String bodyWWCMilk) {
        drinkName += bodyWWCMilk;
    }

    @Override
    public void water(String waterWWCMilk) {
        drinkName += waterWWCMilk;
    }

    @Override
    public void bottleCap(String capWWCMilk) {
        drinkName += capWWCMilk;
    }

    @Override
    public void label(String labelWWCMilk) {
        drinkName += labelWWCMilk;
    }

    @Override
    public String creatDrink() {
        return drinkName;
    }
}
  • 创建Director(控制建造过程,按指定顺序构建)
public class DrinkDirector {
    // 通过构造器注入
    private DrinkBuilder drinkBuilder;

    public DrinkDirector(DrinkBuilder drinkBuilder) {
        this.drinkBuilder = drinkBuilder;
    }

    // 控制饮料生产顺序
    public void creat(String s1, String s2, String s3, String s4) {
        drinkBuilder.bottleBody(s1);
        drinkBuilder.water(s2);
        drinkBuilder.bottleCap(s3);
        drinkBuilder.label(s4);
    }
}
  • 测试
public class Test1 {
    public static void main(String[] args) {
        BuilderCocaCola builderCocaCola = new BuilderCocaCola();
        DrinkDirector director = new DrinkDirector(builderCocaCola);
        director.creat("塑料瓶身-", "碳酸饮料-", "CocaCola盖-", "可口可乐(中国)");
        System.out.println("当前" + builderCocaCola.creatDrink());
        // 当前饮料名称为:塑料瓶身-碳酸饮料-CocaCola盖-可口可乐(中国)
    }
}
public class Test2 {
    public static void main(String[] args) {
        BuilderWWCMilk builderWWCMilk = new BuilderWWCMilk();
        DrinkDirector director1 = new DrinkDirector(builderWWCMilk);
        director1.creat("易拉罐瓶身-", "牛奶饮料-", "易拉罐盖-", "旺仔牛奶");
        System.out.println("当前" + builderWWCMilk.creatDrink());
        // 当前饮料名称为:易拉罐瓶身-牛奶饮料-易拉罐盖-旺仔牛奶
    }
}

总结一下:

  • 这里得到的结果就是我们需要的 Product(产品类)了;
  • 不同Builder实现类接受需要的参数,实现构建对应的产品;
  • Director类类似一个指挥所,控制产品内部组装的顺序。

四、举例2 —— 优化:链式调用

实际开发中,常用的是使用建造者模式实现链式调用,这里可以直接讲Builder、Director、Product等省略掉,直接使用ConcreteBuilder,下面对上述过程进行优化:

public class BuilderFanta {
    // 饮料名称
    private String drinkName = "饮料名称为:";

    public BuilderFanta bottleBody(String body) {
        drinkName += body;
        return this;
    }

    public BuilderFanta water(String water) {
        drinkName += water;
        return this;
    }

    public BuilderFanta bottleCap(String cap) {
        drinkName += cap;
        return this;
    }

    public BuilderFanta label(String label) {
        drinkName += label;
        return this;
    }

    public String creatDrink() {
        return drinkName;
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        BuilderFanta builderFanta = new BuilderFanta();
        String name = builderFanta.bottleBody("塑料瓶身-")
                .water("碳酸饮料-")
                .bottleCap("芬达蓝色盖")
                .label("芬达(苹果味)")
                .creatDrink();
        System.out.println("当前" + name);
    }
}

结果:

当前饮料名称为:塑料瓶身-碳酸饮料-芬达蓝色盖芬达(苹果味)

这就是建造者模式了,尤其是链式调用,简洁而美观~,在Mybatis框架中也被大量使用着建造者模式了,感兴趣的可以研究一下Mybatis源码。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值