1. 現實需求
客戶有了新的需求,這時我們直接新增策略即可,改很少的代碼。基本符合我們面向對象原則中的開閉原則(對擴展開放,對修改關系),實現了高內聚低耦合。
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");
}
}
執行結構:

