策略模式是一种行为模式。用于某一个具体的项目有多个可供选择的算法策略,客户端在其运行时根据不同需求决定使用某一具体算法策略。
将算法和对象分开,使算法独立于使用它的用户。将一个类(环境)中经常改变或将来可能改变的部分提取出来,作为一个接口(抽象策略),然后在类中包含这个对象的实例,这样类的实例在运行时就可以调用实现了这个接口类的行为。即准备一组算法。并将每个算法封装起来,使之可互换,策略算法是相同行为的不同实现。
策略模式并不决定在何时使用何种算法。
策略模式分为三部分:
1. 抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
package com.csii.pp.online.potpay;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.csii.pe.core.Context;
import com.csii.pe.core.PeException;
import com.csii.pe.service.comm.Transport;
import com.csii.pe.validation.RemoteRejectException;
import com.csii.pp.core.Constants;
import com.csii.pp.core.Dict;
import com.csii.pp.core.ErrorConstants;
import com.csii.pp.merchant.Merchant;
import com.csii.pp.order.Order;
import com.csii.pp.util.MiscUtil;
/**
* 圆鼎支付一类户支付策略类
*/
public class PotPayCoreStrategy implements PotPayStrategy {
protected Log log = LogFactory.getLog(getClass());
private Transport dubboTransport;
@Override
public void potPay(Context context , Order order) throws PeException {
//具体逻辑就省掉了
}
public void setDubboTransport(Transport dubboTransport) {
this.dubboTransport = dubboTransport;
}
}
package com.csii.pp.online.potpay;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.csii.pe.core.Context;
import com.csii.pe.core.PeException;
import com.csii.pe.service.comm.Transport;
import com.csii.pe.validation.RemoteRejectException;
import com.csii.pp.core.Constants;
import com.csii.pp.core.Dict;
import com.csii.pp.core.ErrorConstants;
import com.csii.pp.merchant.Merchant;
import com.csii.pp.order.Order;
import com.csii.pp.util.MiscUtil;
/**
* 圆鼎支付二类户支付策略类
*/
public class PotPayNetCoreStrategy implements PotPayStrategy {
protected Log log = LogFactory.getLog(getClass());
private Transport dubboTransport;
private String corePayAcNo;
@Override
public void potPay(Context context, Order order) throws PeException {
//。。。。。。。。。。。。。。。。。。。。
}
public void setDubboTransport(Transport dubboTransport) {
this.dubboTransport = dubboTransport;
}
public void setCorePayAcNo(String corePayAcNo) {
this.corePayAcNo = corePayAcNo;
}
}
3. 环境角色:持有某一个策略类的引用,客户端调用。
package com.csii.pp.online.action.pay;
import com.csii.pe.core.Context;
import com.csii.pe.core.PeException;
import com.csii.pp.online.action.AbstractTwoPhaseAction;
import com.csii.pp.online.potpay.PotPayStrategy;
import com.csii.pp.order.Order;
/**
* @author X
*/
public class PotPayAction extends AbstractTwoPhaseAction {
private PotPayStrategy potpaystrategy;
public PotPayAction() {
super();
}
public PotPayAction(PotPayStrategy potpaystrategy) {
this.potpaystrategy = potpaystrategy;
}
public void prepare(Context context) throws PeException {
//TODO-save merchant send data-plain and signature
}
public void submit(Context context) throws PeException {
Order order = this.getOrder(context);
potpaystrategy.potPay(context, order);
}
}
在模版里调用,选择相应策略,由于策略实现中涉及其他的通讯,将组装好的策略实现类注入模版中。
package com.csii.pp.online.template;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.csii.pe.action.Action;
import com.csii.pe.action.Executable;
import com.csii.pe.action.PlaceholderAction;
import com.csii.pe.action.Preparable;
import com.csii.pe.action.Submitable;
import com.csii.pe.core.Context;
import com.csii.pe.core.PeException;
import com.csii.pe.service.comm.CommunicationException;
import com.csii.pe.template.AbstractTemplate;
import com.csii.pe.validation.RemoteRejectException;
import com.csii.pp.core.Constants;
import com.csii.pp.core.Dict;
import com.csii.pp.core.ErrorConstants;
import com.csii.pp.online.action.pay.PotPayAction;
import com.csii.pp.online.potpay.PotPayStrategy;
import com.csii.pp.order.Order;
import com.csii.pp.transport.HostResponseException;
import com.csii.pp.util.MiscUtil;
/**
*
* 支付类交易模版
*
* @author X
*
*/
public class PotTwoPhaseTrsTemplate extends AbstractTemplate implements ApplicationContextAware {
private ApplicationContext appCtx;
private List timeoutMessages;
private Map potPayStrategyMap;
public PotTwoPhaseTrsTemplate() {
super();
}
public void execute(Context context) throws PeException {
//记录交易流水的action
Action preJnlAction = getAction("preJnlAction", context);
//修改交易流水的action
Action aftJnlAction = getAction("aftJnlAction", context);
//记录交易日志的action
Action preAction = getAction("preAction", context);
//修改交易日志的action
Action aftAction = getAction("aftAction", context);
//交易前期检查的action
Action checkAction = getAction("preCheckAction", context);
//交易前期检查的action
Action aftCheckAction = getAction("aftCheckAction", context);
//具体交易处理的action
Action action = this.getPotAction("action", context);
//超时交易记录的action
Action timeoutAction = this.getAction("timeoutAction", context);
//校验商户号是否合法的action
Action preCheckMchAction = getAction("preCheckMchAction", context);
//..................................................
((Submitable) action).submit(context);
//..................................................
protected Action getPotAction(String id, Context context) {
Map actions = context.getTransactionConfig().getActions();
if (actions == null) {
Object action = getActions().get(id);
return ((Action) action);
}
Object action = actions.get(id);
if (action == null) {
action = getActions().get(id);
}
if(action instanceof PotPayAction){
PotPayStrategy potPayStrategy = (PotPayStrategy) potPayStrategyMap.get(context.getData("CardChannelFlag"));
action = new PotPayAction(potPayStrategy);
}
return ((Action) action);
}
public void setTimeoutMessages(List timeoutMessages) {
this.timeoutMessages = timeoutMessages;
}
public void setPotPayStrategyMap(Map potPayStrategyMap) {
this.potPayStrategyMap = potPayStrategyMap;
}
}