策略模式
假如有一个商场经常搞些商品的促销活动,而且每次促销的方式都有所不同,或七折、八折、买一送一等等
/**
* 商品类
*/
@Data
public class Goods {
private String name;
private String clazz;
private Double price;
// ...
}
1.不使用策略模式
/**
* 第一种 采用简单工厂实现打折类
* 初步优化了代码的可读性和一定的扩展性,但增加打折类型后还需修改代码,违反了开闭原则
*/
public class Discount {
/**
* 打折的标准
*/
public enum DiscountStandard{
/**
* 七折
*/
SEVEN,
/**
* 九折
*/
NINE
}
/**
*
* @param goods 要打折的商品
* @param discountStandard 打折的标准
* @return 打折之后的价格
*/
public static double getPrice(Goods goods, DiscountStandard discountStandard){
switch (discountStandard){
case SEVEN:
return goods.getPrice() * 0.7;
case NINE:
return goods.getPrice() * 0.9;
default:
return goods.getPrice();
}
}
}
使用该类进行商品促销处理
@Test
public void test(){
Goods goods = new Goods();
goods.setName("百科全书");
goods.setPrice(99D);
double price = Discount.getPrice(goods, Discount.DiscountStandard.SEVEN);
System.out.println(price);
}
而下一次如果要打五折,就需要对原来的类进行修改,也就违反了开闭原则
public class Discount {
/**
* 打折的标准
*/
public enum DiscountStandard{
/**
* 五折
*/
FIVE,
/**
* 七折
*/
SEVEN,
/**
* 九折
*/
NINE
}
/**
*
* @param goods 要打折的商品
* @param discountStandard 打折的标准
* @return 打折之后的价格
*/
public static double getPrice(Goods goods, DiscountStandard discountStandard){
switch (discountStandard){
case FIVE:
return goods.getPrice() * 0.5;
case SEVEN:
return goods.getPrice() * 0.7;
case NINE:
return goods.getPrice() * 0.9;
default:
return goods.getPrice();
}
}
}
@Test
public void test1(){
Goods goods = new Goods();
goods.setName("百科全书");
goods.setPrice(99D);
double price = Discount.getPrice(goods, Discount.DiscountStandard.FIVE);
System.out.println(price);
}
2.使用策略模式
public interface IDiscountStrategy {
double getPrice(Goods goods);
}
public class SevenDiscountStrategy implements IDiscountStrategy{
@Override
public double getPrice(Goods goods) {
return goods.getPrice() * 0.7;
}
}
当下一次如果要打五折,就不需要对原来的类进行修改
public class FiveDiscountStrategy implements IDiscountStrategy{
@Override
public double getPrice(Goods goods) {
return goods.getPrice() * 0.5;
}
}
@Test
public void test(){
Goods goods = new Goods();
goods.setName("百科全书");
goods.setPrice(99D);
double price = new FiveDiscountStrategy().getPrice(goods);
System.out.println(price);
}
3.总结
并不是说碰到这种情况一定要使用策略模式,例如在一些需求固定不易变更的时候用第一种比较好(毕竟只需要一个类),但是在大多数情况下需求是变化无常的,虽然策略模式增加了应用程序的类规模,但是使应用的扩展能力得到较强的提升。