策略模式
一个类的行为或其算法可以在运行时更改,这种类型的设计模式属于行为模式.
介绍
在有多种算法的情况下,大量的使用if…else… 会使代码过于冗余,难以维护. 策略模式就是基于这种情况下,将使用的算法封装成单个的类,通过实现同一个接口动态实现需求替换.
优点: 1. 算法可以自由切换; 2. 避免使用多重条件判断; 3. 扩展性良好
缺点: 1.当算法过多时,需要建立大量的策略类; 2. 所有的策略类都需要对外暴露.
注意事项: 当一个系统中策略类超过四个的时候,我们可以考虑使用混合模式,解决策略类膨胀的问题
实现
我们需要先创建一个定义活动的 Strategy接口,在此接口中定义共同执行的方法; 然后再创建策略实现类,并实现Strategy接口; 然后我们需要创建一个Context上下文策略类,用来区分不同的策略执行不同的方法(个人理解).
基础Demo
步骤一 创建一个公共接口Strategy
public interface Strategy {
public int doOperation(int num1, int num2);
}
步骤二 创建几个不同的算法策略类
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2; // 每个实现方法都不同
}
}
public class OperationSubtract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2; // 每个实现方法都不同
}
}
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2; // 每个实现方法都不同
}
}
步骤三 创建Context上下文类
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
步骤四 在main方法内进行测试
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubtract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
运行结果为:
策略模式在SpringBoot中的使用
在springboot中使用与基础的Demo大同小异,无非是再次基础上配置了一些注解是我们的设计更优雅.
步骤一 创建一个公共接口Strategy
/*
策略模式 基类
*/
public interface StudentStrategy {
// 抽象方法,实现不同类型的处理
public void getClassStrategy(Student student);
}
步骤二 创建策略类
@Component("1")
@Slf4j
public class EnumAnalysisStrategy1 implements StudentStrategy {
@Override
public void getClassStrategy(Student student) {
// 枚举类型不进行报警处理
System.out.println("我拿到了语文...............");
}
}
@Component("2")
@Slf4j
public class EnumAnalysisStrategy2 implements StudentStrategy {
@Override
public void getClassStrategy(Student student) {
// 枚举类型不进行报警处理
System.out.println("我拿到了数学...............");
}
}
@Component("3")
@Slf4j
public class EnumAnalysisStrategy3 implements StudentStrategy {
@Override
public void getClassStrategy(Student student) {
// 枚举类型不进行报警处理
System.out.println("我拿到了英语...............");
}
}
步骤三 创建上下文类
@Slf4j
@Service
public class StudentTypeContext {
private Map<String, StudentTypeContext> strategyMap = new ConcurrentHashMap<>();
public StudentTypeContext(Map<String, StudentTypeContext> strategyMap) {
this.strategyMap.clear();
strategyMap.forEach((k,v)->this.strategyMap.put(k,v));
}
public StudentTypeContext getStudentTypeContext(String studentType){
return this.strategyMap.get(studentType);
}
}
步骤四 在方法中进行调用
public class StudentTypeDemo {
@Resource
StudentTypeContext studentTypeContext;
public void checkStudentType(Student student) {
StudentTypeContext studentTypeContext = studentTypeContext.getstudentTypeContext(student.getStudentType);
studentTypeContext.getClassStrategy();
}
}