常见的设计模式
1.策略模式
使用场景
通俗来说,策略模式就像是让你有一个策略的工具箱,在不同的情况下选择最合适的策略来解决问题。
使用场景通常包括以下一些:
多重条件判断语句:
当一个操作包含大量的条件判断语句,并且这些分支具有不同的行为时,可以使用策略模式来避免复杂的条件判断逻辑,让代码更加清晰、易于维护。
同一操作有多种实现:
当你有一个操作,它可以有多种不同的实现方式(算法),而且你希望在运行时根据不同的条件选择不同的实现时,策略模式可以帮你轻松做到这一点。
需要动态切换算法或行为:
如果你的程序需要动态地切换算法或行为,策略模式让这成为可能,并且不会让客户端与具体的算法实现耦合。
避免在客户代码中暴露复杂的、算法相关的数据结构:
通过策略模式,你可以隐藏算法的具体实现,只暴露一个简单的接口给客户端。这意味着,实现细节被封装在策略的内部,而客户端不需要了解这些细节。
提高算法的复用和扩展性:
策略模式使得添加新策略或者修改已有策略变得容易,因为新增加的策略并不会影响到那些使用策略的客户端代码。
不同场景切换不同策略:
例如在游戏开发中,不同的游戏角色可以选择不同的行进策略,如步行、奔跑、飞行等,在不同的游戏状态下也可以灵活切换。
测试和调试时模拟行为:
用策略模式,你可以在测试时轻易地将实际的操作替换为模拟操作,而不需要改变客户端代码。
举个例子:
// 策略接口
public interface Strategy {
void execute();
}
// 定制注解,用于标记策略的类型
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface StrategyType {
String value();
}
@StrategyType("OperationA")
public class ConcreteStrategyA implements Strategy {
@Override
public void execute() {
System.out.println("Executing strategy A");
}
}
@StrategyType("OperationB")
public class ConcreteStrategyB implements Strategy {
@Override
public void execute() {
System.out.println("Executing strategy B");
}
}
现在,我们需要一个策略管理器(或上下文),它可以根据注解选择正确的策略并执行:
public class StrategyManager {
private Map<String, Strategy> strategies;
public StrategyManager() {
strategies = new HashMap<>();
// 在构造方法中加载所有策略
loadStrategies();
}
// 过滤并注册实现了 Strategy 接口的类
private void loadStrategies() {
// 伪代码: 使用反射枚举 Strategy 接口的所有实现,并收集它们的注解值
Reflections reflections = new Reflections("your.package.name");
Set<Class<? extends Strategy>> strategyClasses = reflections.getSubTypesOf(Strategy.class);
for (Class<? extends Strategy> clazz : strategyClasses) {
StrategyType annotation = clazz.getAnnotation(StrategyType.class);
if (annotation != null) {
try {
strategies.put(annotation.value(), clazz.getDeclaredConstructor().newInstance());
} catch (Exception e) {
// 异常处理
}
}
}
}
// 根据策略类型执行策略
public void executeStrategy(String strategyType) {
Strategy strategy = strategies.get(strategyType);
if (strategy != null) {
strategy.execute();
} else {
throw new IllegalArgumentException("No strategy found for type: " + strategyType);
}
}
}
使用方式:
public class AnnotationStrategyDemo {
public static void main(String[] args) {
StrategyManager manager = new StrategyManager()