行为型设计模式:策略模式
时间:2022-07-23
本文章向大家介绍行为型设计模式:策略模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
策略模式是让策略的实现与策略的使用解耦,在我们日常的开发中,经常用来重构和优化if-else和switch语句。当然,策略模式并不是为了取代if-else和switch语句而生的,这里好多人有一个误区,它的思想是接口的一组实现可以相互替换,让使用和实现解耦。
策略的使用分为2种,一种是有状态的,每个if-else分支的策略使用都需要new一个新的策略对象;一种是无状态的,每个if-else分支的策略使用都用一个公共的策略对象。
策略类的一个demo如下:
public interface Strategy {
void doStrategy();
}
public class StrategyA implements Strategy {
private Logger logger = LoggerFactory.getLogger(getClass());
public void doStrategy() {
logger.info("doStrategy StrategyA");
}
}
public class StrategyB implements Strategy{
private Logger logger = LoggerFactory.getLogger(getClass());
public void doStrategy() {
logger.info("doStrategy StrategyB");
}
}
有状态的策略模式使用:
public class StrategyStatefulFactory {
public static Strategy getStatefulStrategy(String type){
if (StringUtils.isEmpty(type)){
throw new IllegalArgumentException("type must be not null");
}
if(StringUtils.pathEquals(type, "strategyA")){
return new StrategyA();
}else if(StringUtils.pathEquals(type, "strategyB")){
return new StrategyB();
}else{
return null;
}
}
}
无状态的策略模式使用
public class StrategyNonStatefulFactory {
private static Map<String, Strategy> strategyMap = new HashMap<>(3);
static {
strategyMap.put("strategyA", new StrategyA());
strategyMap.put("strategyB", new StrategyB());
}
public static Strategy getStrategy(String type){
if (StringUtils.isEmpty(type)){
throw new IllegalArgumentException("type must be not null");
}
return strategyMap.get(type);
}
}
上面的策略工厂,当我们新加入一个策略类时,都需要修改工厂类,这有点不符合开闭原则,那怎么来处理呢?一种方式是在配置文件中增加配置,工厂初始化的时候读配置文件来初始化工厂中map,第二种方式是通过注解来标注策略类,使用java反射机制来初始化工厂中map。这里我给出一个第二种方式实现的demo
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Strategic {
String value();
}
public interface AnnotationStrategy {
void doStrategy();
}
@Strategic(value = "strategyA")
public class AnnotationStrategyA implements AnnotationStrategy{
private Logger logger = LoggerFactory.getLogger(getClass());
public void doStrategy(){
logger.info("doStrategy AnnotationStrategyA");
}
}
@Strategic(value = "strategyB")
public class AnnotationStrategyB implements AnnotationStrategy{
private Logger logger = LoggerFactory.getLogger(getClass());
public void doStrategy(){
logger.info("doStrategy AnnotationStrategyB");
}
}
工厂类代码如下:
public class AnnotationStrategyFactory {
private static Logger logger = LoggerFactory.getLogger(AnnotationStrategyFactory.class);
static Map<String, AnnotationStrategy> map = new HashMap<>(3);
static {
File classPath = new File("./target/classes/design/behavioral/strategy");
String package = "design.behavioral.strategy";
if (classPath.exists()) {
for (File file : classPath.listFiles()){
String fileName = file.getName();
if (fileName.endsWith(".class")) {
fileName = fileName.replace(".class", "");
try {
Class<?> classZ = Class.forName(package+ "." + fileName);
if (classZ.isAnnotationPresent(Strategic.class)){
map.put(classZ.getAnnotation(Strategic.class).value(), (AnnotationStrategy)classZ.newInstance());
}
} catch (Exception e) {
logger.error("exception:", e);
}
}
}
}
}
public static AnnotationStrategy getAnnotationStrategy(String type) {
return map.get(type);
}
}
源码地址:
https://github.com/jinjunzhu/design-pattern.git
- 关于HTML面试题汇总之visibility
- 加密狗进场暴富开始?请别侮辱区块链和游戏
- 程序猿的日常——Java基础之clone、序列化、字符串、数组
- [你必须知道的.NET] 第四回:后来居上:class和struct
- oc 中随机数的用法(arc4random() 、random()、CCRANDOM_0_1()
- 央行出台条码支付新规;美团打车将在7大城市上线;国产人工智能平台型芯片首发;苹果就降速门致歉
- 阿三又让全球看笑话,无人驾驶的地铁名不副实,还直接跑到大街上
- 盘点:2017年度这些科学大事件,哪个给您印象最深?
- 跳台阶问题
- mac下使用github
- CSS3新特性应用之结构与布局
- 程序猿的日常——Java基础之equals与hashCode
- 贾康:智能金融需在发展和规范中掌握理性权衡点
- Objective-C: 字符串NSString与NSMutableString
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Activity的启动过程详解(基于10.0源码)
- Activity生命周期-你真的了解吗?
- Activity启动模式
- Redis6.0主从、哨兵、集群搭建和原理
- Linux入门学习笔记二
- 聊聊dubbo-go的tracingFilter
- 轻松学Pytorch –使用torchvision实现对象检测
- Linux core dump有什么用?
- Linux系统搭建C++开发环境
- Spring入门
- TKE容器实现限制用户在多个namespace上的访问权限(上)
- TKE容器实现限制用户在多个namespace上的访问权限(下)
- 小程序Android可以请求,ios请求失败wx.request
- css中的box-shadow详解
- 迭代器和foreach原理。