共计 3854 个字符,预计需要花费 10 分钟才能阅读完成。
紧接着上节讲到抽象工厂模式,接下来讲建造者模式。
水果店随着业务发展,想要举行各类促销活动来提升人气。
- 会员购买橘子 + 苹果 + 香蕉(可能还有别的水果)立减 15 元
- 假日促销则橘子 + 苹果 + 香蕉(可能还有别的水果)立减 10 元
问题:
- 1. 套餐组合包含各类水果的组合, 较复杂(后续套餐越来越复杂)。
- 2. 套餐的创建步骤基本确定, 设置商品价格 / 设置折扣 / 得到结算价。
- 3. 会不断的推出新的套餐。
针对需求,我们需要考虑扩展性,针对上面三个问题,我们考虑用建造者模式来设计。
1. 创建步骤
针对这几个步骤我们抽象出一个建造接口即 builder 接口用来创建套餐。
套餐是一个对象我们定义一个类封装好属性,主要是各个水果的价格,折扣价,还有套餐总价:
结构图:
代码如下:
// 创建一个水果套餐 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);
}
}
builder 接口:
// 创建一个 Builder 类,实际的 builder 类负责创建套餐 FruitMeal 对象。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;
}
}
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();}
}
public class Apple implements Fruit {
private int price = 100;
public Apple(){}
public Apple(int price){this.price = price;}
public void pack(AppleBag bag){bag.pack();
}
@Override
public int price() {return price;}
@Override
public void draw() {System.out.print("苹果红富士");
}
public void setPrice(int price) {this.price = price;}
}
public class Banana implements Fruit {
private int price = 60;
@Override
public int price() {return price;}
public void pack(BananaBag bag){bag.pack();
}
@Override
public void draw() {System.out.print("仙人蕉");
}
public void setPrice(int price) {this.price = price;}
}
public class Orange implements Fruit {
private String name = "";
private int price = 70;
public Orange(String name,int price){
this.price = price;
this.name = name;
}
public void pack(OrangeBag bag){bag.pack();
}
@Override
public int price() {return price;}
@Override
public void draw() {System.out.print("砂糖桔");
}
public void setPrice(int price) {this.price = price;}
}
/**
* 水果接口
*/
public interface Fruit {int price();
void draw();}
使用 建造者模式 ,使用 建造工厂 (节假日套餐工厂丶会员套餐工厂) 生产出套餐,每多一个套餐,新增一个建造工厂,这实际上是用了工厂方法模式
只是建造工厂有一定相同的步骤。
建造者模式类图
主要有:
- 1 是 Builder 接口,抽象出生产某个复杂的对象的步骤
- 2 复杂对象用一个类
- 3Builder 实现类
在业务需求开发中,适当的使用设计模式将大大提高系统的可扩展性可读性,业务场景需要多考虑清晰。
正文完