【策略工厂模式】记录策略工厂模式简单实现

news2024/12/24 9:59:23

策略工厂模式

  • 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 {

    @Override
    public abstract void sort(int[] array);

    @Override
    public abstract String getStrategyName();

    protected void printStrategyUsed() {
        log.info("使用 " + getStrategyName() + " 排序策略对数组排序");
    }
}

2.4 具体的排序策略实现类

实现四种不同的排序算法作为具体策略:

冒泡排序:

@Component
public class BubbleSortStrategy extends AbstractSortStrategy {

    @Override
    public 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();
    }

    @Override
    public String getStrategyName() {
        return "冒泡排序";
    }
}

插入排序:

@Component
public class InsertionSortStrategy extends AbstractSortStrategy {

    @Override
    public 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();
    }

    @Override
    public String getStrategyName() {
        return "插入排序";
    }
}

快速排序:

@Component
public class QuickSortStrategy extends AbstractSortStrategy {

    @Override
    public 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;
    }

    @Override
    public String getStrategyName() {
        return "快速排序";
    }
}

选择排序:

@Component
public class SelectionSortStrategy extends AbstractSortStrategy {

    @Override
    public 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();
    }

    @Override
    public String getStrategyName() {
        return "选择排序";
    }
}

2.5 实现策略工厂类

实现策略工厂类 SearchStrategyFactory,用于管理和获取不同策略的实例:

@Component
@Slf4j
public class SortStrategyFactory implements ApplicationContextAware {

    private static Map<String, SortStrategy> strategyMap = new HashMap<>();

