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

再探设计模式

  • 一、背景介绍
  • [二、 思路方案](#二、 思路方案)
  • 三、过程
    • [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. 学习是一个反复的过程:通过项目切实的需求来结合具体的设计模式,在反过来在此基础上优化设计模式。
相关推荐
极光雨雨28 分钟前
【设计模式】单例模式 饿汉式单例与懒汉式单例
单例模式·设计模式
贱贱的剑4 小时前
2.单例模式
单例模式·设计模式
Your易元7 小时前
设计模式-模板方法模式
java·设计模式·模板方法模式
暴走的海鸽9 小时前
存储库模式赋能 Django:让你的代码不那么业余,更具生命力
python·设计模式·django
小张在编程11 小时前
Java设计模式实战:备忘录模式与状态机模式的“状态管理”双雄
java·设计模式·备忘录模式
小小寂寞的城1 天前
JAVA观察者模式demo【设计模式系列】
java·观察者模式·设计模式
花好月圆春祺夏安1 天前
基于odoo17的设计模式详解---备忘模式
数据库·设计模式
DKPT1 天前
Java设计模式之行为型模式(责任链模式)介绍与说明
java·笔记·学习·观察者模式·设计模式
使一颗心免于哀伤1 天前
《设计模式之禅》笔记摘录 - 6.原型模式
笔记·设计模式
流星先生!1 天前
策略模式实现
策略模式