在上一篇《【设计模式】策略模式》中,我们讲解了策略模式的基本概念和用法。策略模式是符合“开闭原则”的典型案例,但在上一篇文章中,我们发现,如果想调用其他的策略,虽然不用修改核心业务代码,但需要修改客户端代码。我们说,将策略的选择放在功能页面,当用户选择时,向后端传入策略,从数据库字典表中获取该策略对应的类的名字,再通过反射,获得对应的策略类。但如果不修改数据库,还有没有别的方法?当然有!
使用spring注解!
我们将使用工厂+spring注解的方式实现!
1、工厂类
public class OrderIntegrateReadFactory {
private final static Logger logger= LoggerFactory.getLogger(OrderIntegrateReadFactory.class);
private Map<String,IVendeeContextStrategy> vendeeContextStrategyMap=new HashMap<String, IVendeeContextStrategy>();
public Map<String, IVendeeContextStrategy> getVendeeContextStrategyMap() {
return vendeeContextStrategyMap;
}
public void setVendeeContextStrategyMap(Map<String, IVendeeContextStrategy> vendeeContextStrategyMap) {
this.vendeeContextStrategyMap = vendeeContextStrategyMap;
}
public boolean doAction(String strType, ReportDetail reportDetail, OrderDetail orderDetail){
return this.vendeeContextStrategyMap.get(strType).getTicketContext(reportDetail,orderDetail);
}
}
2、spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!--四种策略-->
<bean id="orderIntegrateReadFactory" class="com.flight.inter.otaadapter.factory.OrderIntegrateReadFactory">
<property name="vendeeContextStrategyMap">
<map>
<entry key="1" value-ref="ctripContextStrategy"/>
<entry key="2" value-ref="qunarContextStrategy"/>
<entry key="3" value-ref="aliquaContextStrategy"/>
<entry key="4" value-ref="tongChengContextStrategy"/>
</map>
</property>
</bean>
<bean id="ctripContextStrategy" class="com.flight.inter.otaadapter.manage.cloudticket.CtripContextStrategy">
<property name="huitiePiaoHao" ref="ctripHuiTieTicketNumber"/>
<property name="redisManage" ref="policyRedis"/>
</bean>
<bean id="qunarContextStrategy" class="com.flight.inter.otaadapter.manage.cloudticket.QunarContextStrategy">
<property name="huitiePiaoHao" ref="qunarHuiTieTicketNumber"/>
<property name="redisManage" ref="policyRedis"/>
</bean>
<bean id="aliquaContextStrategy" class="com.flight.inter.otaadapter.manage.cloudticket.AliquaContextStrategy">
<property name="huitiePiaoHao" ref="quaHuiTieTicketNumber"/>
<property name="redisManage" ref="policyRedis"/>
</bean>
<bean id="tongChengContextStrategy" class="com.flight.inter.otaadapter.manage.cloudticket.TongChengContextStrategy">
<property name="huitiePiaoHao" ref="TongChengHuiTieTicketNumber"/>
<property name="redisManage" ref="policyRedis"/>
</bean>
</beans>
3、接口类
public interface IVendeeContextStrategy {
boolean getTicketContext(ReportDetail reportDetail, OrderDetail orderDetail);
}
4、具体实现类,以QunarContextStrategy策略为例
public class QunarContextStrategy implements IVendeeContextStrategy{
private final static Logger logger= LoggerFactory.getLogger(QunarContextStrategy.class);
HandleManage<TicketContext> huitiePiaoHao;
RedisManager redisManage;
public RedisManager getRedisManage() {
return redisManage;
}
public void setRedisManage(RedisManager redisManage) {
this.redisManage = redisManage;
}
public HandleManage<TicketContext> getHuitiePiaoHao() {
return huitiePiaoHao;
}
public void setHuitiePiaoHao(HandleManage<TicketContext> huitiePiaoHao) {
this.huitiePiaoHao = huitiePiaoHao;
}
@Override
public boolean getTicketContext(ReportDetail reportDetail, OrderDetail orderDetail){
try {
TicketContext ticketContextQunar = QunarTicketContext(reportDetail, orderDetail);
if (ticketContextQunar != null) {
TicketContext ticketContext=huitiePiaoHao.handle(ticketContextQunar);
if (ticketContext.isHuitieresult()){
redisManage.add("vendee-"+ticketContext.getTtsorderno(),"true");
redisManage.expire("vendee-"+ticketContext.getTtsorderno(),600);
logger.info("orderintegrate huitie success data {}",JSONObject.toJSONString(ticketContext));
return true;
}
}
}catch (Exception e){
logger.error("orerintegrate read ticketcontext error {}",e);
return false;
}
return false;
}
}
5、模拟客户端调用
public class StrategyPatternDemo{
public static void main(String[] args){
OrderIntegrateReadFactory orderIntegrateReadFactory = new OrderIntegrateReadFactory ();
String type = "1";
ReportDetail reportDetail = new ReportDetail();
OrderDetail orderDetail = new OrderDetail();
reportDetail.setXXX();
orderDetail.setXXX();
... ...
Boolean boolean = orderIntegrateReadFactory.doAction(strType, reportDetail,orderDetail);
}
}
当需求中有新的类时,我们可以在只添加策略类,修改spring的配置文件来实现啦!
代码借鉴:
https://blog.csdn.net/zlts000/article/details/54754789