设计源于生活,策略模式在生活中很常见。凡是我们听到这种:如果...就,要是...就,做选择的地方,多数都能提出一个策略模式的实现。比如下面列举的。
我们每天出门上班,如果下雨我就开汽车,如果天气好我就骑电动车。
策略模式在设计模式中属于行为型模式,策略模式表现为一个类的行为实现,可以在运行时根据条件自主选择。本质上也是一种面向接口编程,通用的策略是一个抽象的接口,具体的策略根据实际情况自主选择。
通常来说,策略模式在Java里的实现,有三个要素,Context,AbstractStrategy,List,Context代表一个上下文,AbstractStrategy是一个抽象策略,具体的实现在这个List里面,List也代表可以扩展。
看一个实际项目例子
该项目是一个知识付费项目,用户可在线下单支付,商品包括会员商品(年月季会员),虚拟资产(资源包)等。此处在支付核销的环节,使用策略模式,处理不同商品的核销逻辑。
分析下此处项目内设计的商品数据。笔者设计中,年会员、季度会员、月会员分别是一条商品记录、虚拟资产是一条商品记录。其中会员商品是一类商品、虚拟资产又是一类商品。会员商品和虚拟正产的核销逻辑不一样,会员需要给对应用户增加天数。对于年会员、季度会员、阅读会员,它们的区别其实在于会员的权益,对应到系统内部,就是3种会员的一个会员天数不一样。所以这里引入商品的两个逻辑处理字段,处理类型(会员、资源)、处理参数(天数、资源ID等)。
不使用策略模式,我们可能会这么写
@Component
public class PayProssor {
public void process(byte type , Object params , long uid){
if(type == VIP){
this.addUser(uid,params);
return;
}
if(type == RESOURCE_PAC){
this.addUserResource(uid,params);
return;
}
}
}如果增加商品业务,比如此处增加虚拟豆购买,势必在PayProssor增加一个if,久而久之这里的if就会分支比较多。策略模式怎么实现呢?
首先定义一个抽象实现 PayHandler 以及两个具体实现
public interface PayHandler {
boolean check(byte type);
void process(Object params , long uid);
}
@Service
public class VipHandler implements PayHandler {
@Override
public boolean check(byte type) {
return VIP == type;
}
@Override
public void process(Object params , long uid) {
UserProcessor.addUserVip(uid, params);
}
}
@Service
public class ResourcePacHandler implements PayHandler {
@Override
public boolean check(byte type) {
return RESOURCE == type;
}
@Override
public void process(Object params , long uid) {
UserResProcessor.process(uid, params);
}
}定义Context
@Component
public class PayContext {
public void process(byte type , Object params , long uid){
this.getHandler(type).process(params, uid);
}
private PayHandler getHandler(byte type) {
Optional any = payResultHandlers.stream().filter(x -> x.check(type)).findAny();
if (any.isPresent()) {
return any.get();
}
throw new ServiceException("不支持的处理类型");
}
} Context负责串接上下文,自动匹配合适的策略,执行策略的方法。当有新的商品加入系统,只需要考虑增加新的策略实现,对商品数据进行对应的配置,就能实现新商品核销的扩展,用较小改动实现新需求。
| 留言与评论(共有 0 条评论) “” |