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

一、背景介绍

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

二、思路&方案

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

三、过程

1.策略模式简介

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

2.策略模式的类图

在这里插入图片描述

3.策略模式代码

package mark.strategy;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:44
 */
public abstract class Strategy {
    
    
    public abstract void Algorithmlnterface();
}

package mark.strategy;

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

package mark.strategy;

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

package mark.strategy;

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

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();
    }
}

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.策略模式的例子改造(配置文件+反射)

package mark.strategy.transform;

/**
 * 功能描述:
 *
 * @Author:makang
 * @Date: 2021/5/29 14:44
 */
public abstract class Strategy {
    
    
    public abstract void Algorithmlnterface();
}

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的具体实现");
    }
}

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的具体实现");
    }
}

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的具体实现");
    }
}

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();
    }
}

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父类、分别封装起来=子类、让它们之间可以相互替换,算法的变化=多态、不会影响到使用算法的客户端=客户端满足开闭原则但是不太彻底

五、升华

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

猜你喜欢

转载自blog.csdn.net/u013030601/article/details/132265959