设计模式11_策略模式

1、定义


          策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。

          策略模式:
              * 定义了一族算法(业务规则);
              * 封装了每个算法;
              * 这族的算法可互换代替(interchangeable)。

  摘自维基百科:(https://zh.wikipedia.org/wiki/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F)


2、说明

          策略模式属于对象的行为模式。它的目的是定义一系列算法,把它们一个个封装起来, 并且使得它们可相互替换。比如,代码中有很多算法夹在在一个方法中,或者有很多种情况需要处理,但使用的是if…else…进行处理。这样,时间长了代码就会发酵、腐烂,难以维护。比较好的解决方法是将这些算法分离开来,抽象出接口,使用一个context上下文来注入这个接口,使得在需要某一算法的时候,可以直接通过上下文去获取,降低了代码的复杂度,相应代码的可读性也会提高。
        策略模式的适用场景大致有:(1)如果很多相关的类仅仅是行为有异,“策略”则可以提供用行为来配置一个类的方法,即一个系统可按需动态在若干策略中进行选择;(2)需要对客户隐藏复杂的且与算法相关的数据结构;(3)类定义了多种行为,且这些行为在类中以多条件语句的形式出现。


3、角色

          环境角色(Context):持有对Strategy的引用。

          抽象策略角色(Strategy):通常由一个接口或抽象类实现,此角色给出所有的具体策略类所需的接口,并有具体策略类去实现。

          具体策略角色(ConcreteStrategy):包装了相关的算法或行为,需要实现抽象策略类。


4、类图

这里写图片描述


5、示例


/**
 * 策略接口类
 * @author liqqc
 *
 */
public interface IStrategy {

    /*
     * 获取价格
     */
    public double getPrice(double price);
}
/**
 * 
 * @author liqqc
 *
 */
public class Context {

    private IStrategy iStrategy;

    public Context(IStrategy strategy) {
        this.iStrategy = strategy;
    }

    public Double getQuota(Double price) {
        return this.iStrategy.getPrice(price);
    }
}
/**
 * 一般用户
 * @author liqqc
 *
 */
public class GeneralUser implements IStrategy {

    @Override
    public double getPrice(double price) {
        System.err.println("you are general user");
        return price;
    }

}
/**
 * 普通会员
 * @author liqqc
 *
 */
public class VipUser implements IStrategy {

    @Override
    public double getPrice(double price) {
        System.err.println("you are vip ,can get disaccount");
        return price * 0.9;
    }
}
/**
 * 高级会员
 * @author liqqc
 *
 */
public class HighVipUser implements IStrategy {

    @Override
    public double getPrice(double price) {
        System.err.println("you are high vip, can get a high discount");
        return price * 0.5;
    }
}
/**
 * 测试
 * @author liqqc
 *
 */
public class Main {


    public static void main(String[] args) {
        final Double price = 1000.0;

        //high vip 
        IStrategy highVipUser = new HighVipUser();
        Context context1 = new Context(highVipUser);
        Double discount1 = context1.getQuota(price);
        System.err.println("you need pay : " + discount1 + "RMB");

        System.err.println();

        //vip 
        IStrategy vipUser = new VipUser();
        Context context2 = new Context(vipUser);
        Double discount2 = context2.getQuota(price);
        System.err.println("you need pay : " + discount2 + "RMB");

        System.err.println();


        //general 
        IStrategy generalUser = new GeneralUser();
        Context context3 = new Context(generalUser);
        Double discount3 = context3.getQuota(price);
        System.err.println("you need pay : " + discount3 + "RMB");


    }

}

      运行结果:

you are high vip, can get a high discount
you need pay : 500.0RMB

you are vip ,can get disaccount
you need pay : 900.0RMB

you are general user
you need pay : 1000.0RMB

6、总结

          优点:(1)策略模式提供了一种管理相关类型算法的办法。其中,策略类的层级结构定义了若干算法或行为。如果能在其中恰当地使用抽象和继承,可以把公共的代码移到父类中,进而避免代码重复。(2)对于使用大量多重条件(if-else)的代码,使用策略模式可以很好地将其减少消除。由于多重条件语句难以维护,其将算法或行为的逻辑混合在一起,全包在一个多重条件语句里面,阅读起来也很费劲,在开发中应该减少多重条件的使用。

          缺点:(1)对于使用者而言,必须知道所有策略类,并按照需求决定使用哪一个策略类。也就意味使用者必须理解策略类(算法)间的异同,以便选择恰当的策略类,策略模式只适用于使用者知道(策略类)算法或行为的情况下使用。对对于一些特别复杂的算法,也不建议使用。(2)策略模式把具体策略实现都封装成为一个一个的类,如果可选的策略很多的话,那么策略类的数数量会很大,可能会难以维护。

          本文只是简单介绍了策略模式,并未对其进行深入探讨,略显粗糙。希望本文对你有所帮助。


  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值