【校招VIP】如何使用 Spring 实现策略模式+工厂模式

05月19日 收藏 0 评论 3 java开发

【校招VIP】如何使用 Spring 实现策略模式+工厂模式

转载声明:文章来源https://zhuanlan.zhihu.com/p/486894630

一、策略模式

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

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的运算法则...


C 3条回复 评论
慨然思既往

比之前听的课更好懂

发表于 2023-10-06 23:00:00
0 0
灵魂火符

面试官逮着我问内存溢出和内存泄露,k8s,测试前置,jekins集群的问题

发表于 2023-08-04 22:00:00
0 0
梦里不知身是客

请问 一下,我本科就是软件工程(软件测试方向),以后也想成为软件测试工程师,目前大三即将结束,我之前是准备考研 ,也只是知道考研没有考虑具体什么方向之类的。因为软件测试是专业课 大三下才开课,我现在发现考研的学校 基本没有 软件测试方向的,都是比较热门的大数据、人工智能等研究方向。 所以 想成为软件测试工程师 是在大四时好好学习技术 然后本来毕业找工作?还是 应该考研究生(只是 我发现研究生没有研究软件测试的,也可能我没关注到) ?

发表于 2022-11-07 21:00:00
0 0