案例突破——再探策略模式

news2024/11/27 23:40:40

再探设计模式

  • 一、背景介绍
  • 二、 思路方案
  • 三、过程
    • 1. 策略模式基本概念
    • 2. 策略模式类图
    • 3. 策略模式基本代码
      • 策略类
      • 抽象策略类
      • Context类
      • 客户端
    • 4. 策略模式还可以进行优化的地方
    • 5. 对策略模式的优化(配置文件+反射)
  • 四、总结
  • 五、升华

一、背景介绍

在做项目重构的过程中,发现对于主题讨论中,针对于学生评论/回复的内容的按照评论/回复日期排序、按照评论数量排序、按照点赞次数排序可以使用策略模式进行优化。

二、 思路方案

  1. 策略模式基本概念
  2. 策略模式类图
  3. 策略模式基本代码
  4. 策略模式还可以进行优化的地方
  5. 对策略模式进行优化

三、过程

1. 策略模式基本概念

定义:定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化不会影响到使用算法的客户。

2. 策略模式类图

在这里插入图片描述

3. 策略模式基本代码

策略类

package com.wangwei.strategypattern.normal;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : ConcreteStrategy
 * @description : [描述说明该类的功能]
 * @createTime : [2023/9/7 10:34]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:34]
 * @updateRemark : [描述说明本次修改内容]
 */
public class ConcreteStrategyA implements IStrategy{
    public void AlgorithmInterface(){
        System.out.println("算法A实现");
    }
}

package com.wangwei.strategypattern.normal;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : ConcreteStrategy
 * @description : [描述说明该类的功能]
 * @createTime : [2023/9/7 10:34]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:34]
 * @updateRemark : [描述说明本次修改内容]
 */
public class ConcreteStrategyB implements IStrategy{
    public void AlgorithmInterface(){
        System.out.println("算法B实现");
    }
}

package com.wangwei.strategypattern.normal;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : ConcreteStrategy
 * @description : [描述说明该类的功能]
 * @createTime : [2023/9/7 10:34]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:34]
 * @updateRemark : [描述说明本次修改内容]
 */
public class ConcreteStrategyC implements IStrategy{
    public void AlgorithmInterface(){
        System.out.println("算法C实现");
    }
}



抽象策略类

package com.wangwei.strategypattern.normal;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : IStrategy
 * @description : [描述说明该类的功能]
 * @createTime : [2023/9/7 10:37]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:37]
 * @updateRemark : [描述说明本次修改内容]
 */
public interface IStrategy {
    void AlgorithmInterface();
}

Context类

package com.wangwei.strategypattern.normal;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : Context
 * @description : [公共上下文]
 * @createTime : [2023/9/7 10:38]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:38]
 * @updateRemark : [描述说明本次修改内容]
 */
public class Context {
    IStrategy iStrategy=null;

    public Context(IStrategy iStrategy) {
        this.iStrategy = iStrategy;
    }

    public void ContextInterface(){
        iStrategy.AlgorithmInterface();
    }
}

客户端

package com.wangwei.strategypattern.normal;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : Client
 * @description : [描述说明该类的功能]
 * @createTime : [2023/9/7 10:40]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:40]
 * @updateRemark : [描述说明本次修改内容]
 */
public class Client {
    public static void main(String[] args) {
        Context context=null;

        context= new Context(new ConcreteStrategyA());
        context.ContextInterface();

        context = new Context(new ConcreteStrategyB());
        context.ContextInterface();

        context = new Context(new ConcreteStrategyB());
        context.ContextInterface();
    }
}

4. 策略模式还可以进行优化的地方

当我们需要增加新的策略的时候,是需要修改客户端的代码,那么对于客户端来说是不符合开闭原则的。

5. 对策略模式的优化(配置文件+反射)

package com.wangwei.strategypattern.better;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : ConcreteStrategy
 * @description : [描述说明该类的功能]
 * @createTime : [2023/9/7 10:34]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:34]
 * @updateRemark : [描述说明本次修改内容]
 */
