標籤:
策略模式—Java實現
1. 現實需求
本人現在負責開發和維護考核督辦系統,其中一個模組叫編寫工作計劃。是工作計劃就要有時間,我們的各種提醒都做了,但是還是有人把x月的工作計劃內容寫到y月,真心無語了!可能有人會說,讓客戶直接把錯誤的工作計劃全部修改正確不就行了,但是你想客戶會願意嗎?客戶永遠是想做最少的事帶來最多的效果。
好吧,那就是直接修改時間。這時問題來了,如果你修改的時間下,已經有了工作計劃怎麼辦?是覆蓋,還是合并,還是……。這時我們需要給客戶提供策略供其選擇。當然,具體業務還有很多限制,這裡不具體描述了。可能我們沒有想全所有的情況,或客戶有了新的需求,這時我們直接新增策略即可,改很少的代碼。基本符合我們物件導向原則中的開閉原則(對擴充開放,對修改關係),實現了高內聚低耦合。
2. 策略模式定義
策略模式,又叫演算法簇模式,就是定義了不同的演算法族,並且之間可以互相替換,此模式讓演算法的變化獨立於使用演算法的客戶。
3. 設計原則
設計原則是把一個類中經常改變或者將來可能改變的部分提取出來,作為一個介面然後在類中包 含這 個對象的執行個體,這樣類的執行個體在運行時就可以隨意調用實現了這個介面的類的行為。下面是一個例子。
策略模式屬於對象行為型模式,主要針對一組演算法,將每一個演算法封裝到具有共同介面的獨立的類中,從而使得它們可以相互替換。策略模式使得演算法可以在不影響到用戶端的情況下發生變化。通常,策略模式適用於當一個應用程式需要實現一種特定的服務或者功能,而且該程式有多種實現方式時使用。
4. 策略模式中有三個對象:
(1) 環境對象:該類中實現了對抽象策略中定義的介面或者抽象類別的引用。
(2) 抽象策略對象:它可由介面或抽象類別來實現。
(3) 具體策略對象:它封裝了實現同不功能的不同演算法。
利用策略模式構建應用程式,可以根據使用者配置等內容,選擇不同有演算法來實現應用程式的功能。具體的選擇有環境對象來完成。採用這種方式可以避免由於使用條件陳述式而帶來的代碼混亂,提高應用程式的靈活性與條理性。
5. 為了方便大家理解,還是我們以大多網路上的執行個體講解。
劉備要到江東娶老婆了,走之前諸葛亮給趙雲(伴郎)三個錦囊妙計,說是按天機拆開能解決棘手問題,嘿,還別說,真解決了大問題,搞到最後是周瑜陪了夫人又折兵,那咱們先看看這個情境是什麼樣子的。
先說說這個情境中的要素:三個妙計,一個錦囊,一個趙雲,妙計是亮哥給的,妙計放在錦囊裡,俗稱就是錦囊妙計嘛,那趙雲就是一個幹活的人,從錦囊取出妙計,執行,然後獲勝。用java程式怎麼表現這些呢?
類圖:
項目結構:
具體代碼
package chengxuyuanzhilu.com.sp;/** * @author 公眾號:程式員之路 * 首先定義一個策略介面,這是諸葛亮老人家給趙雲的三個錦囊妙計的介面。 */public interface IStrategy { //每個錦囊妙計都是一個可執行檔演算法。 public void operate();}package chengxuyuanzhilu.com.sp.imp;import chengxuyuanzhilu.com.sp.IStrategy;/** * @author 公眾號:程式員之路 * 找喬國老幫忙,使孫權不能殺劉備 */public class BackDoor implements IStrategy { @Override public void operate() { System.out.println("找喬國老幫忙,讓吳國太給孫權施加壓力,使孫權不能殺劉備..."); }}package chengxuyuanzhilu.com.sp.imp;import chengxuyuanzhilu.com.sp.IStrategy;/** * @author 公眾號:程式員之路 * 孫夫人斷後,擋住追兵 */public class BlackEnemy implements IStrategy { @Override public void operate() { System.out.println("孫夫人斷後,擋住追兵..."); }}package chengxuyuanzhilu.com.sp.imp;import chengxuyuanzhilu.com.sp.IStrategy;/** * @author 公眾號:程式員之路 * 求吳國太開個綠燈 */public class GivenGreenLight implements IStrategy { @Override public void operate() { System.out.println("求吳國太開個綠燈,允許存取!"); }}package chengxuyuanzhilu.com.sp;/** * @author 公眾號:程式員之路 * 放策略的錦囊 */public class Context { //介面的好處就在於它可以指向實現了它的任意實作類別 private IStrategy strategy; //通過錦囊的建構函式,去指定具體要選擇哪條策略去處理遇到的危險 public Context(IStrategy strategy) { this.strategy = strategy; } public void operate(){ this.strategy.operate(); }}package chengxuyuanzhilu.com.sp;import chengxuyuanzhilu.com.sp.imp.BackDoor;import chengxuyuanzhilu.com.sp.imp.BlackEnemy;import chengxuyuanzhilu.com.sp.imp.GivenGreenLight;/** * @author 公眾號:程式員之路 * 趙雲就是我們現實生活中的客戶 */public class ZhaoYun { /** * 趙雲出場了,他根據諸葛亮給他的交代,依次拆開妙計 */ public static void main(String[] args) { Context context; //剛到吳國的時候拆開第一個 System.out.println("----------剛剛到吳國的時候拆開第一個---------------"); context = new Context(new BackDoor()); context.operate();//拆開執行 System.out.println("\n"); //當劉備樂不思蜀時,拆開第二個 System.out.println("----------劉備樂不思蜀,拆第二個了---------------"); context = new Context(new GivenGreenLight()); context.operate();//拆開執行 System.out.println("\n"); //孫權的小追兵了,咋辦?拆開第三個錦囊 System.out.println("----------孫權的小追兵了,咋辦?拆開第三個錦囊---------------"); context = new Context(new BlackEnemy()); context.operate();//拆開執行 System.out.println("\n"); }}
執行結構:
策略模式-Java實現