文章内容输出来源:拉勾教育Java高薪训练营
策略模式
策略模式Strategy,指一个问题有多种解决方案,选择其中的一种使用,并能灵活的扩展解决方案而不影响原有的代码。
如商品打折有多种方案:打1折,不打折,打5折,满200减50等。
问题分析
像上面说到的商品打折方案,商家要根据不同的商品选择不同的打折方案,从而计算出客户购买的商品的优惠后价格,生成订单。
比较粗暴点的做法就是在一个计算价格的方法中根据商品选择的打折方案,使用一堆的if/else对应的算价格。
double calculate(type, originalPrice) {
//打1折
if(type == 1) {
return originalPrice * 0.1;
}
//打5折
if(type == 5) {
return originalPrice * 0.5;
}
//不打折
if(type == 0) {
return originalPrice * 1;
}
}
- 商家可能随时会增加/减少打折方案,那么每次增加或者减少就要去改这个计算价格的方法,就不符合开闭原则。
- 当打折方案比较多时,那计算价格的方法就会比较的复杂,越来越难以维护
因此,使用策略模式的话就是将每种方案都有自己的计算价格的方法,商品选择了哪一个方案就直接使用那个方案的计算价格方法去算就好了。
示例Demo
1. 定义能用的折扣方案基类
- 抽象类
- 定义了折扣描述属性
- 定义了计算价格的抽象方法
public abstract class AbstractDiscount {
/**
* 优惠描述
*/
protected String desc;
public AbstractDiscount(String desc) {
this.desc = desc;
}
/**
* 计算优惠后价格
* @param price
* @return
*/
public abstract double calculateFinalPrice(double price);
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
2. 定义多种价格方案
继承上述的基类AbstractDiscount
- 1折优惠方案
public class Discount01 extends AbstractDiscount {
public Discount01() {
super("商品1折优惠");
}
/**
* 计算优惠后价格
*
* @param price
* @return
*/
@Override
public double calculateFinalPrice(double price) {
return price * 0.1;
}
}
- 5折优惠方案
public class Discount05 extends AbstractDiscount {
public Discount05() {
super("商品5折优惠");
}
/**
* 计算优惠后价格
*
* @param price
* @return
*/
@Override
public double calculateFinalPrice(double price) {
return price * 0.5;
}
}
- 无优惠方案
public class NoDiscount extends AbstractDiscount {
public NoDiscount() {
super("商品没有优惠");
}
/**
* 计算优惠后价格
*
* @param price
* @return
*/
@Override
public double calculateFinalPrice(double price) {
return price * 1;
}
}
3. 定义商品
- 商品有名称、原价的属性
- 同时也增加了商品选择使用的优惠方案的属性
- 增加计算商品价格的方法,其能调用使用的优惠方案的计算价格方法
public class Goods {
/**
* 商品名称
*/
private String name;
/**
* 商品价格
*/
private double price;
/**
* 商品的折扣方案
*/
private AbstractDiscount discount;
public Goods(String name, double price, AbstractDiscount discount) {
this.name = name;
this.price = price;
this.discount = discount;
}
/**
* 计算商品最终价格
* @return
*/
public double calculate() {
double finalPrice = discount.calculateFinalPrice(price);
String discountDesc = discount.getDesc();
System.out.println("商品原价是" + price + ",优惠方案是:"+ discountDesc +"。优惠后价格是:" + finalPrice);
return finalPrice;
}
//ignore setter/getter
}
4. 多种商品使用多种优惠的测试
public class StrategyMain {
public static void main(String[] args) {
Goods book = new Goods("Java从入门到放弃", 99D, new Discount01());
book.calculate();
Goods phone = new Goods("小米手机", 3000D, new Discount05());
phone.calculate();
Goods mac = new Goods("苹果电脑", 13000D, new NoDiscount());
mac.calculate();
}
}