public class ConcreteStrategyA implements IStrategy {
    public void AlgorithmInterface(){
        System.out.println("算法A实现");
    }
}

package com.wangwei.strategypattern.better;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : ConcreteStrategy
 * @description : [描述说明该类的功能]
 * @createTime : [2023/9/7 10:34]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:34]
 * @updateRemark : [描述说明本次修改内容]
 */
public class ConcreteStrategyB implements IStrategy {
    public void AlgorithmInterface(){
        System.out.println("算法B实现");
    }
}

package com.wangwei.strategypattern.better;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : ConcreteStrategy
 * @description : [描述说明该类的功能]
 * @createTime : [2023/9/7 10:34]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:34]
 * @updateRemark : [描述说明本次修改内容]
 */
public class ConcreteStrategyC implements IStrategy {
    public void AlgorithmInterface(){
        System.out.println("算法C实现");
    }
}

package com.wangwei.strategypattern.better;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : Context
 * @description : [公共上下文]
 * @createTime : [2023/9/7 10:38]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:38]
 * @updateRemark : [描述说明本次修改内容]
 */
public class Context {

    static Map<String,String> config = new HashMap<>();
    static Map<String,IStrategy> configBean = new HashMap<>();
    //提前读取配置文件中的策略,并提前准备好已有的策略对象
    static {
        InputStream inputStream = Context.class.getResourceAsStream("/config.properties");
        Properties properties = new Properties();
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String strategyType = properties.getProperty("strategyType");
        String[] strs = strategyType.split(",");

        for (String string : strs) {
            String key = string.split(":")[0];
            String value = string.split(":")[1];
            // 去掉头部空格
            String key1 = key.trim();
            String value1 = value.trim();
            config.put(key1, value1);
        }
        //提前准备好已有的策略对象
        for (Map.Entry<String,String> entry:config.entrySet()) {
            Class strategyClass ;
            try {
                strategyClass = Class.forName(entry.getValue());
                configBean.put(entry.getKey(),(IStrategy) strategyClass.getConstructor().newInstance());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }

    }
    IStrategy iStrategy;
    public Context(String type) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException {
        if(configBean.containsKey(type)){
            this.iStrategy = configBean.get(type);
        }else {
            Class strategyClass = Class.forName(config.get(type));
            this.iStrategy = (IStrategy)strategyClass.getConstructor().newInstance();
        }
    }
    public void ContextInterface(){
        iStrategy.AlgorithmInterface();
    }



}

package com.wangwei.strategypattern.better;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : IStrategy
 * @description : [描述说明该类的功能]
 * @createTime : [2023/9/7 10:37]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:37]
 * @updateRemark : [描述说明本次修改内容]
 */
public interface IStrategy {
    void AlgorithmInterface();
}

package com.wangwei.strategypattern.better;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : Client
 * @description : [描述说明该类的功能]
 * @createTime : [2023/9/7 10:40]
 * @updateUser : [WangWei]
 * @updateTime : [2023/9/7 10:40]
 * @updateRemark : [描述说明本次修改内容]
 */
public class Client {
    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException {
        /*
        1.前端通过下拉框选择不同的类型
        2.类型是从配置文件中读取的
         */
        Context context;
        context= new Context("strategyA");
        context.ContextInterface();

        context = new Context("strategyB");
        context.ContextInterface();

        context = new Context("strategyC");
        context.ContextInterface();
    }
}

四、总结

  1. 优点:配置文件+反射的方式,符合开闭原则。用户可以在不修改原有代码的基础上选择算法,也可以灵活的增加新的算法。

  2. 缺点:无法同时在客户端使用多个策略类。

  3. 关键点:都是对通一份数据,根据不同的算法进行处理。

  4. 什么时候使用策略模式:一个系统需要动态地在几种算法中选择一种。

