策略模式-面向接口编程
什么是策略模式?
比如说对象的某个行为,在不同场景中有不同的实现方式,这样就可以将这些事件方式定义为一组策略,每一个实现类对应一个策略,在不同的场景就使用不同的实现类,并且可以自由切换策略。
策略模式结构图:
策略模式需要一个策略接口,不同的策略实现不同的实现类,在具体业务环境中仅持有该策略接口,根据不同的场景使用不同的实现类即可。
面向接口编程,不是面向实现。
策略模式的优点:
1.干掉繁琐的if,switch判断逻辑;(具体情况具体分析)
2. 代码优雅,可复用,可读性好;
3. 符合开闭原则,扩展性号,便于维护;
策略模式的缺点:
1.策略如果很多的话,会造成策略类膨胀;
2. 使用者必须清楚所有的策略类及其用途;
策略模式实战
举例:xx公司是做支付的,根据不同的客户类型会有不同的支付方式和支付产品。比如:信用卡、本地支付,而本地支付在中国又有微信支付,支付宝支付,云闪付等更多的第三方支付公司,这时候策略模式就派上用场了。
- 定义一个策略接口,所有支付方式的接口
- 定义各种支付策略,微信支付,支付宝等实现类都实现这个接口
- 使用的时候根据传不同的支付方式执行不同的策略实现类。
真实业务使用
自定义流程里有一个步骤是新增记录,给当前表单配置新增记录到另一个表单中,实际上就是将当前表单的一条事件信息同步到另一个配置的表单中去。类比支付的例子,就是一个表单有很多种表单选择新增记录,选择不同的表单,要执行不同的方法。具体业务是变更审批表单(Change)要新增到变更通知(ChangeTotal)里面去,所以此时:
定义一个策略接口
/**
* 新增记录通用接口
*/
public interface InsertRecordCallBack {
void callBack(Change callData);
}
创建一个通用实体类
@Component("insertRecordCallBack")
public class InsertRecordCallBackImpl implements InsertRecordCallBack{
/*
* Change callData (Change此时是一个实体类,也可以传JSONObject)
* callData.getCallBackBeanName(),指的是每一个策略实现类的@Component("changeTotalCallBack")
*/
@Override
public void callBack(Change callData) {
String beanName = callData.getCallBackBeanName().trim();
InsertRecordCallBack bean = SpringUtil.getBean(beanName, InsertRecordCallBack.class);
if (bean == null) {
//记录至对应的error中,暂不进行其他处理
}else{
bean.callBack(callData);
}
}
}
定义策略实现类(可根据业务定义很多策略实现类)
@Component("changeTotalCallBack")
public class ChangeTotalCallBack implements InsertRecordCallBack {
@Autowired
private TotalMapper totalMapper;
@Override
public void callBack(Change callData) {
//实际业务就是将变更审批的字段赋予变更通知的某些字段
Total total= new Total();
total.setChangeType(callData.getChangeType());
total.setReason(callData.getReason());
totalMapper.autoInsertTotal(total);
}
}
真实使用
String functionName = stepList.get(i).get("functionName").toString();
//数据库里存每一个表单配置的@Component("changeTotalCallBack")值,
//此时是 changeTotalCallBack,传了这个bean名称,程序就知道要找哪一个策略实现类了
change.setCallBackBeanName(functionName);
//调用通用的策略实现类
insertRecordCallBack.callBack(change);
文章文字部分参考公众号 Java技术栈-别在再满屏的 if/ else 了,试试策略模式,真香!!