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

再探设计模式

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

一、背景介绍

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

二、 思路方案

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

三、过程

1. 策略模式基本概念

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

2. 策略模式类图

3. 策略模式基本代码

策略类

java 复制代码
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实现");
    }
}

抽象策略类

java 复制代码
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类

java 复制代码
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();
    }
}

客户端

java 复制代码
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. 对策略模式的优化(配置文件+反射)

java 复制代码
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实现");
    }
}
java 复制代码
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实现");
    }
}
java 复制代码
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实现");
    }
}
java 复制代码
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();
    }



}
java 复制代码
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();
}
java 复制代码
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. 学习是一个反复的过程:通过项目切实的需求来结合具体的设计模式,在反过来在此基础上优化设计模式。
相关推荐
Zane19946 天前
一个 new 就能创建对象,为什么还要拆出单例、工厂、建造者、原型四种模式?
设计模式
怕浪猫7 天前
一行命令复刻爆款视频,我把 Hypit 从安装跑到了出片
人工智能·设计模式·程序员
Zane19947 天前
函数式编程里的函数,其实不是你天天写的那个函数——三大编程范式的边界在哪
设计模式
Zane19948 天前
策略模式现在该不该上?一次讲清楚过度设计和设计不足怎么找平衡
设计模式
她说..8 天前
常见设计模式-模板方法模式
java·spring·设计模式·springboot
xiaofeiyang1509 天前
第六章 · 桥接 — 三支毛笔,画出九种颜色
设计模式
Shadow(⊙o⊙)9 天前
OTOL设计模式 One Thread One Loop
服务器·网络·设计模式
sarasuki10 天前
如何让LLM 能在半夜偷偷打开网易云呢?
人工智能·设计模式·agent
小王师傅6610 天前
【设计模式】装饰模式(四):框架源码实战——从 Java I/O 到 Spring 到 MyBatis
java·设计模式
执明wa10 天前
Android RecyclerView 多类型, 多种 Item
android·xml·开发语言·设计模式·android studio