设计模式系列:策略模式的设计与实践

发布于:2024-08-15 ⋅ 阅读:(127) ⋅ 点赞:(0)

一、背景

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户。

二、结构

策略模式主要包含三个角色:

  • Strategy(策略接口):定义了所有支持的所有算法的公共接口。
  • ConcreteStrategy(具体策略):实现了 Strategy 接口,提供了具体的算法实现。
  • Context(上下文):维护了一个对 Strategy 对象的引用,通常在构造函数中传入具体的策略对象,并通过一个方法让策略接口的实现生效。

三、示例代码

假设我们需要获取每个班级的学生人数,只是简单的一个示例:

3.1 创建班级的枚举类
/**
 * 班级信息枚举
 */
@AllArgsConstructor
@Getter
public enum ClassEnum {
    CLASS_1A("1A", "一年级一班", 25),
    CLASS_1B("1B", "一年级二班", 32);

    // 班级代码
    private final String classCode;
    // 班级名称
    private final String className;
    // 班级人数
    private final int numberOfStudents;

    public static ClassEnum getByClassCode(String classCode) {
        return Arrays.stream(ClassEnum.values()).filter(classInfo -> classInfo.getClassCode().equals(classCode)).findFirst().orElse(null);
    }
}
3.2 抽象类
/**
 * 抽象处理类
 */
public abstract class AbstractClassHandle {

    public abstract String getCode();

    public abstract int getCount();

}
3.3 简单工厂
/**
 * 简单工厂类
 *
 */
@Component
public class ClassExecuteServiceFactory implements ApplicationContextAware {

    private final static Map<String, AbstractClassHandle> CLASS_CODE_ABSTRACT_CLASS_HANDLE_MAP = new HashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, AbstractClassHandle> types = applicationContext.getBeansOfType(AbstractClassHandle.class);
        types.values().forEach(e -> CLASS_CODE_ABSTRACT_CLASS_HANDLE_MAP.putIfAbsent(e.getCode(), e));
    }

    public static AbstractClassHandle getHandler(String code) {
        return CLASS_CODE_ABSTRACT_CLASS_HANDLE_MAP.get(code);
    }
}
3.4 两个不同的处理类

ClassOneExecuteServiceHandle 班级一

/**
 * 1班handle类
 *
 */
@Component
public class ClassOneExecuteServiceHandle extends AbstractClassHandle {

    @Override
    public String getCode() {
        return ClassEnum.CLASS_1A.getClassCode();
    }

    @Override
    public int getCount() {
        return ClassEnum.CLASS_1A.getNumberOfStudents();
    }
}

ClassTwoExecuteServiceHandle 班级二

/**
 * 2班handle类
 *
 */
@Component
public class ClassTwoExecuteServiceHandle extends AbstractClassHandle {

    @Override
    public String getCode() {
        return ClassEnum.CLASS_1B.getClassCode();
    }

    @Override
    public int getCount() {
        return ClassEnum.CLASS_1B.getNumberOfStudents();
    }
}
3.5 测试请求类
/**
 * @author Jerryean
 * @description 测试策略方式
 */
@Api(tags = "测试策略方式")
@RestController
@RequestMapping("/strategy")
public class AbstractTestController {

    @GetMapping("/abstractTest")
    @ApiOperation("策略模式-简单测试")
    public BaseResponse<Integer> abstractTest(@RequestParam(value = "classCode") String classCode) {
        int count = ClassExecuteServiceFactory.getHandler(classCode).getCount();
        return BaseResponse.data(count);
    }
}

四、总结

策略模式非常适合那些需要在运行时动态改变行为的场景。
策略模式是一种非常实用的设计模式,可以帮助开发人员编写更加灵活和可维护的代码。