23種設計模式(12):策略模式

定義:定義一組算法,將每一個算法都封裝起來,而且使他們之間能夠互換。 html

類型:行爲類模式 算法

類圖: 編程

23種設計模式(12):策略模式 - 第1張  | 快課網

策略模式是對算法的封裝,把一系列的算法分別封裝到對應的類中,而且這些類實現相同的接口,相互之間能夠替換。在前面說過的行爲類模式中,有一種模式也是關注對算法的封裝——模版方法模式,對照類圖能夠看到,策略模式與模版方法模式的區別僅僅是多了一個單獨的封裝類Context,它與模版方法模式的區別在於:在模版方法模式中,調用算法的主體在抽象的父類中,而在策略模式中,調用算法的主體則是封裝到了封裝類Context中,抽象策略Strategy通常是一個接口,目的只是爲了定義規範,裏面通常不包含邏輯。其實,這只是通用實現,而在實際編程中,由於各個具體策略實現類之間不免存在一些相同的邏輯,爲了不重複的代碼,咱們經常使用抽象類來擔任Strategy的角色,在裏面封裝公共的代碼,所以,在不少應用的場景中,在策略模式中通常會看到模版方法模式的影子。 設計模式

 

策略模式的結構 數組

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

策略模式代碼實現 this

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
interface IStrategy {
     public void doSomething ( ) ;
}
class ConcreteStrategy1 implements IStrategy {
     public void doSomething ( ) {
         System . out . println ( "具體策略1" ) ;
     }
}
class ConcreteStrategy2 implements IStrategy {
     public void doSomething ( ) {
         System . out . println ( "具體策略2" ) ;
     }
}
class Context {
     private IStrategy strategy ;
 
     public Context ( IStrategy strategy ) {
         this . strategy = strategy ;
     }
 
     public void execute ( ) {
         strategy . doSomething ( ) ;
     }
}
 
public class Client {
     public static void main ( String [ ] args ) {
         Context context ;
         System . out . println ( "-----執行策略1-----" ) ;
         context = new Context ( new ConcreteStrategy1 ( ) ) ;
         context . execute ( ) ;
 
         System . out . println ( "-----執行策略2-----" ) ;
         context = new Context ( new ConcreteStrategy2 ( ) ) ;
         context . execute ( ) ;
     }
}

 

策略模式的優缺點 spa

策略模式的主要優勢有: 設計

  • 策略類之間能夠自由切換,因爲策略類實現自同一個抽象,因此他們之間能夠自由切換。
  • 易於擴展,增長一個新的策略對策略模式來講很是容易,基本上能夠在不改變原有代碼的基礎上進行擴展。
  • 避免使用多重條件,若是不使用策略模式,對於全部的算法,必須使用條件語句進行鏈接,經過條件判斷來決定使用哪種算法,在上一篇文章中咱們已經提到,使用多重條件判斷是很是不容易維護的。

策略模式的缺點主要有兩個: code

  • 維護各個策略類會給開發帶來額外開銷,可能你們在這方面都有經驗:通常來講,策略類的數量超過5個,就比較使人頭疼了。
  • 必須對客戶端(調用者)暴露全部的策略類,由於使用哪一種策略是由客戶端來決定的,所以,客戶端應該知道有什麼策略,而且瞭解各類策略之間的區別,不然,後果很嚴重。例如,有一個排序算法的策略模式,提供了快速排序、冒泡排序、選擇排序這三種算法,客戶端在使用這些算法以前,是否是先要明白這三種算法的適用狀況?再好比,客戶端要使用一個容器,有鏈表實現的,也有數組實現的,客戶端是否是也要明白鏈表和數組有什麼區別?就這一點來講是有悖於迪米特法則的。

 

適用場景 htm

作面向對象設計的,對策略模式必定很熟悉,由於它實質上就是面向對象中的繼承和多態,在看完策略模式的通用代碼後,我想,即便以前歷來沒有據說過策略模式,在開發過程當中也必定使用過它吧?至少在在如下兩種狀況下,你們能夠考慮使用策略模式,

  • 幾個類的主要邏輯相同,只在部分邏輯的算法和行爲上稍有區別的狀況。
  • 有幾種類似的行爲,或者說算法,客戶端須要動態地決定使用哪種,那麼可使用策略模式,將這些算法封裝起來供客戶端調用。

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

相關文章
相關標籤/搜索