策略模式
策略模式的定义是:定义了一系列的算法,把它们一个个的封装起来,并且使它们可相互替换,让算法可以独立于使用它的客户而变化。
设计原则是:把一个类中经常改变或者将来可能会经常改变的部分提取出来作为一个接口,然后在使用类中包含这个接口的实例,这样使用类的对象就可以随意调用实现了这个接口的类行为。
在策略模式中有如下几个角色:
环境角色(Context): 此角色中实现了对策略角色的引用和使用。
抽象策略角色:此角色通常由抽象类或接口来实现,定义了,所以具体策略角色的行为。
具体策略角色:此角色封装了实现不同功能的不同算法。
演示代码如下:
抽象策略类
public interface Strategy { /** * 策略方法 */ void strategyMethod(); }
具体角色类A
class ConcreteStrategyA implements Strategy{ @Override strategyMethod() { //具体的行为 } }
具体角色类B
class ConcreteStrategyB Strategy { @Override } }
环境角色类
class Context { * 持有一个具体的策略对象 private Strategy strategy; * 构造方法,传入一个具体的策略对象 * @param strategy 具体的策略对象 public Context(Strategy strategy) { this.strategy = strategy; } * 对外提供的使用策略的方法 contextMethod() { 通常会转调具体的策略对象进行算法运算 strategy.strategyMethod(); } }
策略模式具体场景例子
某Saas公司的企业服务系统,在销售时,会根据客户的购买时长来确定优惠策略,分为普通客户(无优惠政策),大客户(98折),战略客户(95折)。普通客户是指一次性租用服务在一到3年之间的,大客户指一次性使用服务3到5年之间的,战略客户指一次性使用服务5年以上的。因为每种客户价格算法不同,所以这个场景就可以使用策略模式。
定义一个计算价格行为的接口
SalePrice { * 根据原价返回不同的价格 * originalPrice 原始价格 * @return */ BigDecimal salePrice(BigDecimal originalPrice); }
然后定义三中客户的具体计算价格类(策略类)
class OriginalCustomer * 普通客户直接返回原价 * @return 计算后的价格 @Override BigDecimal salePrice(BigDecimal originalPrice) { return originalPrice.multiply(BigDecimal.valueOf(1)); } }
class LargeCustomer * 大客户返回98折价格 * return originalPrice.multiply(BigDecimal.valueOf(0.98)); } }
class StrategicCustomer * 战略客户直接返回95折价格 * BigDecimal salePrice(BigDecimal originalPrice) { return originalPrice.multiply(BigDecimal.valueOf(0.95)); } }
客户类,需要判断具体的调用哪个计算价格的方法
Customer { private int years; 租用服务一年的初始价格 private BigDecimal originalPrice = BigDecimal.valueOf(50000); 客户最终支付的价格 *private BigDecimal payForPrice = BigDecimal.ZERO; 每个客户的初始价格都是原价 private SalePrice salePrice = new OriginalCustomer(); * 根据客户购买的时长来计算每一年的优惠价格(单位:年) * years void buy( years) { this.years = years; payForPrice = originalPrice.multiply(BigDecimal.valueOf(years)); 大于5年的战略客户价格 if(years >= 5){ salePrice = StrategicCustomer(); }else if(years >= 3)3年到5年的大客户优惠价格 { salePrice = LargeCustomer(); }if(years >= 1)1到3年的普通用户原价 OriginalCustomer(); } } * 计算客户最终支付的价格 * BigDecimal payPrice(){ return salePrice.salePrice(payForPrice); } }
客户端调用类,自动计算支付价格
** * 客户端调用类 */ @Slf4j Client { static main(String[] args){ Customer customer = Customer(); customer.buy(1); log.info("客户需支付:{}",customer.payPrice()); customer.buy(3
输出结果:
客户需支付:50000 客户需支付:147000.00 客户需支付:285000.00
根据输出结果可以看出购买不同时间的服务,收费价格是不同的。这样客户可以不用依赖具体的收费方法,直接根据需要的服务的时间购买即可。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。