Spring AOP的应用:在处理业务短信之前,可以执行前置方法,在处理业务短信之后,可以执行后置方法。
策略模式的应用:不同的业务对应不同的短信格式,业务短信可以随时新增、删除,扩展性高。
模板方法模式的应用:业务短信的校验和最后处理定义成抽象方法,而且,要先通过校验后才能作最后的处理。
访问者模式的应用:每种校验规则都是对所属的短信处理器进行校验。
相关的源代码、类图、配置信息如下:
一、类图
二、类源代码
1、抽象类AbstractNoteProcessor源代码
public abstract class AbstractNoteProcessor {
private String prefix;
private long smsid;
private String msisdn;
private String content;
//###### 此处省略成员变量的get方法 #####
/**
* 此处应用了模板方法模式
*
* @param prefix 短信前缀
* @param smsid 短信流水号
* @param msisdn 手机号码
* @param content 短信内容
*/
public void process(String prefix, long smsid, String msisdn, String content){
this.prefix = prefix;
this.smsid = smsid;
this.msisdn = msisdn;
this.content = content;
boolean b = validate();
if(b){
proceed();
}
}
protected abstract boolean validate();
/**
* 在该方法控制事务
*/
protected abstract void proceed();
}
2、类DefaultNoteProcessor的源代码
public class DefaultNoteProcessor extends AbstractNoteProcessor {
private List checkRules;
public void setCheckRules(List checkRules) {
this.checkRules = checkRules;
}
/**
* 遍历执行每个校验规则,当一个校验规则返回false时,结束继续校验
*
* 此处应用了访问者模式
*/
protected boolean validate() {
if(checkRules == null || checkRules.size() <= 0) return true;
for(int i=0;i<checkRules.size();i++){
Rule rule = (Rule)checkRules.get(i);
boolean b = rule.check(this);
if(!b) return false;
}
return true;
}
protected void proceed() {
}
}
3、类CardSalesNoteProcessor的源代码
public class CardSalesNoteProcessor extends DefaultNoteProcessor {
protected void proceed() {
System.out.println("卡品批售业务短信已处理!");
}
}
4、接口Rule的源代码
public interface Rule {
public boolean check(AbstractNoteProcessor processor);
}
5、类FormatRule的源代码
/**
* 短信格式规则验证类
*/
public class FormatRule implements Rule {
public boolean check(AbstractNoteProcessor processor) {
boolean pass = true;
String[] arr1 = processor.getContent().split(",");
//格式判断
if(arr1.length < 2 || arr1.length > 7){
pass = false;
}else{
for(int i=0;i<arr1.length;i++){
String s = arr1[i];
if(i == 0){
if(s.split("#").length != 3){
pass = false;
break;
}
}else{
if(s.split("#").length != 2){
pass = false;
break;
}
}
}
}
if(!pass){
System.out.println("短信格式有误,卡品申请短信的正确格式为:" + processor.getPrefix() + "帐号#密码,卡编号1#数量1,卡编号2#数量2,...(最多6组卡品)!");
}
return pass;
}
}
6、类NoteManager的源代码
/**
* 短信管理器类
*/
public class NoteManager{
/**
* 存放短信处理器列表
*/
private Map processorMap;
public void setProcessorMap(Map processorMap) {
this.processorMap = processorMap;
}
/**
* 根据短信前缀调用相应的处理器处理短信
*
* 此处应用了策略模式
*
* @param smsid 短信流水号
* @param msisdn 手机号码
* @param content 短信内容
*/
private void doInProcessor(long smsid, String msisdn, String content){
boolean done = false;
if(processorMap!=null && processorMap.keySet().size() > 0){
for(Iterator it=processorMap.keySet().iterator();it.hasNext();){
String prefix = (String)it.next();
AbstractNoteProcessor processor = (AbstractNoteProcessor)processorMap.get(prefix);
if(content.startsWith(prefix)){
processor.process(prefix, smsid, msisdn, content);
done = true;
break;
}
}
}
if(!done){
System.out.println("短信格式不支持!");
}
}
public void run(){
List dataList = getTestData();
if(dataList==null || dataList.size()<=0) return;
for(int i=0;i<dataList.size();i++){
Map map = (Map)dataList.get(i);
long smsid = ((Long)map.get("smsid")).longValue();
String msisdn = (String)map.get("msisdn");
String content = (String)map.get("content");
doInProcessor(smsid, msisdn, content);
}
}
/**
* 获取测试数据的方法
*/
private List getTestData(){
List dataList = new ArrayList();
Map map1 = new HashMap();
map1.put("smsid", new Long(1));
map1.put("msisdn", "13763387426");
map1.put("content", "91#3070301,123456,221#40,222#20");
dataList.add(map1);
Map map2 = new HashMap();
map2.put("smsid", new Long(2));
map2.put("msisdn", "13763387427");
map2.put("content", "66#307030102#13826532222");
dataList.add(map2);
Map map3 = new HashMap();
map3.put("smsid", new Long(3));
map3.put("msisdn", "13763387428");
map3.put("content", "88#13826532223#cl");
dataList.add(map3);
return dataList;
}
}
7、前置通知类的源代码
public class NoteManagerBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target)throws Throwable {
System.out.println("在执行NoteManager的run方法之前,执行该方法!");
}
}
8、后置通知类的源代码
public class NoteManagerAfterReturningAdvice implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("在执行NoteManager的run方法之后,执行该方法!");
}
}
三、Bean配置
<!-- 短信处理器 --> <!-- 卡品批售短信处理器 --> <bean id="cardSalesNoteFormatRule" class="com.jeyo.note.processor.cardsales.FormatRule"/> <bean id="cardSalesNoteProcessor" class="com.jeyo.note.processor.cardsales.CardSalesNoteProcessor"> <property name="checkRules"> <list> <ref bean="cardSalesNoteFormatRule"/> </list> </property> </bean> <!-- 号码激活短信处理器 --> <bean id="numActiveNoteProcessor" class="com.jeyo.note.processor.numactive.NumActiveNoteProcessor"/> <!-- 数据业务开通短信处理器 --> <bean id="operationOpenNoteProcessor" class="com.jeyo.note.processor.operation.OperationOpenNoteProcessor"/> <!-- 短信管理器目标对象 --> <bean id="noteManagerTarget" class="com.jeyo.note.NoteManager"> <property name="processorMap"> <map> <entry key="91#" value-ref="cardSalesNoteProcessor"/> <entry key="66#" value-ref="numActiveNoteProcessor"/> <entry key="88#" value-ref="operationOpenNoteProcessor"/> </map> </property> </bean> <!-- 短信管理器的拦截器 --> <bean id="noteManagerBeforeAdvice" class="com.jeyo.note.interceptor.NoteManagerBeforeAdvice"/> <bean id="noteManagerAfterReturningAdvice" class="com.jeyo.note.interceptor.NoteManagerAfterReturningAdvice"/> <!-- 短信管理器代理工厂 --> <bean id="noteManager" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyTargetClass" value="true"/> <property name="target" ref="noteManagerTarget"/> <property name="interceptorNames"> <list> <value>noteManagerBeforeAdvice</value> <value>noteManagerAfterReturningAdvice</value> </list> </property> </bean>