博主将会针对Java面试题写一组文章,包括J2ee,SQL,主流Web框架,中间件等面试过程中面试官经常问的问题,欢迎大家关注。一起学习,一起成长。
![0cc85af7dc06ae907742877b2fad5949.png](https://i-blog.csdnimg.cn/blog_migrate/ba1a06c8fa810c3580f32b64c79f2806.jpeg)
需求
根据日期来返回不同的价格,日期是不固定的,随时可能要增加,优惠力度也不是固定的。
传统if-else写法
if("normalDate".equals(new Date())){ return price;}else if("圣诞节".equals(new Date())){//打八折 return price * 0.8;}
缺点:如果有新增类型,就需要频繁的修改此处的代码,不符合开闭原则!
三、使用策略模式
3.1、定义策略接口
/**策略定义接口 */public interface CashSuper { BigDecimal accepCash(BigDecimal money);}
3.2、定义上下文
/** * implements * 根据不同日期打折,返利等活动 */public class Context { CashSuper cashSuper ; public void initCash(CashSuper cashSuper){ this.cashSuper = cashSuper; } public BigDecimal getResult(BigDecimal money){ return cashSuper.accepCash(money); }}
3.3、不同的日期不同折扣
/** * 不打折 */public class CashNormal implements CashSuper{ @Override public BigDecimal accepCash(BigDecimal money) { return money; }}
/** * 打八折 */public class CashDiscount implements CashSuper { @Override public BigDecimal accepCash(BigDecimal money) { return money.multiply(BigDecimal.valueOf(0.8)); }}
3.3、调用示例
public class StrategyMain { public static void main(String[] args) { //上下文,根据不容入参获取不同折扣 Context context = new Context(); context.initCash(new CashNormal()); System.out.println(context.getResult(BigDecimal.valueOf(10))); context.initCash(new CashDiscount()); System.out.println(context.getResult(BigDecimal.valueOf(10))); }}
3.4、结果示例
![9cfe742cf506e1b17b6e1a3ed62bd242.png](https://i-blog.csdnimg.cn/blog_migrate/d9333d1b8104bad31c0d0947ea50d96f.jpeg)
总结
使用场景:
1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
2、一个系统需要动态地在几种算法中选择一种。
3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
![5e2dfe7695b078d727c185fb4f5b3607.png](https://i-blog.csdnimg.cn/blog_migrate/a296e3e19c56b8141377c05fc8769a3d.jpeg)