策略模式

简介: 策略模式标签 : Java与设计模式 策略模式: 定义一系列的算法, 将其一个个封装起来, 并使它们可相互替换, 使得算法可独立于使用它的客户而变化.

策略模式

标签 : Java与设计模式


策略模式: 定义一系列的算法, 将其一个个封装起来, 并使它们可相互替换, 使得算法可独立于使用它的客户而变化.

(图片来源: 设计模式: 可复用面向对象软件的基础)
策略模式对应于解决某一问题的一个算法族, 允许用户从该算法族中任选一个算法解决该问题, 同时可以方便的更换算法或者增加新的算法. 并由客户端决定调用哪个算法(核心: 分离算法, 选择实现).


模式实现

案例: 商场打折 -策略可以简单分为: 原价购买、满减、返利三种策略:


Strategy

抽象策略: 定义算法族中所有算法的公共接口, Context使用这个接口来调用ConcreteStrategy定义的算法:

/**
 * @author jifang
 * @since 16/8/29 下午7:43.
 */
public interface Strategy {

    double acceptCash(double money);
}

ConcreteStrategy

具体策略: 以Strategy接口实现某具体算法或行为:

// 正常收费
class Normal implements Strategy {

    @Override
    public double acceptCash(double money) {
        return money;
    }
}

// 打折收费
class Discount implements Strategy {

    private double rate;

    public Discount(double rate) {
        if (rate > 1.0) {
            throw new RuntimeException("折扣力度怎么能大于1.0?");
        }
        this.rate = rate;
    }

    @Override
    public double acceptCash(double money) {
        return money * rate;
    }
}

// 返利收费
class Rebate implements Strategy {

    private double cashState;

    private double cashReturn;

    public Rebate(double cashState, double cashReturn) {
        this.cashState = cashState;
        this.cashReturn = cashReturn;
    }

    @Override
    public double acceptCash(double money) {
        if (money > cashState) {
            money -= Math.floor(money / cashState) * cashReturn;
        }
        return money;
    }
}

Context

  • 上下文:
    • 维护一个Strategy对象的引用;
    • 定义一个接口让Strategy访问它的数据;
public class Context {

    private Strategy strategy;

    public void setStrategy(Type type, double... args) {
        if (type == Type.NORMAL) {
            strategy = new Normal();
        } else if (type == Type.DISCOUNT) {
            strategy = new Discount(args[0]);
        } else if (type == Type.REBATE) {
            strategy = new Rebate(args[0], args[1]);
        }
    }

    public double getResult(double money) {
        return strategy.acceptCash(money);
    }

    public enum Type {
        NORMAL(0, "正常"),
        DISCOUNT(1, "打折"),
        REBATE(2, "返利");

        private int value;

        private String desc;

        Type(int value, String desc) {
            this.value = value;
            this.desc = desc;
        }
    }
}

注: 将客户端需要选择具体Strategy的任务交给Context完成:
基础策略模式中,选择所用具体Strategy实现的职责由Client承担, 并将其传递给Context, 这种方案对Client的负担较重, 因此将Context简单工厂融合, 选择算法实现的工作改由Context负责.

  • Client
    仅与Context交互: 通常有一系列的ConcreteStrategy可供选择.
public class Client {

    @Test
    public void client() {
        double money = 1000;
        Context context = new Context();
        context.setStrategy(Context.Type.NORMAL);
        System.out.println("原价: [" + context.getResult(money) + "]");


        context.setStrategy(Context.Type.REBATE, 100, 20);
        System.out.println("满100返20: [" + context.getResult(money) + "]");

        context.setStrategy(Context.Type.DISCOUNT, 0.8);
        System.out.println("6折优惠: [" + context.getResult(money) + "]");
    }
}

小结

  • 作用

    • 析取算法: Strategy接口为Context定义了一个可重用的算法/行为, 继承/实现其有助于析取出算法族的公共功能, 且可减少算法与Client间的耦合.
    • 消除条件语句: 避免将不同行为堆砌在一个类中, 将行为封装在独立的Strategy实现中, 可在Client中消除条件语句.
    • 简化单元测试: 每个算法都有自己的类, 可以单独测试.
  • 场景

    • 当使用一个算法的不同变体, 且这些变体可以实现为一个算法族时;
    • 算法的客户不需要知晓其内部数据, 策略模式可以避免暴露复杂的、与算法相关的数据结构;
    • 一个类定义了多种行为, 且这些行为以多个条件语句形式出现, 可将相关行为各自的Strategy(如: Servlet-api service()方法).
  • 相关模式
    Flyweight: Strategy对象经常是很好的轻量级对象.


目录
相关文章
|
4月前
|
算法 数据安全/隐私保护
行为型 策略模式
行为型 策略模式
18 1
|
8月前
|
设计模式 算法 Java
什么场景要使用策略模式,什么场景不能使用?
如果,让我来设计,我最先想到的就是策略模式。另外,我把往期面试题解析的配套文档我已经准备好,想获得的可以在我的煮叶简介中找到。那么什么场景要使用策略模式,什么场景又不应该使用策略模式呢?我们可以先来看官方对策略模式的定义。
108 0
|
8月前
|
前端开发
策略模式
策略模式
53 0
|
9月前
|
设计模式 算法
策略模式详细介绍
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列的算法,并将每个算法封装到具有共同接口的独立类中,使得它们可以互相替换。策略模式可以让算法的变化独立于使用它的客户端。
94 0
|
9月前
|
算法 测试技术 C#
C#策略模式
C#策略模式
40 0
|
10月前
|
设计模式 前端开发
关于策略模式我所知道的
关于策略模式我所知道的
56 0
|
10月前
|
算法 程序员 开发工具
简单说说我对策略模式的了解
简单说说我对策略模式的了解
62 0
|
设计模式 算法
我学会了,策略模式
策略模式属于行为型模式,这个类型的设计模式总结出了 类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,花式的去使用对象的行为来完成特定场景下的功能。
96 0
我学会了,策略模式