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

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

使用场景

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

代码示例

/**
 * 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();
     }
 }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我思知我在

原创不易,多多一键三连

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值