0x01:策略模式簡介
策略模式指對象有某個行為,但是在不同的場景中,該行為有不同的實現算法。比如每個人都要交個人所得稅,但是根據個人的收入情況,個人所得稅的計算算法是有不同的策略的。
我想大家都看過《三國演義》,其中劉備娶孫夫人時,諸葛亮交給趙雲三個
錦囊,就是三個策略
錦囊一:到達東吳,先去拜會喬國老
錦囊二:劉備貪念美色不思離開,就對他謊稱曹操大軍壓境
錦囊三:如果被東吳軍隊追趕,求孫夫人解圍
策略模式的UML類圖如下:
主要角色分析:
抽象策略角色(Strategy):策略類,通常由一個接口或者抽象類實現;
具體策略角色(ConcreteStrategyA):包裝了相關的算法和行為;
上下文角色(Context):持有一個策略類的引用,最終給客戶端調用;
Context是上下文,用一個ConcreteStrategy來配置,維護一個Strategy對象的引用;Strategy是策略類,用於定義所有支持算法的公共接口;ConcreteStrategy是具體策略類,封裝了具體的算法或行為,繼承於Strategy。
0x02:策略模式實現
Context:Context上下文角色,也叫Context封裝角色,起承上啟下的作用,屏蔽高層模塊對策略、算法的直接訪問,封裝可能存在的變化。
Strategy:抽象策略角色,是對策略、算法家族的抽象,通常為接口,定義每個策略或算法必須具有的方法和屬性。algorithm是運算法則的意思。
ConcreteStrategy:具體策略角色,用於實現抽象策略中的操作,即實現具體的算法,下方用print代替。
策略模式測試代碼:可以依次更換策略,測試一下策略模式。
0x03:策略模式在JDK的運用
在多線程編程中,經常使用線程池來管理線程,以減緩線程頻繁的創建和銷毀帶來的資源的浪費,其中ThreadPoolExecutor類中的RejectedExecutionHandler參數就是一個使用了策略模式的典型例子。
ThreadPoolExecutor的構造函數
RejectedExecutionHandler接口
RejectedExecutionHandler的四種策略實現
CallerRunsPolicy:該策略並沒有拋棄任何的任務,由於線程池中已經沒有了多餘的線程來分配該任務,該策略是在當前線程(調用者線程)中直接執行該任務;
AbortPolicy:該策略是直接將提交的任務拋棄掉,並拋出RejectedExecutionException異常;
DiscardPolicy:該策略也是將任務拋棄掉(對於提交的任務不管不問,什麼也不做),不過並不拋出異常。
DiscardOldestPolicy:該策略是當執行器未關閉時,從任務隊列workQueue中取出第一個任務,並拋棄這第一個任務,進而有空間存儲剛剛提交的任務。使用該策略需要特別小心,因為它會直接拋棄之前的任務。