1 概述
策略模式(Strategy Pattern)是行爲模式的一種,複雜度並不高,當完成某項任務的方式有多種時,可以考慮使用策略模式。
2 策略模式
在策略模式中,我們需要定義一族算法,並將算法放入獨立的類中,每種算法代表完成任務的一種方法。如計算器,我們可以定義基本的加,減,乘,除四種策略,對於任意輸入的兩個數字,調用不同的策略,將得到不同的結果;又如網上購物結算,我們可以定義一系列支付策略,支付寶支付,微信支付,信用卡支付,儲值卡支付…顧客可以根據自己的喜好選擇相應的支付方式。
策略模式解耦了算法的實現和定義。新引入策略,無需對現有邏輯進行修改,符合開閉原則。
3 案例
用一個案例來說明。對於上班族來說,上班方式有多種,可以開車,可以騎自行車,也可以坐公共交通。不同人有不同的選擇,甚至對於同一個人,今天和明天的選擇也會不一樣,如果將上班方式維護在上班族這個類的內部,邏輯將會比較複雜。下面來看,通過策略模式將上班方式抽離出來,如何簡化代碼邏輯:
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 BusStrategy("Tesla");
Worker yoshi = new Worker("Yoshi");
yoshi.goToWork(carStrategy);
}
}
輸出:
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.
Taking the bus with traffic card 'Tesla'...
Yoshi is on the way to office.
通過定義一個抽象層TransportationStrategy
,使得代碼結構清晰,組件之間的耦合度也很低。選擇不同的策略類,便能完成相應的功能。
我們最熟悉的例子,應該是JDK
中的Collections.sort()方法,該方法可以根據傳入的Comparator
的不同,將List
按不同的算法排序,其中Comparator
就是策略。
4 總結
合理地運用策略模式,可以降低系統的複雜度。當一個類包含了多種行爲,表現爲多個if
分支時,可以考慮用策略模式將每個行爲做成一個策略類。