策略工厂模式
- 1. 需求背景
- 2. 代码实现
- 2.1 定义基类接口
- 2.2 排序策略接口定义
- 2.3 定义抽象类,实现策略接口
- 2.4 具体的排序策略实现类
- 2.5 实现策略工厂类
- 2.6 控制类
- 3. 启动测试
- 4. 总结
1. 需求背景
现在需要你创建一个策略工厂类,来根据策略实现各种排序功能
2. 代码实现
2.1 定义基类接口
首先定义基类接口BaseStrategy
,获取策略名称
public interface BaseStrategy {/*** 获取策略名称*/String getStrategyName();
}
2.2 排序策略接口定义
其次,定义排序策略接口 SortStrategy
:
public interface SortStrategy extends BaseStrategy {/*** 对数组进行排序* @param array 待排序的数组*/void sort(int[] array);
}
2.3 定义抽象类,实现策略接口
定义一个抽象类 AbstractSortStrategy,它实现了部分 SortStrategy 接口的功能,并留出 sort 方法需要被具体策略实现类实现
@Service
@Slf4j
public abstract class AbstractSortStrategy implements SortStrategy {@Overridepublic abstract void sort(int[] array);@Overridepublic abstract String getStrategyName();protected void printStrategyUsed() {log.info("使用 " + getStrategyName() + " 排序策略对数组排序");}
}
2.4 具体的排序策略实现类
实现四种不同的排序算法作为具体策略:
冒泡排序:
@Component
public class BubbleSortStrategy extends AbstractSortStrategy {@Overridepublic void sort(int[] array) {int n = array.length;for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (array[j] > array[j + 1]) {// 交换 array[j] 和 array[j + 1]int temp = array[j];array[j] = array[j + 1];array[j + 1] = temp;}}}printStrategyUsed();}@Overridepublic String getStrategyName() {return "冒泡排序";}
}
插入排序:
@Component
public class InsertionSortStrategy extends AbstractSortStrategy {@Overridepublic void sort(int[] array) {int n = array.length;for (int i = 1; i < n; i++) {int key = array[i];int j = i - 1;while (j >= 0 && array[j] > key) {array[j + 1] = array[j];j--;}array[j + 1] = key;}printStrategyUsed();}@Overridepublic String getStrategyName() {return "插入排序";}
}
快速排序:
@Component
public class QuickSortStrategy extends AbstractSortStrategy {@Overridepublic void sort(int[] array) {quickSort(array, 0, array.length - 1);printStrategyUsed();}private void quickSort(int[] array, int low, int high) {if (low < high) {int pi = partition(array, low, high);quickSort(array, low, pi - 1);quickSort(array, pi + 1, high);}}private int partition(int[] array, int low, int high) {int pivot = array[high];int i = low - 1;for (int j = low; j < high; j++) {if (array[j] < pivot) {i++;int temp = array[i];array[i] = array[j];array[j] = temp;}}int temp = array[i + 1];array[i + 1] = array[high];array[high] = temp;return i + 1;}@Overridepublic String getStrategyName() {return "快速排序";}
}
选择排序:
@Component
public class SelectionSortStrategy extends AbstractSortStrategy {@Overridepublic void sort(int[] array) {int n = array.length;for (int i = 0; i < n - 1; i++) {int minIndex = i;for (int j = i + 1; j < n; j++) {if (array[j] < array[minIndex]) {minIndex = j;}}// 交换 array[i] 和 array[minIndex]int temp = array[i];array[i] = array[minIndex];array[minIndex] = temp;}printStrategyUsed();}@Overridepublic String getStrategyName() {return "选择排序";}
}
2.5 实现策略工厂类
实现策略工厂类 SearchStrategyFactory
,用于管理和获取不同策略的实例:
@Component
@Slf4j
public class SortStrategyFactory implements ApplicationContextAware {private static Map<String, SortStrategy> strategyMap = new HashMap<>();@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {Map<String, SortStrategy> map = applicationContext.getBeansOfType(SortStrategy.class);log.info("初始化排序策略工厂,共找到 {} 个排序策略:", map.size());map.forEach((key, value) -> {strategyMap.put(value.getStrategyName(), value);log.info("策略名称:{},策略类:{}", key, value.getClass().getSimpleName());});}public <T extends SortStrategy> T getStrategy(String strategyName) {SortStrategy strategy = strategyMap.get(strategyName);if (strategy == null) {log.error("获取策略失败,策略名称:{}",strategyName);throw new BaseException(CommonErrorEnum.SYSTEM_ERROR);}return (T) strategy;}
}
2.6 控制类
@RestController
@RequestMapping("/sort")
@Slf4j
public class SortController {@Autowiredprivate SortStrategyFactory strategyFactory;@GetMapping("/array")public ResponseEntity<Map<String,String>> sortArray(@RequestParam String strategyName, @RequestParam int[] array) {Map<String,String> result = new HashMap<>();SortStrategy strategy = strategyFactory.getStrategy(strategyName);strategy.sort(array);// 返回排序后的数组String sortedArray = Arrays.toString(array);log.info("排序后的数组:{}", sortedArray);result.put("排序结果", sortedArray);result.put("排序策略", strategy.getStrategyName());return ResponseEntity.ok(result);}
}
项目完整目录结构
3. 启动测试
请求接口:
运行代码,打断点,结果如下:
结果如下:
4. 总结
ApplicationContextAware 接口实现: SortStrategyFactory
类实现了ApplicationContextAware
接口,并重写了 setApplicationContext
方法。在这个方法中,它获取了所有类型为 SortStrategy
的 Bean,并将它们存储在 strategyMap
中,以策略名称作为键,策略实例作为值。
getStrategy 方法: getStrategy
方法用于根据传入的策略名称 strategyName
,从 strategyMap
中获取对应的策略实例。如果找不到对应的策略实例,则记录错误日志并抛出 BaseException
异常。
代码:GitHub