策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法(或策略),并将每个算法封装起来,使得它们可以互相替换。策略模式允许算法的变化独立于使用算法的客户(即客户端代码)。简而言之,它让我们可以在运行时选择具体的算法,避免了大量的 if-else
或 switch
语句。
策略模式的组成部分
策略模式主要有以下几个组成部分:
- Context(上下文):持有一个策略的引用,可以更换不同的策略来执行某个操作。
- Strategy(策略接口):定义一个策略接口,通常这个接口包含一个方法,这个方法是被策略实现类所共享的。
- ConcreteStrategy(具体策略):具体的策略类,实现策略接口,定义具体的算法或行为。
- Client(客户端):通过设置策略(ConcreteStrategy)来决定使用哪种具体策略。
策略模式的结构图
+---------------------+
| Context |
+---------------------+
| - strategy: Strategy |
+---------------------+
| + setStrategy() |
| + execute() |
+---------------------+
^
|
+-----------+-----------+
| |
+--------------+ +--------------+
| Strategy | | ConcreteStrategyA |
+--------------+ +---------------------+
| + algorithm()| | + algorithm() |
+--------------+ +---------------------+
+---------------------+
| ConcreteStrategyB |
+---------------------+
| + algorithm() |
+---------------------+
1.方法入口
java
@Component
public class AppContext {
@Autowired
private List<AppStrategy> userAppStrategyList;
private final Map<String, AppStrategy> STRATEGYMAP = new HashMap<>();
@PostConstruct
public void init() {
userAppStrategyInterfaceList.forEach(strategy -> {
STRATEGYMAP.put(strategy.type(), strategy);
});
}
public void add(UserDto userDto) {
STRATEGYMAP.entrySet().stream()
.filter(entry -> entry.getKey().contains(userDto.getType().toString()))
.findFirst()
.ifPresent(entry -> entry.getValue().add(userDto));
}
}
2.接口
java
public interface AppStrategy {
String type();
void add(UserDto dto);
}
3.实现类
实现类1
java
@Service
@Slf4j
public class AppCompanyService implements AppStrategy {
@Override
public String type() {
return "1,2";
}
@Override
public void add(UserDto dto) {
log.info("调用了实现类1");
}
}
实现类2
java
@Service
@Slf4j
public class AppPersonService implements AppStrategy {
@Override
public String type() {
return "3,4";
}
@Override
public void add(UserDto dto) {
log.info("调用了实现类2");
}
}
4.调用
java
@Service
@Slf4j
public class AppUserService {
@Resource
private AppContext appContext;
@GlobalTransactional
public void add(UserDto userDto) throws Exception {
userDto.setType(1);
appIdentityContext.add(userIdentityDto);
}
}
这样就完成了一个策略模式的小demo。