Java設計模式百例 - 策略模式

本文源碼見:https://github.com/get-set/get-designpatterns/tree/master/strategy前端

策略(Strategy)模式是對算法的一種封裝,是把使用算法的責任和算法自己分割開來,委託給不一樣的對象管理,從而能夠實現算法的互換,從而一個類的行爲或其算法能夠在運行時更改,這種設計模式屬於行爲型模式。java

策略模式在生活中和架構設計中很是常見。git

  • 好比,商場打折,對於一樣一類商品,不一樣的時間,促銷方式和打折力度是不一樣的,這時候,促銷方式和打折力度就是策略,對於這種應用場景來講,策略須要是能夠隨時變動的。
  • 還有個例子,好比排序,不一樣的對象,其排序依據不一樣。對於學生而言,有時候根據身高排序安排坐位,有時候根據成績排序安排考場,這時候把這兩種排序方式獨立出來是一種比較好的方法,當須要安排坐位時,就使用「按照身高排序」的策略,當須要安排考場時就使用「按照成績排序」的策略。從而一旦有新的需求和新的策略,只須要變動另一個策略(好比「按年齡排序」)就OK了。
  • 再舉個例子,說到插卡遊戲機,估計很多朋友沒見過,80後仍是有印象的,遊戲機自己不能玩,須要再購買不一樣的遊戲卡插上才能玩,好比魂鬥羅、超級瑪麗等等。

例子

咱們用一個簡單的計算的例子來闡述這種模式。需求很簡單,提供兩個數字,給出這兩個數字的加減乘除的結果。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

總結

策略模式是如何作到隨意切換的呢?很顯然,仍然是採用了面向接口編程的思路,全部的策略都實現了一樣的接口,策略消費者只須要基於接口調用便可,不一樣的接口實現提供了不一樣的策略。這也是「歷史替換原則」的具體體現。

在具體的開發中,策略模式的例子常常見到:

  • 咱們在使用SpringMVC開發的時候,前端頁面的渲染可能採用不一樣的技術,好比JSP、Thymeleaf等,對於Spring框架來講,要可以接納不一樣的頁面渲染技術,所以提供了ViewResolver的接口,若是是JSP的渲染方法,那麼就使用InternalResourceViewResolver;若是是Thymeleaf的渲染方法,就配置使用ThymeleafViewResolver
  • Java中觀察ComparableComparator兩個接口的應用,也是理解策略模式的好思路。對於Comparable來講,其應用於被比較的對象上,從接口方法int compareTo(T o);能夠看出,是由當前對象調起的與另外一個對象的比較;而Comparator接口的用於比較的接口方法爲int compare(T o1, T o2);,不一樣點在於參數個數,一個Comparator是獨立於o1o2兩個被比較對象以外的第三方,所以作到了排序算法與調用算法的解耦,不一樣的Comparator實現就是不一樣的策略,可見Comparator的應用方式是策略模式。

最後總結一下策略模式的使用場景:一、若是在一個系統裏面有許多類,它們之間的區別僅在於它們的行爲,那麼使用策略模式能夠動態地讓一個對象在許多行爲中選擇一種行爲。 二、一個系統須要動態地在幾種算法中選擇一種。 三、若是一個對象有不少的行爲,若是不用恰當的模式,這些行爲就只好使用多重的條件選擇語句來實現。

相關文章
相關標籤/搜索