    @Override
    public 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 {

    @Autowired
    private 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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1960675.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

达梦数据库的系统视图v$buffer_lru_first

达梦数据库的系统视图v$buffer_lru_first 达梦数据库系统视图V$BUFFER_LRU_FIRST的主要作用是显示所有缓冲区LRU链首页信息。这个视图帮助数据库管理员监控和管理缓冲池中LRU&#xff08;Least Recently Used&#xff0c;最近最少使用&#xff09;链的性能&#xff0c;通过查看…

专业级享受:2024年视频剪辑工具深度评测与推荐

说到视屏剪辑很多人都会想要到剪映吧&#xff0c;那剪映怎么剪辑视屏呢&#xff1f;剪映之外还有没有其他好用到视屏剪辑软件呢&#xff1f;这次就分享一些我自己用过到工具吧。 1.福昕视频编辑 链接直达>>https://www.pdf365.cn/foxit-clip/ 这个视频剪辑软件大大的…

【Stable Diffusion】(基础篇六)—— embedding

embedding 本系列博客笔记主要参考B站nenly同学的视频教程&#xff0c;传送门&#xff1a;B站第一套系统的AI绘画课&#xff01;零基础学会Stable Diffusion&#xff0c;这绝对是你看过的最容易上手的AI绘画教程 | SD WebUI 保姆级攻略_哔哩哔哩_bilibili 除了大模型和VAE之外…

普明服务小程序正式招募合伙人,共绘家政保洁行业新蓝图

随着家政保洁行业的快速发展和消费者对高品质服务需求的日益增长&#xff0c;普明服务小程序凭借其专业、高效、便捷的服务体验&#xff0c;迅速在市场上崭露头角。为了进一步拓展业务&#xff0c;提升品牌影响力&#xff0c;普明服务小程序现正式面向社会招募合伙人&#xff0…

你还在为PDF转Word烦恼?试试这四款免费工具吧!

悄咪咪问一句&#xff0c;大家在平时上班时最头疼的事情有哪些&#xff1f;我想会有很多朋友也有pdf如何在线转换word文档的免费方式&#xff0c;毕竟这些办公文档是非常常见的问题了&#xff0c;所以今天就专门准备这么一篇文章来分享我个人喜欢的四款好用工具&#xff1a; 第…

基于ChatGPT的“看图说话”

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

dockerd --debugr排查服务无法启动的异常

1、查看docker服务运行状态 [rootlocalhost ~]# systemctl status docker 2、使用dockerd --debug排查错误 [rootlocalhost ~]# dockerd --debug 3、使用dockerd --debug获取的错误 4、根错误在网上查找解决方法 上图错误为二进制安装docker服务&#xff0c;/usr/local/bin/…

从里到外刨析一台电脑的性能,认识电脑很重要,妈妈再也不用担心我买电脑被骗了

现如今时代随着技术的发展&#xff0c;骗子的手段也越来越高明&#xff0c;因此从里到外刨析一台电脑的性能&#xff0c;认识电脑很重要&#xff0c;特别是准备购买电脑的小伙伴&#xff0c;建议看完这篇文章&#xff0c;其他听别人说电脑的好坏都是虚的&#xff0c;只有自己真…

创新概念:柯尔莫哥洛夫-阿诺德网络

文章目录 一、说明二、基础概念三、kolmogorov-Arnold 网络性质3.1 KAN 的潜在优势3.2 挑战和注意事项 四、基本 KAN 超参数五、COLAB 代码六、注意点 一、说明 kolmogorov-Arnold 网络 (KAN) 是深度学习领域的一项“创新”&#xff0c;它提供了一种受现有 Kolmogorov-Arnold …

【时时三省】(C语言基础)循环语句do while循环

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ——csdn时时三省 do语句的语法 do 循环语句&#xff1b; while(表达式)&#xff1b; 表达式为真继续循环 表达式为假停止 示例: break和cobtinue的运用 示例: cobtinue会跳出这个括号 到while 接着一直循…

Python 【机器学习】 进阶 之 【实战案例】房价数据中位数分析 | 1/2(含分析过程)

Python 【机器学习】 进阶 之 【实战案例】房价数据中位数分析 | 1/2&#xff08;含分析过程&#xff09; 目录 Python 【机器学习】 进阶 之 【实战案例】房价数据中位数分析 | 1/2&#xff08;含分析过程&#xff09; 一、简单介绍 二、机器学习 1、为什么使用机器学习&a…

Qt6 qml文件导入系统组件时不再需要版本号

qt开发中&#xff0c;以往在Qt5中&#xff0c;我们导入quick组件的时候总是要写版本号&#xff0c;挺麻烦的&#xff0c;而现在Qt6中qml导入组件无需再使用版本号了。直接导入即可。 import QtQuick import QtQuick.Controls import QtQuick.Window 想要看是否有这个组件&…

【题解】2024牛客多校第5场

E 安 https://ac.nowcoder.com/acm/contest/81600/E 分析 简单博弈 / 思维题。 当 ai > bi 时&#xff0c;当前骑士一定存活。 当 ai < bi 时&#xff0c;当前骑士一定死亡。 为了使得自己存活的骑士尽可能多&#xff0c;若存在 ai bi 的情况&#xff0c;一定会选…

XXE-lab-master靶场:PHP_xxe

目录 有回显 测试回显位置 构建payload 无回显数据外带 构建payload 漏洞修复 XXE-lab是一个一个包含php,java,python,C#等各种语言版本的XXE漏洞靶场。 下载地址&#xff1a;https://github.com/c0ny1/xxe-lab 将PHPStudy的中间件与版本信息调制为 php-5.4.29Apache 以…

【测试】博客系统的测试报告

项目背景 个人博客系统采用了 SSM 框架与 Redis 缓存技术的组合 &#xff0c;为用户提供了一个功能丰富、性能优越的博客平台。 在技术架构上 &#xff0c;SSM 框架确保了系统的稳定性和可扩展性。Spring 负责管理项目的各种组件 &#xff0c;Spring MVC 实现了清晰的请求处理…

【Linux系统】POSIX信号量 线程池

PISIX信号量 概念 POSIX信号量和SystemV信号量作用相同&#xff0c;都是用于同步操作&#xff0c;达到无冲突的访问共享资源目的。 但POSIX可以用于线程间同步。 引入环形队列的概念 环形队列&#xff1a;当队列为空||为满时 head end&#xff0c;我们发现这样无法区分为空…

Springboot2.6.13整合flowable6.8.1

背景 项目上需要使用到工作流相关内容&#xff0c;比对了好久采用flowable实现&#xff0c;该插件和activiti等很相似&#xff0c;基本上可以直接移植 代码如下 <!-- 父引用用--><parent><groupId>org.springframework.boot</groupId><artifactI…

LLM的训练与推断

LLM的训练与推断 目前比较流行的大模型一般都是自回归模型。在推理时&#xff0c;它类似于RNN&#xff0c;每次计算下一个token的概率。也就是说&#xff0c;如果除去最开始的输入情况下&#xff0c;最终推理长度为n的话&#xff0c;就需要计算n次。但是训练却是并行化的。 在…

你想活出怎样的人生?我只活一次,所以想做自己

你好&#xff0c;我是腾阳。 在这纷繁复杂的世界中&#xff0c;我们每个人都像是一颗颗星星&#xff0c;闪烁着自己的光芒。 然而&#xff0c;在这光芒背后&#xff0c;有多少人真正了解自己&#xff0c;又有多少人敢于追随内心的声音&#xff0c;去追寻那些看似遥不可及的梦…

arduino程序-程序函数2(led电路及相关函数)(基础知识)

arduino程序-程序函数2&#xff08;led电路及相关函数&#xff09;&#xff08;基础知识&#xff09; 1-9 程序函数2&#xff08;led电路及相关函数&#xff09;点亮LED需要Blink程序PinMode(LED_BUTTIN,OUTPUT)DigitalWrite(LED_BUILTIN,HIGH)第一个参数(13/LED_BUILTIN)第二个…