Home 策略模式
Post
Cancel

策略模式

Strategy Pattern 对象行为型模式

意图

定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。此模式使得算法可以独立于使用它们的客户而变化

结构

策略模式

其中:

  • Strategy (策略) 定义所有支持的算法的公共接口。Context 使用这个接口来调用某 ConcreteStrategy 定义的算法

  • ConcreteStrategy (具体策略) 以 Strategy 接口实现某具体算法

  • Context (上下文) 用一个 ConcreteStrategy 对象来配置;维护一个对 Strategy 对象的引用;可定义一个接口来让 Strategy 访问它的数据

适用性

Strategy 模式适用于:

  • 许多相关的类仅仅是行为有异。”策略” 提供了一种用多个行为中的一个行为来配置一个类的方法

  • 需要使用一个算法的不同变体。例如,定义一些反映不同空间的空间/时间权衡的算法。当这些变体实现为一个算法的类层次吋,可以使用策略模式

  • 算法使用客户不应该知道的数裾。可使用策略模式以避免暴露复杂的、与算法相关的数据结构

  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,将相关的条件分支移入它们各自的 Strategy 类中,以代替这些条件语句

例子 1

某大型购物中心欲开发一套收银软件,要求其能够支持购物中心在不同时期推出的各种促销活动,如打折、返利 (例如,满300返100) 等等。现采用策略模式实现该要求,所设计的类图如下所示

策略模式-例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.util.*;

enum TYPE { NORMAL, CASH_DISCOUNT, CASH_RETURN};

interface CashSuper {
    public double acceptCash(double money);
}

class CashNormal implements CashSuper { // 正常收费子类
    public double acceptCash(double money) {
        return money;
    }
}
class CashDiscount implements CashSuper {
    private double moneyDiscount; // 折扣率
    public CashDiscount(double moneyDiscount) {
        this moneyDiscount = moneyDiscount;
    }
    public double acceptCash(double money) {
        return money* moneyDiscount;
    }
}

class CashReturn implements CashSuper { // 满额返利
    private double moneyCondition;
    private double moneyReturn;
    public CashReturn(double moneyCondition, double moneyReturn) {
        this.moneyCondition = moneyCondition; // 满额数额
        this.moneyReturn = moneyReturn; // 返利数额
    }
    public double acceptCash(double money) {
        double result = money;
        if(money >= moneyCondition )
            result = money - Math.floor(money / moneyCondition) * moneyReturn;
        return result;
    }
}

class CashContext {
    private CashSuper cs;
    private TYPE t;
    public CashContext(TYPE t) {
        switch(t) {
            case NORMAL: // 正常收费
                cs = new CashNormal();
                break;
            case CASH_DISCOUNT: // 打8折
                cs = new CashDiscount(0.8);
                break;
            case CASH_RETURN: // 满300返100
                cs = new CashReturn(300, 100);
                break;
        }
    }
    public double GetResult(double money) {
        return cs.acceptCash(money);
    }
// 此处略去main()函数
}

例子 2

加减乘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class StrategyPattern {
    public static void main(String[] args) {
        Strategy add = new AddStrategy();
        Strategy subtraction = new SubtractionStrategy();
        Strategy multiply = new MultiplyStrategy();

        OperationContext context = new OperationContext(add);
        context.Operation(1, 2);

        context = new OperationContext(subtraction);
        context.Operation(1, 2);

        context = new OperationContext(multiply);
        context.Operation(1, 2);
    }
}

class OperationContext{
    private Strategy strategy;

    public OperationContext(Strategy strategy){
        this.strategy = strategy;
    }

    public void Operation(int a, int b){
        strategy.operation(a, b);
    }

}

interface Strategy{
    public void operation(int a, int b);
}

class AddStrategy implements Strategy{
    @Override
    public void operation(int a, int b){
        System.out.println(a + b);
    }
}

class SubtractionStrategy implements Strategy{
    @Override
    public void operation(int a, int b){
        System.out.println(a - b);
    }
}

class MultiplyStrategy implements Strategy{
    @Override
    public void operation(int a, int b){
        System.out.println(a * b);
    }
}
This post is licensed under CC BY 4.0 by the author.

状态模式

模板方法模式