五、升华

  1. 学习是一个反复的过程:通过项目切实的需求来结合具体的设计模式,在反过来在此基础上优化设计模式。

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

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

相关文章

ccf_csp第一题汇总

ccf_csp第一题汇总 printf()输出格式大全&#xff08;附 - 示例代码&#xff09;现值计算AcWing 4699. 如此编码AcWing 4509. 归一化处理(小数位数根号函数)AcWing 4454. 未初始化警告AcWing 4280. 序列查询AcWing 4006. 数组推导(小陷阱)AcWing 3292. 称检测点查询AcWing 3287…

git你学“废”了吗?——git本地仓库的创建

git你学“废”了吗&#xff1f;——git本地仓库的创建&#x1f60e; 前言&#x1f64c;初识gitgit 本地仓库的创建1、基于centos7环境下 git的下载2、设置自己的用户名和邮箱 查看.git中的结构区分清楚版本库和工作区 查看git中的相关内容查看仓库的状态 总结撒花&#x1f49e;…

给奶牛做直播之一

一、前言 前几天看了薇亚写的一本书《人生是用来改变的》&#xff0c;和同事聊的时候同事问我这本书讲了什么&#xff0c;我回想了一下说主要是讲&#xff1a;我很辛苦&#xff0c;我很上进&#xff0c;我很牛逼&#xff0c;我很善良&#xff01;话说成功人士放个屁都是香的&am…

[题]修剪草坪 #单调队列优化

题目 洛谷上的题目 Acwing上的题目 根据y总的一波分析&#xff0c;我们得出……公式就是一切…… 所以&#xff0c;我要学会推公式…… 推公式…… 公式…… #include<bits/stdc.h> using namespace std; typedef long long ll; const int N 1e5 10; int n, m; ll s[N…

知识库系统都有哪些?知识库系统功能和介绍

知识库的建立是企业数字化转型的重要一步&#xff0c;能够为企业的可持续发展奠定坚实的基础。使用HelpLook创建的知识库知识库系统已经成为当前很多人的选择。 HelpLook可以实现并制作企业帮助中心设计、产品说明书、常见问题手册、在线知识库、企业文档制作。 点击注册使用&…

pip version 更新

最近报了一个错&#xff1a; 解决办法&#xff1a; 在cmd输入“conda install pip” conda install pip 完了之后再输入&#xff1a; python -m pip install --upgrade pip ok.

面试题六:Promise的使用,一文详细讲解

含义 Promise是异步编程的一种解决方案&#xff0c;比传统的解决方案&#xff08;回调函数和事件&#xff09;更合理更强大。 所谓Promise&#xff0c;简单说就是一个容器&#xff0c;里面保存着某个未来才会结束的事件 (通常是一个异步操作)的结果。从语法上说&#xff0c;P…

WPF 01

xaml是声明性语言 每见到一个标签&#xff0c;就意味着xaml为我们声明一个标签对应的对象。 在XAML中为对象属性赋值 1. AttributeValue形式 <Grid><Rectangle Width"100" Height"80" Stroke"Black" Fill"Blue" RadiusX&q…

Mybatis 二级缓存(使用Redis作为二级缓存)

上一篇我们介绍了mybatis中二级缓存的使用&#xff0c;本篇我们在此基础上介绍Mybatis中如何使用Redis作为二级缓存。 如果您对mybatis中二级缓存的使用不太了解&#xff0c;建议您先进行了解后再阅读本篇&#xff0c;可以参考&#xff1a; Mybatis 二级缓存https://blog.csd…

oracle分组合并数值带顺序

比如&#xff1a;有如下一张设备电子围栏位置坐标的表&#xff08;tb_equ_point&#xff09;。 equ_name:设备电子围栏名称 point_id:点位坐标id point_x:点位x坐标 point_y:点位y坐标。 附数据&#xff1a; INSERT INTO "tb_equ_point" ("EQU_NAME",…

数据结构题型11-顺序队列

