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

再探设计模式

  • 一、背景介绍
  • [二、 思路方案](#二、 思路方案)
  • 三、过程
    • [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. 学习是一个反复的过程:通过项目切实的需求来结合具体的设计模式,在反过来在此基础上优化设计模式。
相关推荐
春风十里不如你95273 小时前
【设计模式】【结构型模式(Structural Patterns)】之代理模式(Proxy Pattern)
设计模式·代理模式
请你打开电视看看6 小时前
观察者模式
java·观察者模式·设计模式
Mr.朱鹏6 小时前
设计模式之策略模式-工作实战总结与实现
java·spring·设计模式·kafka·maven·策略模式·springbbot
春风十里不如你95277 小时前
【设计模式】【结构型模式(Structural Patterns)】之组合模式(Composite Pattern)
设计模式·组合模式
捕鲸叉7 小时前
C++设计模式之组合模式实践原则
c++·设计模式·组合模式
阿熊不会编程7 小时前
【计网】自定义协议与序列化(一) —— Socket封装于服务器端改写
linux·开发语言·网络·c++·设计模式
春风十里不如你95277 小时前
【设计模式】【行为型模式(Behavioral Patterns)】之责任链模式(Chain of Responsibility Pattern)
java·设计模式·责任链模式
博风8 小时前
设计模式:11、迭代器模式(游标)
设计模式·迭代器模式
春风十里不如你95279 小时前
【设计模式】【行为型模式(Behavioral Patterns)】之命令模式(Command Pattern)
设计模式·命令模式
岳轩子12 小时前
23种设计模式之原型模式
设计模式·原型模式