本文源碼見:https://github.com/get-set/get-designpatterns/tree/master/strategy前端
策略(Strategy)模式是對算法的一種封裝,是把使用算法的責任和算法自己分割開來,委託給不一樣的對象管理,從而能夠實現算法的互換,從而一個類的行爲或其算法能夠在運行時更改,這種設計模式屬於行爲型模式。java
策略模式在生活中和架構設計中很是常見。git
咱們用一個簡單的計算的例子來闡述這種模式。需求很簡單,提供兩個數字,給出這兩個數字的加減乘除的結果。github
在這裏,加減乘除就是不一樣的策略,咱們統一用Operation
抽象。算法
Operation.java編程
public interface Operation { int calculate(int x, int y); }
AddOperation.java設計模式
public class AddOperation implements Operation { public int calculate(int x, int y) { return x + y; } }
SubOperation.java架構
public class SubOperation implements Operation { public int calculate(int x, int y) { return x - y; } }
MulOperation.java框架
public class MulOperation implements Operation { public int calculate(int x, int y) { return x * y; } }
MulOperation.javaide
public class DivOperation implements Operation { public int calculate(int x, int y) { return x / y; } }
咱們的計算器比較舊,來自上世紀,就像插卡遊戲機,須要先設定計算方法,而後才能進行計算。
Calculator.java
public class Calculator { private Operation operation; public Calculator(Operation operation) { this.operation = operation; } public void setOperation(Operation operation) { this.operation = operation; } public int calculate(int x, int y) { return operation.calculate(x, y); } }
下面咱們用一下這個計算器:
Client.java
public class Client { public static void main(String[] args) { int x = 6, y = 3; Calculator calculator = new Calculator(new AddOperation()); System.out.println("6+3=" + calculator.calculate(x, y)); calculator.setOperation(new SubOperation()); System.out.println("6-3=" + calculator.calculate(x, y)); calculator.setOperation(new MulOperation()); System.out.println("6*3=" + calculator.calculate(x, y)); calculator.setOperation(new DivOperation()); System.out.println("6/3=" + calculator.calculate(x, y)); } }
輸出以下:
6+3=9 6-3=3 6*3=18 6/3=2
策略模式是如何作到隨意切換的呢?很顯然,仍然是採用了面向接口編程的思路,全部的策略都實現了一樣的接口,策略消費者只須要基於接口調用便可,不一樣的接口實現提供了不一樣的策略。這也是「歷史替換原則」的具體體現。
在具體的開發中,策略模式的例子常常見到:
ViewResolver
的接口,若是是JSP的渲染方法,那麼就使用InternalResourceViewResolver
;若是是Thymeleaf的渲染方法,就配置使用ThymeleafViewResolver
。Comparable
和Comparator
兩個接口的應用,也是理解策略模式的好思路。對於Comparable
來講,其應用於被比較的對象上,從接口方法int compareTo(T o);
能夠看出,是由當前對象調起的與另外一個對象的比較;而Comparator
接口的用於比較的接口方法爲int compare(T o1, T o2);
,不一樣點在於參數個數,一個Comparator
是獨立於o1
和o2
兩個被比較對象以外的第三方,所以作到了排序算法與調用算法的解耦,不一樣的Comparator
實現就是不一樣的策略,可見Comparator
的應用方式是策略模式。最後總結一下策略模式的使用場景:一、若是在一個系統裏面有許多類,它們之間的區別僅在於它們的行爲,那麼使用策略模式能夠動態地讓一個對象在許多行爲中選擇一種行爲。 二、一個系統須要動態地在幾種算法中選擇一種。 三、若是一個對象有不少的行爲,若是不用恰當的模式,這些行爲就只好使用多重的條件選擇語句來實現。