策略模式
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个随着行为变化而选择不同策略对象的 context 对象。策略对象改变 context 对象的执行算法。
实现流程:
1.创建接口,统一策略行为
2.所有策略实现接口行为,写自己对应的业务逻辑,所有的策略都向Spring容器注册
3.创建上下文类(context),并将所有的策略对象放入Map容器
4.根据不同的行为调用上下文对象获取不同的策略对象,执行相应逻辑
Demo:
package
com.swt.demo;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.boot.SpringApplication;
import
org.springframework.boot.autoconfigure.SpringBootApplication;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RestController;
import
java.math.BigDecimal;
@RestController
@SpringBootApplication
public
class
DemoApplication {
@Autowired
private
StrategyContext strategyContext;
@RequestMapping
(
"calculatePrice"
)
public
BigDecimal calculatePrice(String memberLevel) {
return
strategyContext.calculatePrice(memberLevel);
}
public
static
void
main(String[] args) {
SpringApplication.run(DemoApplication.
class
, args);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
package
com.swt.demo;
import
java.math.BigDecimal;
public
interface
Strategy {
/**
* 计算价格
* @return
*/
BigDecimal calculatePrice();
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package
com.swt.demo;
import
org.springframework.stereotype.Component;
import
java.math.BigDecimal;
@Component
(
"generalMember"
)
public
class
GeneralMember
implements
Strategy {
@Override
public
BigDecimal calculatePrice() {
// 普通会员没有折扣,直接返回原价
return
new
BigDecimal(
"100"
);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package
com.swt.demo;
import
org.springframework.stereotype.Component;
import
org.springframework.stereotype.Service;
import
java.math.BigDecimal;
@Component
(
"vipMember"
)
public
class
VipMember
implements
Strategy {
@Override
public
BigDecimal calculatePrice() {
// VIP会员打8折
return
new
BigDecimal(
"80"
);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package
com.swt.demo;
import
org.springframework.stereotype.Component;
import
org.springframework.stereotype.Service;
import
java.math.BigDecimal;
@Component
(
"superMember"
)
public
class
SuperMember
implements
Strategy {
@Override
public
BigDecimal calculatePrice() {
// 超级会员打1折
return
new
BigDecimal(
"10"
);
}
}
|
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
42
43
44
45
46
|
package
com.swt.demo;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Service;
import
java.math.BigDecimal;
import
java.util.Map;
import
java.util.concurrent.ConcurrentHashMap;
@Service
public
class
StrategyContext {
private
final
Map<String, Strategy> strategyMap =
new
ConcurrentHashMap<>();
/**
* 注入所以实现了Strategy接口的Bean
* @param strategyList
*/
/*@Autowired
public StrategyContext(List<Strategy> strategyList) {
strategyMap.clear();
Integer index = 0;
for (Strategy strategy : strategyList) {
strategyMap.put(index.toString(), strategy);
index++;
}
}*/
/**
* 注入所以实现了Strategy接口的Bean
* @param strategyMap
*/
@Autowired
public
StrategyContext(Map<String, Strategy> strategyMap) {
this
.strategyMap.clear();
strategyMap.forEach((k, v)->
this
.strategyMap.put(k, v));
}
/**
* 计算价格
* @param memberLevel 会员等级
* @return 价格
*/
public
BigDecimal calculatePrice(String memberLevel) {
return
strategyMap.get(memberLevel).calculatePrice();
}
}
|
package
com.swt.demo;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.boot.SpringApplication;
import
org.springframework.boot.autoconfigure.SpringBootApplication;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RestController;
import
java.math.BigDecimal;
@RestController
@SpringBootApplication
public
class
DemoApplication {
@Autowired
private
StrategyContext strategyContext;
@RequestMapping
(
"calculatePrice"
)
public
BigDecimal calculatePrice(String memberLevel) {
return
strategyContext.calculatePrice(memberLevel);
}
public
static
void
main(String[] args) {
SpringApplication.run(DemoApplication.
class
, args);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
package
com.swt.demo;
import
java.math.BigDecimal;
public
interface
Strategy {
/**
* 计算价格
* @return
*/
BigDecimal calculatePrice();
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package
com.swt.demo;
import
org.springframework.stereotype.Component;
import
java.math.BigDecimal;
@Component
(
"generalMember"
)
public
class
GeneralMember
implements
Strategy {
@Override
public
BigDecimal calculatePrice() {
// 普通会员没有折扣,直接返回原价
return
new
BigDecimal(
"100"
);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package
com.swt.demo;
import
org.springframework.stereotype.Component;
import
org.springframework.stereotype.Service;
import
java.math.BigDecimal;
@Component
(
"vipMember"
)
public
class
VipMember
implements
Strategy {
@Override
public
BigDecimal calculatePrice() {
// VIP会员打8折
return
new
BigDecimal(
"80"
);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package
com.swt.demo;
import
org.springframework.stereotype.Component;
import
org.springframework.stereotype.Service;
import
java.math.BigDecimal;
@Component
(
"superMember"
)
public
class
SuperMember
implements
Strategy {
@Override
public
BigDecimal calculatePrice() {
// 超级会员打1折
return
new
BigDecimal(
"10"
);
}
}
|
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
42
43
44
45
46
|
package
com.swt.demo;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Service;
import
java.math.BigDecimal;
import
java.util.Map;
import
java.util.concurrent.ConcurrentHashMap;
@Service
public
class
StrategyContext {
private
final
Map<String, Strategy> strategyMap =
new
ConcurrentHashMap<>();
/**
* 注入所以实现了Strategy接口的Bean
* @param strategyList
*/
/*@Autowired
public StrategyContext(List<Strategy> strategyList) {
strategyMap.clear();
Integer index = 0;
for (Strategy strategy : strategyList) {
strategyMap.put(index.toString(), strategy);
index++;
}
}*/
/**
* 注入所以实现了Strategy接口的Bean
* @param strategyMap
*/
@Autowired
public
StrategyContext(Map<String, Strategy> strategyMap) {
this
.strategyMap.clear();
strategyMap.forEach((k, v)->
this
.strategyMap.put(k, v));
}
/**
* 计算价格
* @param memberLevel 会员等级
* @return 价格
*/
public
BigDecimal calculatePrice(String memberLevel) {
return
strategyMap.get(memberLevel).calculatePrice();
}
}
|