创建型设计模式之--建造者模式

建造者模式也被称为生成器模式,它是创建一个复杂对象的创建型模式,其将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的表示分离开来。

我们接着用工厂模式中的果园举例,我们的水果店为了吸引老顾客、以及新顾客办理会员,推出了各式各样的促销活动,例如会员购买苹果、香蕉、桔子可以减15元;假日促销活动可以立减10元的活动;如图,目前我们推出了两种活动套餐

上面一条流程可以抽象为如下步骤:首先设定苹果礼盒价钱-->设置香蕉礼盒价钱-->设置桔子礼盒价钱-->设置折扣价钱,最终我们拿到了水果套餐的结算价。抽象步骤如下:

建造者模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

在建造者模式中有如下角色。
• Director:导演类,负责安排已有模块的顺序,然后通知Builder开始建造。
• Builder:抽象Builder类,规范产品的组建,一般由子类实现。
• ConcreteBulider:具体建造者,实现抽象 Builder 类定义的所有方法,并且返回一个组建好的对象。
• Product:产品类。

对应的类图:

  • 概念中的导演类,就是我们建造出来的对象的使用者,例如本例中收银台就是一步一步给各个水果定价的收银员,也就是建造者模式建造出来的对象的使用者;
  • builder接口,就是我们四个固定的定价步骤;
  • HolidayBuilder、OldCustomBuilder就是上面builder的具体实现类;
  • FruitMeal就是我们建造者模式最终建造出来的复杂的对象。

对应的实现代码:

建造者需要的复杂建造步骤,最终需要返回这个复杂的套餐对象:

//创建一个MealBuilder类,实际的builder类负责创建套餐Meal对象。
public interface Builder {//也是工厂

    void buildApple(int price);//设置苹果
    void buildBanana(int price);//设置香蕉
    void buildOrange(int price);//设置桔子

    FruitMeal getFruitMeal();//返回创建的套餐
}

两种对应的建造师,就是这个复杂步骤的实现对象:

假期水果套餐建造者:

/**
 * 假期水果套餐
 */
public class HolidayBuilder implements Builder {
    private FruitMeal fruitMeal = new FruitMeal();

    @Override
    public void buildApple(int price) {
        Apple apple = new Apple();
        apple.setPrice(price);
        fruitMeal.setApple(apple);
    }

    @Override
    public void buildBanana(int price) {
        Banana fruit = new Banana();
        fruit.setPrice(price);
        fruitMeal.setBanana(fruit);
    }

    @Override
    public void buildOrange(int price) {
        Orange fruit = new Orange("Peter",80);
        fruit.setPrice(price);
        fruitMeal.setOrange(fruit);
    }

    @Override
    public FruitMeal getFruitMeal() {
        fruitMeal.setDiscount(15);//折扣价格对一个套餐来,是固定的
        fruitMeal.init();
        return fruitMeal;
    }
}

老会员水果套餐建造者:

/**
 * 老会员水果套餐
 */
public class OldCustomerBuilder implements Builder {
    private FruitMeal fruitMeal = new FruitMeal();

    @Override
    public void buildApple(int price) {
        Apple apple = new Apple();
        apple.setPrice(price);
        fruitMeal.setApple(apple);
    }

    @Override
    public void buildBanana(int price) {
        Banana fruit = new Banana();
        fruit.setPrice(price);
        fruitMeal.setBanana(fruit);
    }

    @Override
    public void buildOrange(int price) {
        Orange fruit = new Orange("Peter",80);
        fruit.setPrice(price);
        fruitMeal.setOrange(fruit);
    }

    @Override
    public FruitMeal getFruitMeal() {
        fruitMeal.setDiscount(10);
        fruitMeal.init();
        return fruitMeal;
    }
}

最终需要建造的水果套餐类:

//创建一个水果套餐Meal类
public class FruitMeal {

    private Apple apple;//苹果--价格
    private Banana banana;//香蕉价格
    private Orange orange;    //桔子价格
    private int discount;//折扣价

    private int totalPrice;//套餐总价

    public void setDiscount(int discount) {
        this.discount = discount;
    }

    public void setApple(Apple apple) {
        this.apple = apple;
    }

    public void setBanana(Banana banana) {
        this.banana = banana;
    }

    public void setOrange(Orange orange) {
        this.orange = orange;
    }

    public int cost(){
        return this.totalPrice;
    }

    public void init() {
        if (null != apple){
            totalPrice += apple.price();
        }
        if (null != orange){
            totalPrice += orange.price();
        }
        if (null != banana){
            totalPrice += banana.price();
        }
        if (totalPrice > 0){
            totalPrice -= discount;
        }
    }

    public void showItems() {
        System.out.println("totalPrice:" + totalPrice);
    }
}

导演,建造类的使用者:

public class FruitMealController {//收银台---导演类

    public void construct() {
//        Builder builder = new HolidayBuilder();
        Builder builder = new OldCustomerBuilder();//spring注入方法,

        //以下代码模板,轻易是不变的
        builder.buildApple(120);//创建苹果设置价格
        builder.buildBanana(80);//创建香蕉设置香蕉价格
        builder.buildOrange(50);//创建桔子设置价格

        FruitMeal fruitMeal = builder.getFruitMeal();


        int cost = fruitMeal.cost();
        System.out.println("本套件花费:"+cost);
    }

    public static void main(String[] args) {
        new FruitMealController().construct();
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章