行为模式之策略模式

Posted by Night Field's Blog on May 24, 2020

1 概述

策略模式(Strategy Pattern)是行为模式的一种,复杂度并不高,当完成某项任务的方式有多种时,可以考虑使用策略模式。

2 策略模式

策略模式中,我们需要定义一族算法,并将算法放入独立的类中,每种算法代表完成任务的一种方法。如计算器,我们可以定义基本的四种策略,对于任意输入的两个数字,调用不同的策略,将得到不同的结果;又如网上购物结算,我们可以定义一系列支付策略,支付宝支付微信支付信用卡支付储值卡支付…顾客可以根据自己的喜好选择相应的支付方式。

策略模式解耦了算法的实现和定义。新引入策略,无需对现有逻辑进行修改,符合开闭原则

3 案例

用一个案例来说明。对于上班族来说,上班方式有多种,可以开车,可以骑自行车,也可以坐公共交通。不同人有不同的选择,甚至对于同一个人,今天和明天的选择也会不一样,如果将上班方式维护在上班族这个类的内部,逻辑将会比较复杂。下面来看,通过策略模式上班方式抽离出来,如何简化代码逻辑:

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
60
61
62
63
public interface TransportationStrategy {
    void execute();
}

public class BikeStrategy implements TransportationStrategy {
    private String bike;
    BikeStrategy(String bike) {
        this.bike = bike;
    };
    @Override
    public void execute() {
        System.out.println("Riding the '" + bike + "'bike...");
    }
}

public class BusStrategy implements TransportationStrategy {
    private String trafficCard;
    BusStrategy(String trafficCard) {
        this.trafficCard = trafficCard;
    };
    @Override
    public void execute() {
        System.out.println("Taking the bus with traffic card '" + trafficCard + "'...");
    }
}

public class CarStrategy implements TransportationStrategy {
    private String car;
    CarStrategy(String car) {
        this.car = car;
    };
    @Override
    public void execute() {
        System.out.println("Driving the '" + car + "'car...");
    }
}

public class Worker {
    private String name;
    Worker(String name) {
        this.name = name;
    };
    public void goToWork(TransportationStrategy strategy) {
        strategy.execute();
        System.out.println(name + " is on the way to office.");
    }
}

public class Test {
    public static void main(String[] args) {
        TransportationStrategy BusStrategy = new BusStrategy("NO.9382-2345");
        Worker link = new Worker("Link");
        link.goToWork(BusStrategy);

        TransportationStrategy bikeStrategy = new BikeStrategy("Giant");
        Worker mario = new Worker("Mario");
        mario.goToWork(bikeStrategy);

        TransportationStrategy carStrategy = new CarStrategy("Tesla");
        Worker yoshi = new Worker("Yoshi");
        yoshi.goToWork(carStrategy);
    }
}

输出:

1
2
3
4
5
6
Taking the bus with traffic card 'NO.9382-2345'...
Link is on the way to office.
Riding the 'Giant'bike...
Mario is on the way to office.
Driving the 'Tesla'car...
Yoshi is on the way to office.

uml

通过定义一个抽象层TransportationStrategy,使得代码结构清晰,组件之间的耦合度也很低。选择不同的策略类,便能完成相应的功能。

我们最熟悉的例子,应该是JDK中的Collections.sort()方法,该方法可以根据传入的Comparator的不同,将List按不同的算法排序,其中Comparator就是策略

4 总结

合理地运用策略模式,可以降低系统的复杂度。当一个类包含了多种行为,表现为多个if分支时,可以考虑用策略模式将每个行为做成一个策略类。

文中例子的github地址