Strategy Pattern -- 策略模式

什麼是策略模式?

策略模式(Strategy Pattern):定義一系列算法,將每個算法封裝起來,並讓它們能夠相互替換。策略模式讓算法獨立於使用它的客戶而變化,也稱爲政策模式(Policy)。 算法

在軟件開發過程當中,咱們經常會遇到這樣一種狀況:爲了實現某一種功能,咱們有多種實現方式,算法或者策略。好比對於查找算法來講,要提供多種查找算法,能夠將這些算法寫到一個類中,在該類中提供多個方法,每個方法對應一個具體的查找算法;固然也能夠將這些查找算法封裝在一個統一的方法中,經過if…else…或者case等條件判斷語句來進行選擇。若是須要增長一種新的查找算法,須要修改封裝算法類的源代碼;更換查找算法,也須要修改客戶端調用代碼。在這個算法類中封裝了大量查找算法,該類代碼將較複雜,維護較爲困難。若是咱們將這些策略包含在客戶端,這種作法更不可取,將致使客戶端程序龐大並且難以維護,若是存在大量可供選擇的算法時問題將變得更加嚴重。安全

組織結構

下面來看一下策略模式的具體組成bash

  • 環境類(Context):也叫上下文,對策略進行二次封裝,目的是避免高層模塊對策略的直接調用。
  • 抽象策略類(Strategy):一般狀況下爲一個接口,當各個實現類中存在着重複的邏輯時,則使用抽象類來封裝這部分公共的代碼,此時,策略模式看上去更像是模版方法模式。
  • 具體策略類(ConcreteStrategy):具體策略角色一般由一組封裝了算法的類來擔任,這些類之間能夠根據須要自由替換。

For example數據結構

首先咱們須要定義咱們的抽象策略,將接口、公共代碼部分封裝在這裏ide

public interface Strategy {
	public void operater();
}
複製代碼

而後咱們根據具體需求,去實現對應策略類函數

public class strateyA implements Strategy {
	@Override
	public void operater() {
	//  策略 A 的執行方式
	}
}

public class strateyB implements Strategy {
	@Override
	public void operater() {
	//  策略 B 的執行方式
	}
}
複製代碼

在經過環境類去進行二次封裝,從中能夠看到能夠經過構建函數來決定使用哪一條策略,也能夠經過 setStrategy 方法,去改變因此使用的策略,而且執行的爲對應策略中所實現的方法。ui

public class Context {
	private Strategy strategy;

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

	public void setStrategy(Strategy strategy) {
	    this.strategy = strategy;
	}

	public void operater() {
	    this.strategy.operater();
	}
}
複製代碼

接下來看一下調用者的具體調用this

public class Client {
    public static void main(String[] args) {
        Context context;

    // 我想使用第一個策略
	context = new Context(new strateyA());
	context.operater();

	// 條件改變了,我想使用第二個策略
	context.setStrategy(new strateyB());
	context.operater();
    }
}
複製代碼

優勢與缺點

優勢

  • 策略模式提供了對「開閉原則」的完美支持,用戶能夠在不修改原有系統的基礎上選擇算法或行爲,也能夠靈活地增長新的算法或行爲。
  • 策略模式提供了管理相關的算法族。
  • 策略模式提供了能夠替換繼承關係的方式。
  • 使用策略模式能夠避免使用多重條件轉移語句。

缺點

  • 客戶端必須知道全部的策略類,並自行決定使用哪個策略類。
  • 策略模式將形成產生不少策略類,增長了工程類數目(這個問題能夠經過享元模式在必定程度上緩解)

適用狀況

  • 若是在一個系統裏面有許多類,它們之間的區別僅在於它們的行爲,那麼使用策略模式能夠動態地讓一個對象在許多行爲中選擇一種行爲。
  • 一個系統須要動態地在幾種算法中選擇一種。
  • 若是一個對象有不少的行爲,若是不用恰當的模式,這些行爲就只好使用多重的條件選擇語句來實現。
  • 不但願客戶端知道複雜的、與算法相關的數據結構,在具體策略類中封裝算法和相關的數據結構,提升算法的保密性與安全性。

策略模式與狀態模式對比

  • 能夠經過環境類狀態的個數來決定是使用策略模式仍是狀態模式。
  • 策略模式的環境類本身選擇一個具體策略類,具體策略類無須關心環境類;而狀態模式的環境類因爲外在因素須要放進一個具體狀態中,以便經過其方法實現狀態的切換,所以環境類和狀態類之間存在一種雙向的關聯關係。
  • 使用策略模式時,客戶端須要知道所選的具體策略是哪個,而使用狀態模式時,客戶端無須關心具體狀態,環境類的狀態會根據用戶的操做自動轉換。
  • 若是系統中某個類的對象存在多種狀態,不一樣狀態下行爲有差別,並且這些狀態之間能夠發生轉換時使用狀態模式;若是系統中某個類的某一行爲存在多種實現方式,並且這些實現方式能夠互換時使用策略模式

總結

策略模式主要就是爲了分離算法和使用,使系統有很好的拓展性spa

策略模式是一種簡單經常使用的模式,咱們在進行開發的時候,會常常有意無心地使用它,通常來講,策略模式不會單獨使用,跟模版方法模式、工廠模式等混合使用的狀況比較多。code

Article by 夏風_Me

相關文章
相關標籤/搜索