#include <iostream> //引入头文件 using namespace std;typedef int Elemtype;#define Maxsize 5 #define ERROR 0 #define OK 1typedef struct {Elemtype data[Maxsize];int front, rear; }SqQueue;void InitQueue(SqQueue& Q) //初始化队列 {Q.rear Q.front…

使用代理IP进行安全高效的竞争情报收集,为企业赢得竞争优势

在激烈的市场竞争中&#xff0c;知己知彼方能百战百胜。竞争对手的信息对于企业来说至关重要&#xff0c;它提供了洞察竞争环境和市场的窗口。在这个信息时代&#xff0c;代理IP是一种实用的工具&#xff0c;可以帮助企业收集竞争对手的产品信息和营销活动数据&#xff0c;为企…

lv5 嵌入式开发-11 消息队列

掌握&#xff1a;消息队列机制、打开/创建消息队列、发送消息、接收消息 1 消息队列 消息队列是System V IPC对象的一种 消息队列由消息队列ID来唯一标识 消息队列就是一个消息的列表。用户可以在消息队列中添加消息、读取消息等 消息队列可以按照类型来发送/接收消息 消…

Win10自带输入法怎么删除-Win10卸载微软输入法的方法

Win10自带输入法怎么删除&#xff1f;Win10系统自带输入法就是微软输入法&#xff0c;这个输入法满足了很多用户的输入需求。但是&#xff0c;有些用户想要使用其它的输入法&#xff0c;这时候就想删除掉微软输入法。下面小编给大家介绍最简单方便的卸载方法吧。 Win10卸载微软…

数据挖掘(1)概述

一、数据仓库和数据挖掘概述 1.1 数据仓库的产生 数据仓库与数据挖掘&#xff1a; 数据仓库和联机分析处理技术(存储)。数据挖掘&#xff1a;在大量的数据中心挖掘感兴趣的知识、规则、规律、模式、约束(分析)。数据仓库用于决策分析&#xff1a; 数据仓库&#xff1a;是在数…

在Qt中,怎么获取到在mainwindow.ui文件中添加的控件

2023年9月30日&#xff0c;周六晚上 假设我在mainwindow.ui中添加了一个名为textEdit的QTextEdit对象 在mainwindow.cpp中&#xff0c;可以通过ui对象来获取到这个控件

妙不可言的Python之旅----(一)

初识Python python的起源 1989年&#xff0c;为了打发圣诞节假期&#xff0c;Gudio van Rossum吉多 范罗苏姆&#xff08;龟叔&#xff09;决心开发一个新的解释程序&#xff08;Python雏形&#xff09; 1991年&#xff0c;第一个Python解释器诞生 Python这个名字&#xff…

怎么修改jupyter lab 的工作路径而不是直接再桌面路径打开

要修改Jupyter Lab的工作路径&#xff0c;你可以按照以下步骤操作&#xff1a; 打开终端或命令提示符窗口。 输入 jupyter lab --generate-config 命令来生成Jupyter Lab的配置文件。 找到生成的配置文件&#xff0c;通常会位于 ~/.jupyter/jupyter_notebook_config.py。 使…

C++ AB组辅导课

C AB组辅导课 蓝桥杯C AB组辅导课 第一讲 递归与递推 Acwing1、整数划分(递归)2、acwing92. 递归实现指数型枚举10凑算式(全排列)11李白打酒(全排列)12、棋牌总数(递归)13、剪邮票(递归)14、1050. 鸣人的影分身 (递归或动态规划(记忆化搜索))15、方格分割 &#xff08;dfs思维&…

蓝桥杯每日一题2023.9.30

蓝桥杯大赛历届真题 - C&C 大学 B 组 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 对于此题&#xff0c;首先想到了dfs进行一一找寻&#xff0c;注意每次不要将重复的算进去&#xff0c;故我们每次循环可以记录一个开始的位置&#xff0c;下一次到这个位置时&#xff0c;…