一文理解设计模式之–策略模式(Strategy)

导读:本篇文章讲解 一文理解设计模式之–策略模式(Strategy),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

首先定义一组算法,将每一个算法封装起来,从而使它们可以相互切换

使用场景

  • 同样的流程,需要执行不同的策略算法,传入不同策略,执行传入对应的策略算法

代码示例

/**
 * Context持有Strategy的引用,并提供了调用策略的方法,所以叫Context
 *
 * @author July
 * @date 2020/10/20
 */
public class Context {

    private Strategy strategy;

    /**
     * 传入策略
     *
     * @param strategy
     */
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    /**
     * 调用策略
     */
    public void execute() {
        strategy.algorithmLgic();
    }
}

/**
 * 抽象策略角色,定义了策略组的方法
 *
 * @author July
 * @date 2020/10/20
 */
public interface Strategy {

    /**
     * 算法逻辑
     */
    public void algorithmLgic();
}
/**
 * 策略A
 *
 * @author July
 * @date 2020/10/20
 */
public class ConcreteStrategyA implements Strategy {

    @Override
    public void algorithmLgic() {
        System.out.println("执行算法A");
    }
}

/**
 * 策略B
 *
 * @author July
 * @date 2020/10/20
 */
public class ConcreteStrategyB implements Strategy {

    @Override
    public void algorithmLgic() {
        System.out.println("执行算法B");
    }
}
/**
 * 客户端,调用策略
 *
 * @author July
 * @date 2020/10/20
 */
public class App {

    public static void main(String[] args) {
        // 根据传入的不同策略执行相应的策略算法
        Context context = new Context(new ConcreteStrategyA());
        context.execute();
    }
}

角色说明

在这里插入图片描述

  • 封装角色(Context):上层访问策略的入口,它持有着抽象策略对象的引用
  • 抽象策略角色(Strategy):提供接口或抽象类,定义策略组都需要拥有的方法和属性
  • 具体策略角色(ConcreteStrategyA、B):实现抽象策略,定义具体的算法逻辑

优缺点

优点

  • 策略模式提供了管理相关算法族的方法。策略类的等级结构定义了⼀个算法或⾏为族。恰当使⽤继承可以把公共的代码移到⽗类⾥⾯,从⽽避免代码重复。
  • 避免使用if-else多重条件语句,因为策略模式下可以动态传入需要的算法对象

缺点

  • 客户端(调用方)必须知道所有策略类,并自行决定使用哪种策略。这就意味着客户端必须理解所有算法的区别,以便需要的时候选择合适的算法。也就是说策略模式只适用于客户端知道所有算法的情况
  • 一个策略对应一个类,如果备选策略很多的话,类的数目就会很可观

高级用法

  • 传入的策略对象可以替换为类的全路径,通过反射来动态获取策略算法
        // 根据传入的不同策略执行相应的策略算法
        ContextReflect context = new ContextReflect ("com.siqi.strategy.ConcreteStrategyA");
        context.execute();
public class ContextReflect {
     Class<?> clazz = null;
     Object obj = null;
     public CashContextReflect(String className, Class[] paramsType, Object[] parmas){
         try {
             clazz = Class.forName(className);
             Constructor con = clazz.getConstructor(paramsType);
             obj = con.newInstance(parmas);
         } catch (InstantiationException | IllegalAccessException e) {
             e.printStackTrace();
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         } catch (IllegalArgumentException e) {
             e.printStackTrace();
         } catch (InvocationTargetException e) {
             e.printStackTrace();
         } catch (NoSuchMethodException e) {
             e.printStackTrace();
         } catch (SecurityException e) {
             e.printStackTrace();
         }
         
     }
     
     public double execute(){
         return ((Strategy)obj).algorithmLogic();
     }
 }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/17890.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!