spring容器注入实现策略模式

spring容器注入实现策略模式

Posted by John Doe on 2022-04-22
Words 908 and Reading Time 4 Minutes
Viewed Times

背景

一个项目对接多个系统的同一功能,或者同一功能多种实现的选择需求的策略模式实现。

Spring容器实现

需求: 物质采购汉堡选择,可以选择采购肯德基或麦当劳

示例代码:

汉堡策略类上下文HamburgerContext:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Component
public class HamburgerContext {

/**
* 汉堡采购service的实现类
*/
@Autowired
private final Map<String, HamburgerStrategy> HamburgerStrategyMap = new ConcurrentHashMap<>();

/**
*
* HamburgerStrategyContext
* @author guozhixian
* @date 2022-4-14
*/
public HamburgerStrategy getHamburgerStrategy(String key) {
return HamburgerStrategyMap.get(key);
}
}

汉堡策略类接口HamburgerStrategy:

1
2
3
4
5
6
7
8
9
10
/**
* HamburgerStrategy
* @date 2022-4-14
*/
public interface HamburgerStrategy {

String getBeefBurger(String count);

String getChickenBurger(String count);
}

汉堡策略接口实现类KFCStrategy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Service("KFCStrategy")
@Slf4j
public class KFCStrategy implements HamburgerStrategy{

@Override
public String getBeefBurger(String count) {
log.info("采购KFC牛肉汉堡{}个",count);
return String.format("KFC牛肉汉堡%s个", count);
}

@Override
public String getChickenBurger(String count) {
log.info("采购KFC鸡肉汉堡{}个",count);
return String.format("KFC鸡肉汉堡%s个", count);
}
}

汉堡策略接口实现类McDonaldStrategy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Service("McDonaldStrategy")
public class McDonaldStrategy implements HamburgerStrategy{

@Override
public String getBeefBurger(String count) {
log.info("采购麦当劳牛肉汉堡{}个",count);
return String.format("麦当劳牛肉汉堡%s个", count);
}

@Override
public String getChickenBurger(String count) {
log.info("采购麦当劳鸡肉汉堡{}个",count);
return String.format("麦当劳鸡肉汉堡%s个", count);
}
}

实现类枚举HamburgerEnum

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Getter
@AllArgsConstructor
public enum HamburgerEnum {
/**
* KFC实现类
*/
KFC("1", "KFCStrategy"),

/**
* McDonald实现类
*/
MCDONALD("2", "McDonaldStrategy");
/**
* 单值码
*/
private final String code;

/**
* 值
*/
private final String value;

public static String getStrategyByCode(String code) {
// 默认KFC实现类
String result = HamburgerEnum.KFC.value;
for (HamburgerEnum hamburgerEnum : HamburgerEnum.values()) {
if (StringUtils.equals(HamburgerEnum.code, code)) {
result = HamburgerEnum.value;
break;
}
}
return result;
}
}

controller调用的策略选择service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Service
public class HamburgerChooseStrategy {

@Autowired
private HamburgerContext hamburgerContext;

@Value("${type}")
private String type;


/**
* 根据配置选择哪家牛肉汉堡
* @param count 数量
* @return String
*/
public String getBeefBurgerBySysConfig(String count) {
return hamburgerContext.getHamburgerStrategy(HamburgerEnum.getStrategyByCode(type)).getBeefBurger(count);
}


/**
* 根据参数选择哪家鸡肉汉堡
*/
public String getChickenBurgerByParam(String count, String code) {
return hamburgerContext.getHamburgerService(HamburgerEnum.getStrategyByCode(code)).getChickenBurger(count);
}
}

传统策略模式写法实现

汉堡策略类上下文HamburgerContext:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class HamburgerContext {

private final HamburgerStrategy hamburgerStrategy

public HamburgerContext(HamburgerStrategy hamburgerStrategy) {
this.hamburgerStrategy = hamburgerStrategy;
}

public String getBeefBurger(String count) {
this.hamburgerStrategy.getBeefBurger(count);
}

public String getChickenBurger(String count) {
this.hamburgerStrategy.getChickenBurger(count);
}
}

汉堡策略类接口HamburgerStrategy:

1
2
3
4
5
6
7
8
9
10
/**
* HamburgerStrategy
* @date 2022-4-14
*/
public interface HamburgerStrategy {

String getBeefBurger(String count);

String getChickenBurger(String count);
}

汉堡策略接口实现类KFCStrategy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Service
@Slf4j
public class KFCStrategy implements HamburgerStrategy{

@Override
public String getBeefBurger(String count) {
log.info("采购KFC牛肉汉堡{}个",count);
return String.format("KFC牛肉汉堡%s个", count);
}

@Override
public String getChickenBurger(String count) {
log.info("采购KFC鸡肉汉堡{}个",count);
return String.format("KFC鸡肉汉堡%s个", count);
}
}

汉堡策略接口实现类McDonaldStrategy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Service
public class McDonaldStrategy implements HamburgerStrategy{

@Override
public String getBeefBurger(String count) {
log.info("采购麦当劳牛肉汉堡{}个",count);
return String.format("麦当劳牛肉汉堡%s个", count);
}

@Override
public String getChickenBurger(String count) {
log.info("采购麦当劳鸡肉汉堡{}个",count);
return String.format("麦当劳鸡肉汉堡%s个", count);
}
}

实现类枚举HamburgerEnum

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Getter
@AllArgsConstructor
public enum HamburgerEnum {
/**
* KFC实现类
*/
KFC("1", "KFC"),

/**
* McDonald实现类
*/
MCDONALD("2", "MCDONALD");
/**
* 单值码
*/
private final String code;

/**
* 值
*/
private final String name;
}

controller调用的策略选择service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Service
public class HamburgerChooseStrategy {

@Value("${type}")
private String type;

@Autowired
private KFCStrategy kfcStrategy;

@Autowired
private McDonaldStrategy mcDonaldStrategy;

@PostConstruct
private void init() {
HamburgerStrategy hamburgerStrategy;
if (StringUtils.isNotBlank(type) && HamburgerEnum.KFC.getName().equals(type)) {
hamburgerStrategy = kfcStrategy;
}else {
hamburgerStrategy = mcDonaldStrategy;
}
HamburgerContext = new HamburgerContext(hamburgerStrategy);
}


/**
* 根据配置选择哪家牛肉汉堡
* @param count 数量
* @return String
*/
public String getBeefBurgerBySysConfig(String count) {
return hamburgerContext.getBeefBurger(count);
}


/**
* 根据参数选择哪家鸡肉汉堡
*/
public String getChickenBurgerByParam(String count, String code) {
return hamburgerContext.geChickenBurger(count);
}
}

This is copyright.

...

...

00:00
00:00