什麼是策略模式?
個人認為,設計模式的定義是比較晦澀抽象的,瞭解設計模式的最合適的方法就是先看看它的使用場景和相關案例,Java的JDK中就有此設計模式的體現。先講一個比較簡單的,那就是File的檔案過濾機制。File類中有個list(FilenameFilter filter)的方法用於過濾File物件(如果是目錄的話)下檔案及資料夾。
list方法 (File.java 部分程式碼),其中無參的list方法是獲取目錄下所有檔案及資料夾的名稱。
注:File類並不保留策略,每次過濾都需傳入策略類。在其他策略模式的案例中,可能會保留本次策略引用。
FilenameFilter介面,在其實現類中,根據檔案的相關引數對是否通過過濾進行判斷。
JDK並沒有提供FileFilter的實現類,而是讓程式設計者根據需要自由發揮。如下所示,可以程式設計者可以根據正規表示式對檔案進行過濾。
以上例子,"策略"指的就是檔案的過濾方案(或者說,是演算法)。它的思想就是可以根據需要,靈活的建立並替換策略(這裡指過濾方案),而不影響客戶端(這裡指File物件)。
在增加策略時,策略模式是如何防止對客戶端(策略執行者)的修改的?
這裡有必要提一下策略模式體現的OO原則:
(1)封裝變化:在File類中,過濾方式就是變化點,在實際需求中可能經常發生變化,這樣的話,過濾方式就不能寫死在File類中(如果這樣的話,要更換過濾方式,只能通過子類覆蓋的方法實現),而是從File類中抽取出來,封裝成另一個策略類,然後由File類引用。這樣,File類就只管引用策略類並呼叫即可。
(2)針對介面程式設計,而不是針對實現程式設計:如上,list方法中只根據FilenameFilter介面進行程式設計,呼叫介面方法。不會涉及到具體類的其他方法,所以,不管具體類是什麼,list方法呼叫過程都無需改變。
策略模式在JDK中還有那些使用案例?
策略模式在JDK執行緒池中也有使用。這裡,簡要地提一下。在固定大小的執行緒池實現中,有這樣一種情況,即當前執行緒池內的所有執行緒都在使用狀態,而此時又有新的任務進來,這時候如何處理這個新任務就有多種方案了。有的直接拒絕,有的拒絕但會丟擲異常,有的阻塞直到有可用的執行緒,有的移除一個任務來執行當前任務,有的用當前執行緒執行任務。這幾種方案,並沒有明確的優劣之分。可以根據應用場景進行選擇。