1

一、什么是策略模式(What)?

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

翻译成人话:对变化的参数 运行 对应的程序。会联想到:if(...){..}else if(...){}... ,但if-else用的多了,程序可读性和维护程度就大大下降。

二、为什么要用策略模式(Why)?

就是为了解决多层if-else判断嵌套的头疼问题,一个问题对应一个策略。

三、怎么使用策略模式(How)?

这里直接用一个 大家熟悉的 “淘宝活动折扣”为例。不同活动期间,对总价(money)进行不同的折扣计算最终应付款(dues)。代码如下:

1. 应付款 抽象类

abstract class ActivityAbstract {
    /**
     * 活动期应付款
     *
     * @param money 原价
     * @return 折扣后应付款
     */
    public abstract double dues(double money);
}

2. 多个不同活动 应付款子类

(1)正常时期 应付款类

public class ActivityNormal extends ActivityAbstract {
    /**
     * 活动期应付款
     *
     * @param money 原价
     * @return 折扣后应付款
     */
    @Override
    public double dues(double money) {
        // 原价
        return money;
    }
}

(2)618年中大促 应付款类

public class Activity0618 extends ActivityAbstract {
    /**
     * 活动期应付款
     *
     * @param money 原价
     * @return 折扣后应付款
     */
    @Override
    public double dues(double money) {
        // 满500元 减少 50元
        if (money >= 500) {
            money = money - 50;
        }
        return money;
    }
}

(3)双11活动 应付款类

public class Activity1111 extends ActivityAbstract {
    /**
     * 活动期应付款
     *
     * @param money 原价
     * @return 折扣后应付款
     */
    @Override
    public double dues(double money) {
        // 全场半价
        return money / 2;
    }
}

3. 活动上下文分析 类

public class ActivityContext {
    private ActivityAbstract activity = null;

    /**
     * 根据活动类型 构造 对应的 活动类
     *
     * @param type 活动类型
     */
    public ActivityContext(String type) {
        switch (type) {
            case "AC_0618":
                activity = new Activity0618();
                break;
            case "AC_1111":
                activity = new Activity1111();
                break;
            default:
                activity = new ActivityNormal();
        }
    }

    /**
     * 从对应的活动,获取 应付款
     *
     * @param money 原价
     * @return 应付款
     */
    public double getDues(double money) {
        return activity.dues(money);
    }

}

4. 运行调用

public class RunTest {
    public static void main(String[] args) {
        // 模拟一个 原价
        double money = 600;

        // 正常:原价
        ActivityContext context1 = new ActivityContext("AC_NORMAL");
        double moneyNormal = context1.getDues(money);
        System.out.println("正常时期 应付款:" + moneyNormal);

        // 618年中大促:满500减50
        ActivityContext context2 = new ActivityContext("AC_0618");
        double money0618 = context2.getDues(money);
        System.out.println("618年中大促 应付款:" + money0618);

        // 双11活动:半价
        ActivityContext context3 = new ActivityContext("AC_1111");
        double money1111 = context3.getDues(money);
        System.out.println("双11活动 应付款:" + money1111);


    }
}

最终输出结果

正常时期应付款:600.0
618年中大促应付款:550.0
双11活动应付款:300.0

总结

优点

1、算法可以自由切换。
2、避免使用多重条件判断。
3、扩展性良好

缺点

1、策略类会增多。 子类5个以上就不推荐这种模式了。
2、所有策略类都需要对外暴露。

再回去看前面的What,Why,How。

转载 请注明出处 思否-是大尧啊 https://segmentfault.com/u/dayaocool


是大尧啊
6 声望0 粉丝

谋其上,而得其中;谋其中,而得其下。