设计模式——策略模式
2019-07-18 本文已影响0人
prik丶
《Head First 设计模式》 学习笔记
码云同步更新中
如有错误或不足之处,请一定指出,谢谢~
目录
查看其它设计模式笔记,点这里→设计模式笔记汇总
策略模式
- 定义:
- 策略模式——定义算法族,分别封装起来,让他们可以互相替换,此模式让算法的变化独立与使用算法的客户
- 适用范围:
- 几个类的主要逻辑相同,只在部分逻辑的算法和行为上稍有区别的情况
- 有几种相似的行为(算法),客户端需要动态决定使用哪一种
- 优点:
- 动态改变对象的行为
- 扩展性良好
- 缺点:
- 客户端必须知道所有的策略类,并自行决定使用哪一个
- 会产生很多策略类
- 只适合扁平的结构,策略之间层级平等,不能互相嵌套
- 设计原则:
- 找出应用中可能需要变化的地方,把它们独立出来,不要和那些不需要变化的代码混在一起
- 针对接口编程,而不是针对实现编程
- 多用组合,少用继承
- 结构
- 抽象策略:抽象类或接口,约束具体策略的行为
- 具体策略:抽象策略的实现
- 上下文类:负责具体交互,相当于一个容器,持有具体策略实现的引用
- 执行顺序:
- 创建具体策略实现
- 创建上下文类,并注入策略
- 通过上下文类处理数据
- 案例
- 电子商城,客户下单时需要根据不同的客户类型计算折扣后价格
- 普通客户:无优惠
- vip客户:9折
- 其他自定义策略...
- 还用到了工厂模式,工厂类用到了单例模式,达到消除if/else语句的目的
- 电子商城,客户下单时需要根据不同的客户类型计算折扣后价格
- 代码
/**
* 策略接口
*
* @author Xushiwei
* @date 2019/7/18
*/
public interface DiscountStrategy {
/**
* 计算折扣后价格
*
* @param originalPrice 原价
* @return 折扣后应付价格
*/
BigDecimal calDiscountPrice(BigDecimal originalPrice);
}
/**
* 普通客户策略实现
*
* @author Xushiwei
* @date 2019/7/18
*/
public class OrdinaryDiscountStrategy implements DiscountStrategy {
@Override
public BigDecimal calDiscountPrice(BigDecimal originalPrice) {
System.out.println("普通客户,无优惠");
return originalPrice;
}
}
/**
* vip客户策略实现,九折
*
* @author Xushiwei
* @date 2019/7/18
*/
public class VipDiscountStrategy implements DiscountStrategy {
@Override
public BigDecimal calDiscountPrice(BigDecimal originalPrice) {
System.out.println("VIP客户,九折优惠~");
return originalPrice.multiply(new BigDecimal("0.9"));
}
}
/**
* 顾客
* 注:@Data为lombok注解
*
* @author Xushiwei
* @date 2019/7/18
*/
@Data
public class Customer {
/**
* 姓名
*/
private String name;
/**
* 客户类型
*/
private Integer type;
/**
* 普通客户
*/
public static final int TYPE_ORDINARY = 1;
/**
* vip客户
*/
public static final int TYPE_VIP = 2;
/**
* 合作伙伴
*/
public static final int TYPE_PARTNER = 3;
}
/**
* 策略工厂
* 单例
*
* @author Xushiwei
* @date 2019/7/18
*/
public class DiscountStrategyFactory {
/**
* private修饰的构造函数,防止使用者手动创建
*/
private DiscountStrategyFactory() {
}
private static DiscountStrategyFactory factory = new DiscountStrategyFactory();
private static Map<Integer, DiscountStrategy> strategyMap = new HashMap();
static{
strategyMap.put(Customer.TYPE_ORDINARY, new OrdinaryDiscountStrategy());
strategyMap.put(Customer.TYPE_VIP, new VipDiscountStrategy());
strategyMap.put(Customer.TYPE_PARTNER, new PartnerDiscountStrategy());
}
public DiscountStrategy creator(int customerType) {
return strategyMap.get(customerType);
}
public static DiscountStrategyFactory getInstance() {
return factory;
}
}
/**
* 上下文类
*
* @author Xushiwei
* @date 2019/7/18
*/
public class DiscountContext {
private static DiscountStrategyFactory strategyFactory = DiscountStrategyFactory.getInstance();
public BigDecimal calDiscountPrice(BigDecimal originalPrice, int customerType) {
DiscountStrategy strategy = strategyFactory.creator(customerType);
return strategy.calDiscountPrice(originalPrice);
}
}
/**
* 测试类
*
* @author Xushiwei
* @date 2019/7/18
*/
public class Test {
public static void main(String[] args) {
BigDecimal originalPrice = new BigDecimal(100);
// 普通客户
DiscountContext discountContext = new DiscountContext();
BigDecimal price1 = discountContext.calDiscountPrice(originalPrice, 1);
System.out.println("普通客户下单,原价:" + originalPrice + "元,应付款:" + price1 + "元");
// vip客户
BigDecimal price2 = discountContext.calDiscountPrice(originalPrice, 2);
System.out.println("vip客户下单,原价:" + originalPrice + "元,应付款:" + price2 + "元");
}
}
执行结果:
普通客户,无优惠
普通客户下单,原价:100元,应付款:100元
VIP客户,九折优惠~
vip客户下单,原价:100元,应付款:90.0元
- 参考资料: