问题
问题场景
需求是这样:webService接口需根据传入的消息格式(JSON/XML),对传入的字符串参数解析成对象类型供Service调用,且响应时也需根据传入的消息格式(JSON/XML)转换查询到的数据
问题分析
个人分析理解:
- 根据消息格式解析参数String可以单独拿出来作为方法调用
- 将响应的数据转化为String响应也是需要作为方法调用
- JSON和XML解析的过程不一致,但参数和结果一致。正常的话ifelse或switchcase判断消息格式调用相应方法即可,但频繁调用会强耦合且产生很多ifelse冗余代码
- 使用策略模式可以定义接口,使用多个类来继承策略类,然后在Context中可以添加逻辑判断自动选择对应的实现类调用其方法满足需求
- 且使用策略模式使调用方不再需要关注调用的具体方法
策略模式应用
接口
public interface FormatConversionStrategy {
// 将消息格式为(xml/json)的参数转为Map
Map<String, Object> parseParamToMap(String paramStr);
//将list转为 xml / json 字符串
String parseList(String reqStatus, String reqMsg, String rootName, List<Map<String, Object>> paramlist);
}
XML实现类
public class XmlFormatConversion implements FormatConversionStrategy {
@Override
public Map<String, Object> parseParamToMap(String paramStr) {
// XML解析数据逻辑
return new HashMap<String, Object>
}
@Override
public String parseList(String reqStatus, String reqMsg, String rootName, List<Map<String, Object>> paramlist) {
// XML转化数据逻辑
return "";
}
}
JSON实现类
public class JsonFormatConversion implements FormatConversionStrategy {
@Override
public Map<String, Object> parseParamToMap(String paramStr) {
// JSON解析数据逻辑
return new HashMap<String, Object>
}
@Override
public String parseList(String reqStatus, String reqMsg, String rootName, List<Map<String, Object>> paramlist) {
// JSON转化数据逻辑
return "";
}
}
Context同样实现策略类
public class FormatConversionContext implements FormatConversionStrategy {
private FormatConversionStrategy parser;
/**
* 根据消息格式类型实例化对象
* @param messageFormat 消息格式类型 json / xml
*/
public FormatConversionContext(String messageFormat){
if ("JSON".equalsIgnoreCase(messageFormat)) {
this.parser = new JsonFormatConversion();
} else if ("XML".equalsIgnoreCase(messageFormat)) {
this.parser = new XmlFormatConversion();
}
}
@Override
public Map<String, Object> parseParamToMap(String paramStr) {
return parser.parseParamToMap(paramStr);
}
@Override
public String parseList(String reqStatus, String reqMsg, String rootName, List<Map<String, Object>> paramlist) {
return parser.parseList(reqStatus, reqMsg, rootName, paramlist);
}
}
调用方式
// 根据接收的消息格式参数来实例化Context
FormatConversionContext context = new FormatConversionContext(messageFormat);
//直接调用接口的方法即可
Map<String, Object> paramMap = context.parseParamToMap(message);
String resXmlStr = context.parseList(STATUS_FAIL, MSG_FAIL, ROOT_NAME_DATA, null);