【设计模式】策略模式 模式介绍 示例 优缺点

模式介绍

一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

示例

1
2
3
4
5
6
7
go复制代码if (type == "A") {
// A逻辑
} else if (type == "B") {
// B逻辑
} else {
// 其他逻辑
}

解决有多个if...else等条件分支的情况

定义策略

1
2
3
4
5
6
arduino复制代码public interface BaseStrategy {

public final static String KEY_CONCAT = "_";

String getStrategyKey();
}
1
2
3
4
5
6
7
8
csharp复制代码public interface IStrategy  extends BaseStrategy {

public final static String ESTATE_STRATEGY_KEY_PREFIX = IStrategy.class.getSimpleName() + KEY_CONCAT;

void deal1();

void deal2();
}

添加策略

A

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
typescript复制代码import com.design.pattern.strategy.IStrategy;
import com.design.pattern.strategy.TypeEnum;
import org.springframework.stereotype.Service;

@Service
public class AStrategyImpl implements IStrategy {

@Override
public String getStrategyKey() {
return ESTATE_STRATEGY_KEY_PREFIX + TypeEnum.A.getCode();
}

@Override
public void deal1() {
System.out.println("处理A逻辑的1事件");
}

@Override
public void deal2() {
System.out.println("处理A逻辑的1事件");
}
}

B

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
typescript复制代码import com.design.pattern.strategy.IStrategy;
import com.design.pattern.strategy.TypeEnum;
import org.springframework.stereotype.Service;

@Service
public class BStrategyImpl implements IStrategy {

@Override
public String getStrategyKey() {
return ESTATE_STRATEGY_KEY_PREFIX + TypeEnum.B.getCode();
}

@Override
public void deal1() {
System.out.println("处理B逻辑的1事件");
}

@Override
public void deal2() {
System.out.println("处理B逻辑的2事件");
}
}

其他

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
typescript复制代码import com.design.pattern.strategy.IStrategy;
import com.design.pattern.strategy.TypeEnum;
import org.springframework.stereotype.Service;

@Service
public class OtherStrategyImpl implements IStrategy {

@Override
public String getStrategyKey() {
return ESTATE_STRATEGY_KEY_PREFIX + TypeEnum.Other.getCode();
}

@Override
public void deal1() {
System.out.println("处理其他逻辑的1事件");
}

@Override
public void deal2() {
System.out.println("处理其他逻辑的2事件");
}
}

将策略加载至工厂

使用ApplicationContextAware接口,把所有的策略,初始化到iStrategyMap里面。然后对外提供getStrategy方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
java复制代码@Component
public class TypeStrategyFactory implements ApplicationContextAware {

private Map<String, IStrategy> iStrategyMap = new ConcurrentHashMap<>();

public <T extends IStrategy> T getStrategy(String strategyKey) throws Exception {
IStrategy strategy = iStrategyMap.get(IStrategy.ESTATE_STRATEGY_KEY_PREFIX + strategyKey);
if (strategy == null) {
throw new Exception("TypeStrategyFactory.getStrategy is error, strategyKey is " + strategyKey);
}
return (T) strategy;
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, IStrategy> map = applicationContext.getBeansOfType(IStrategy.class);
map.forEach((key, value) -> iStrategyMap.put(value.getStrategyKey(), value));
}
}

优缺点

优点

  1. 避免使用多重条件判断
  2. 扩展性良好。
  3. 算法可以自由切换

缺点

  1. 策略类会增多。
  2. 所有策略类都需要对外暴露。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%