⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/qq_40378034/article/details/104121363/ 「邋遢的流浪剑客」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

一、策略模式

策略模式定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换

1、策略模式主要角色

主要角色如下:

  • 封装角色(Context): 也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化
  • 抽象策略角色(Strategy): 策略家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性
  • 具体策略角色(ConcreteStrategy): 实现抽象策略中的操作,该类含有具体的算法

2、实现策略模式

//抽象策略角色
public interface Strategy {
//策略模式的运算法则
void doSomething();
}
//具体策略角色
public class ConcreteStrategy1 implements Strategy {
@Override
public void doSomething() {
System.out.println("具体策略1的运算法则...");
}
}
//具体策略角色
public class ConcreteStrategy2 implements Strategy {
@Override
public void doSomething() {
System.out.println("具体策略2的运算法则...");
}
}
public class Client {
public static void main(String[] args) {
//声明一个具体的策略
Strategy strategy = new ConcreteStrategy1();
//声明上下文对象
Context context = new Context(strategy);
//执行封装后的方法
context.doAnything();
}
}

执行结果如下:

具体策略1的运算法则...

二、使用Spring实现策略模式+工厂模式

1、实现策略类

public interface Strategy {
//策略模式的运算法则
void doSomething();
}
@Component
public class ConcreteStrategy1 implements Strategy {
@Override
public void doSomething() {
System.out.println("具体策略1的运算法则...");
}

@Override
public String toString() {
return "具体策略1";
}
}
@Component
public class ConcreteStrategy2 implements Strategy {
@Override
public void doSomething() {
System.out.println("具体策略2的运算法则...");
}

@Override
public String toString() {
return "具体策略2";
}
}
@Component
public class DefaultStrategy implements Strategy {
@Override
public void doSomething() {
System.out.println("默认策略的运算法则...");
}

@Override
public String toString() {
return "默认策略";
}
}

2、实现工厂类

@Component
public class StrategyFactory {
//Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类
@Autowired
private Map<String, Strategy> strategyMap;

public Strategy getBy(String strategyName) {
return strategyMap.get(strategyName);
}
}

Spring会自动将Strategy接口的实现类注入到这个Map中(前提是实现类得是交给Spring 容器管理的),这个Map的key为bean id,可以用@Component(value = "xxx")的方式设置,如果直接用默认的方式的话,就是首字母小写。value值则为对应的策略实现类

测试类:

@SpringBootTest
class SpringbootDemoApplicationTests {

@Autowired
private ApplicationContext context;

@Test
public void test() {
context.getBean(StrategyFactory.class).getBy("concreteStrategy1").doSomething();
context.getBean(StrategyFactory.class).getBy("concreteStrategy2").doSomething();
}

}

执行结果如下:

具体策略1的运算法则...
具体策略2的运算法则...

3、别名转换

上面测试类调用的使用使用的bean id,实际业务中应该是将传入的code转义成对应的策略类的bean id

@Component
@PropertySource("classpath:application.properties")
@ConfigurationProperties(prefix = "strategy")
public class StrategyAliasConfig {
private HashMap<String, String> aliasMap;

public static final String DEFAULT_STATEGY_NAME = "defaultStrategy";

public HashMap<String, String> getAliasMap() {
return aliasMap;
}

public void setAliasMap(HashMap<String, String> aliasMap) {
this.aliasMap = aliasMap;
}

public String of(String entNum) {
return aliasMap.get(entNum);
}
}

配置文件application.properties

strategy.aliasMap.strategy1=concreteStrategy1
strategy.aliasMap.strategy2=concreteStrategy2
@Component
public class StrategyFactory {
@Autowired
private StrategyAliasConfig strategyAliasConfig;

//Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类
@Autowired
private Map<String, Strategy> strategyMap;

//找不到对应的策略类,使用默认的
public Strategy getBy(String strategyName) {
String name = strategyAliasConfig.of(strategyName);
if (name == null) {
return strategyMap.get(StrategyAliasConfig.DEFAULT_STATEGY_NAME);
}
Strategy strategy = strategyMap.get(name);
if (strategy == null) {
return strategyMap.get(StrategyAliasConfig.DEFAULT_STATEGY_NAME);
}
return strategy;

}
}

测试类:

@SpringBootTest
class SpringbootDemoApplicationTests {

@Autowired
private ApplicationContext context;

@Test
public void test() {
context.getBean(StrategyFactory.class).getBy("strategy1").doSomething();
context.getBean(StrategyFactory.class).getBy("strategy2").doSomething();
}

}

执行结果如下:

具体策略1的运算法则...
具体策略2的运算法则...

文章目录
  1. 1. 一、策略模式
    1. 1.1. 1、策略模式主要角色
    2. 1.2. 2、实现策略模式
  2. 2. 二、使用Spring实现策略模式+工厂模式
    1. 2.1. 1、实现策略类
    2. 2.2. 2、实现工厂类
    3. 2.3. 3、别名转换