设计模式再探——策略模式

目录

一、背景介绍

最近在做产品的过程中,对于主题讨论回复内容,按照追评次数排序、点赞排序、时间排序等内容做了深入研究,通过策略模式可以很好的进行优化。

二、思路&方案

  • 1.策略模式简介
  • 2.策略模式的类图
  • 3.策略模式代码
  • 4.策略模式还可以优化的地方
  • 5.策略模式的例子改造

三、过程

1.策略模式简介

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

2.策略模式的类图

3.策略模式代码

java 复制代码
package mark.strategy;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:44
 */
public abstract class Strategy {
    public abstract void Algorithmlnterface();
}
java 复制代码
package mark.strategy;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:46
 */
public class ConcreteStrategyA extends Strategy{
    @Override
    public void Algorithmlnterface() {
        System.out.println("算法A的具体实现");
    }
}
java 复制代码
package mark.strategy;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:47
 */
public class ConcreteStrategyB extends Strategy{
    @Override
    public void Algorithmlnterface() {
        System.out.println("算法B的具体实现");
    }
}
java 复制代码
package mark.strategy;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:47
 */
public class ConcreteStrategyC extends Strategy{
    @Override
    public void Algorithmlnterface() {
        System.out.println("算法C的具体实现");
    }
}
java 复制代码
package mark.strategy;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:45
 */
public class Context {
    private Strategy strategy;

    Context(Strategy strategy){
        this.strategy = strategy;
    }
    public void ContextInterafce(){
        strategy.Algorithmlnterface();
    }
}
java 复制代码
package mark.strategy;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:48
 */
public class Client {
    public static void main(String[] args) {
        Context context;
        context = new Context(new ConcreteStrategyA());
        context.ContextInterafce();

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

        context = new Context(new ConcreteStrategyC());
        context.ContextInterafce();

    }
}

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

策略模式后续进行策略的扩充,需要修改客户端代码;对于客户端而言未满足开闭原则。

5.策略模式的例子改造(配置文件+反射)

java 复制代码
package mark.strategy.transform;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:44
 */
public abstract class Strategy {
    public abstract void Algorithmlnterface();
}
java 复制代码
package mark.strategy.transform;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:46
 */
public class ConcreteStrategyA extends Strategy {
    @Override
    public void Algorithmlnterface() {
        System.out.println("算法A的具体实现");
    }
}
java 复制代码
package mark.strategy.transform;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:47
 */
public class ConcreteStrategyB extends Strategy {
    @Override
    public void Algorithmlnterface() {
        System.out.println("算法B的具体实现");
    }
}
java 复制代码
package mark.strategy.transform;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:47
 */
public class ConcreteStrategyC extends Strategy {
    @Override
    public void Algorithmlnterface() {
        System.out.println("算法C的具体实现");
    }
}
java 复制代码
package mark.strategy.transform;

import java.util.HashMap;
import java.util.Map;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:45
 */
public class Context {

    //将这个数据放到配置文件中
    static Map<String,String> config = new HashMap<>();
    static Map<String,Strategy> configBean = new HashMap<>();
    static {
        config.put("strategyA","mark.strategy.transform.ConcreteStrategyA");
        config.put("strategyB","mark.strategy.transform.ConcreteStrategyB");
        config.put("strategyC","mark.strategy.transform.ConcreteStrategyC");
        //预加载提前做好的策略
        for (Map.Entry<String,String> entry:config.entrySet()) {
            Class strategyClass = null;
            try {
                strategyClass = Class.forName(entry.getValue());
                configBean.put(entry.getKey(),(Strategy)strategyClass.newInstance());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }
    }

    private Strategy strategy;

    Context(String type){
        try {
            if(configBean.containsKey(type)){
                this.strategy = configBean.get(type);
            }else {
                Class strategyClass = Class.forName(config.get(type));
                this.strategy = (Strategy)strategyClass.newInstance();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public void ContextInterafce(){
        strategy.Algorithmlnterface();
    }
}
java 复制代码
package mark.strategy.transform;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:48
 */
public class Client {
    public static void main(String[] args) {
        Context context;
        //前端通过下拉框选择不同的类型;下拉框中的值,也是通过配置文件进行读取的
        context = new Context("strategyA");
        context.ContextInterafce();
        context = new Context("strategyB");
        context.ContextInterafce();
        context = new Context("strategyC");
        context.ContextInterafce();
    }
}

四、总结

1.通过知识的综合运用,使得软件工程落地更加明确

2.何时使用策略:单一入口,单一出口的情况下;内部需要根据不同条件进行不同策略执行的时候使用

3.对策略模式概念的深度理解:算法家族=Strategy父类、分别封装起来=子类、让它们之间可以相互替换,算法的变化=多态、不会影响到使用算法的客户端=客户端满足开闭原则但是不太彻底

五、升华

原则是用来严格遵守的,变是永远不变的。

相关推荐
小湘西3 小时前
拓扑排序(Topological Sort)
python·设计模式
蜜獾云7 小时前
设计模式之观察者模式:监听目标对象的状态改变
观察者模式·设计模式·rxjava
知无不研7 小时前
中介者模式
c++·设计模式·中介者模式
badhope7 小时前
OpenClaw卸载命令全解析
java·linux·人工智能·python·sql·数据挖掘·策略模式
bmseven8 小时前
大白话讲解23种设计模式简介
设计模式
蜜獾云8 小时前
设计模式之代理模式:本地接口代理远程接口的调用
设计模式·系统安全·代理模式
蜜獾云8 小时前
设计模式之访问者模式:动态的给目标对象增加新功能
设计模式·访问者模式
蜜獾云10 小时前
设计模式之策略模式:替换掉糟糕的if else语句实现面向对象编程而非面向过程
设计模式·策略模式
蜜獾云10 小时前
设计模式之状态模式:封装数据的状态流转逻辑
设计模式·状态模式
Serene_Dream10 小时前
深度解析设计模式:单例模式(Singleton Pattern)
单例模式·设计模式