1.策略模式的定义(百度百科)
策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。
从上面我们可以看出,策略模式解决的是不同场景下,对象有不同的行为的问题,对应的java语法就是if-else。
2.案例
客户端传一串模板数据,有json、xml 2种类型,服务端从中解析出关键的信息,然后返回到客户端。
3.策略模式的实现
3.1 定义抽象接口
无论哪种数据类型,都需要对模板进行解析,我们可以定义一个parse方法执行这个动作。
public interface TemplateStrategy {
/**
* 解析模板
* @param params
* @return
*/
List<Map<String, Object>> parse(Map<String, Object> params);
}
3.2 定义实现算法
模板有json、xml 2中格式,我们可以定义对应的算法。
public class JsonStrategy implements TemplateStrategy {
/**
* 解析模板
*
* @param params
* @return
*/
@Override
public List<Map<String, Object>> parse(Map<String, Object> params) {
// 解析JSON数据
System.out.println("JSON.....");
return null;
}
}
public class XmlStrategy implements TemplateStrategy{
/**
* 解析模板
*
* @param params
* @return
*/
@Override
public List<Map<String, Object>> parse(Map<String, Object> params) {
System.out.println("XML.....");
return null;
}
}
3.3 定义上下文对象
上下文对象一般持有一个策略对象,调用策略算法。
public class TemplateContext {
/**
* 模板内容
*/
private String template;
/**
* 类型
*/
private String templateType;
/**
* 模板数据格式 json
*/
private final static String TEMPLATE_TYPE_JSON = "json";
/**
* 模板数据格式 xml
*/
private final static String TEMPLATE_TYPE_XML = "xml";
/**
* 构造函数
* @param template
*/
public TemplateContext(String template) {
this.template = template;
init();
}
/**
* 初始化数据
*/
private void init() {
// 解析数据格式
template = template.trim();
if (template.startsWith("<")) {
if (template.indexOf("<?xml") < 0) {
template = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + template;
}
templateType = TEMPLATE_TYPE_XML;
} else {
templateType= TEMPLATE_TYPE_JSON;
}
}
/**
* 校验模板数据
* @return
*/
public String checkData() {
// 校验成功时返回空
// 校验失败时返回具体的错误信息
return "";
}
/**
* 解析模板
* @return
*/
public List<Map<String, Object>> parse() {
TemplateStrategy strategy = getStrategy();
return strategy.parse(new HashMap<>());
}
/**
* 获取解析策略
* @return
*/
private TemplateStrategy getStrategy() {
if ("json".equalsIgnoreCase(templateType)){
return new JsonStrategy();
} else if ("xml".equalsIgnoreCase(templateType)) {
return new XmlStrategy();
} else {
return new TextStrategy();
}
}
}
3.4 客户端调用
public class Client {
public static void main(String[] args) {
String template = "{\"a\" : \"123\"}";
// 1.初始化上下文对象
TemplateContext context = new TemplateContext(template);
// 2.数据校验 返回空时,数据正常
String msg = context.checkData();
// 3.解析模板
List<Map<String, Object>> result = context.parse();
}
}
4 策略模式总结
- 一般有一个公共算法的抽象接口,一些具体的算法实现,一个上下文对象。 客户端可以将具体的策略传给上下文对象,也可以根据具体的情况,在上下文中决定使用哪个策略。
- 将具体的算法抽象出来,使这些算法可以相互替换。
- 适合于扁平化算法,每个策略都是平等的、可替换的,因此每个算法只会被使用一次,不可重复使用,不可嵌套。
- 策略模式体现了开闭原则和里氏替换原则。