策略模式也是一種非常常用的設計模式,而且也不復雜。下面我們就來看看這種模式。
定義:策略模式定義了一系列的算法,并將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立于使用它的客戶而獨立變化。
角色:
- 抽象策略角色(Strategy): 抽象策略類。
- 具體策略角色(ConcreteStrategy):封裝了繼續相關的算法和行為。
- 環境角色(Context):持有一個策略類的引用,最終給客戶端調用。
UML圖:
例子:
#include <iostream> using namespace std; class WeaponBehavior { public: void virtual useWeapon() = 0; }; class AK47:public WeaponBehavior { public: void useWeapon() { cout << "Use AK47 to shoot!" << endl; } }; class Knife:public WeaponBehavior { public: void useWeapon() { cout << "Use Knife to kill!" << endl; } }; class Character { public: Character() { weapon = 0; } void setWeapon(WeaponBehavior *w) { this->weapon = w; } void virtual fight() = 0; protected: WeaponBehavior *weapon; }; class King:public Character { public: void fight() { cout << "The king:" ; if ( this->weapon == NULL) { cout << "You don't have a weapon! Please Set Weapon!" << endl; } else { weapon->useWeapon(); } } }; int main() { WeaponBehavior *ak47 = new AK47(); WeaponBehavior *knife = new Knife(); Character *kin = new King(); kin->fight(); cout << endl; kin->setWeapon(ak47); kin->fight(); cout << endl; kin->setWeapon(knife); kin->fight(); return 0; }
適用性:
1,多個類只區別在表現行為不同,可以使用Strategy模式,在運行時動態選擇具體要執行的行為。
2,需要在不同情況下使用不同的策略(算法),或者策略還可能在未來用其它方式來實現。
3,對客戶隱藏具體策略(算法)的實現細節,彼此完全獨立。
優缺點:
優點:
1,策略模式提供了管理相關的算法族的辦法。策略類的等級結構定義了一個算法或行為族。恰當使用繼承可以把公共的代碼移到父類里面,從而避免代碼重復。
2,使用策略模式可以避免使用多重條件(if-else)語句。多重條件語句不易維護,它把采取哪一種算法或采取哪一種行為的邏輯與算法或行為的邏輯混合在一起,統統列在一個多重條件語句里面,比使用繼承的辦法還要原始和落后。
缺點:
1,客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。這就意味著客戶端必須理解這些算法的區別,以便適時選擇恰當的算法類。換言之,策略模式只適用于客戶端知道算法或行為的情況。
2,由于策略模式把每個具體的策略實現都單獨封裝成為類,如果備選的策略很多的話,那么對象的數目就會很可觀。
和其他設計模式的區別:
1,與狀態模式
在解決的問題上,狀態模式是解決內在狀態的改變,而策略模式是解決內部算法的改變。在解決的方法上,狀態模式是自我控制狀態的改變,而策略模式是由外部制定使用使用啥策略。
2,簡單工廠模式
簡單工廠模式是創建型模式,關注對象的創建。策略模式是行為型模式,關注行為的封裝。簡單工廠模式是根據不同的條件返回一個適合的類給你使用,然后調用者使用工廠類返回的類去完成相應的操作。而策略模式是必須首先創建一個想使用的類實例,然后實例被當作參數傳遞進去,既而通過該實例去調用不用的算法。在簡單工廠模式中實現了通過條件選取一個類去實例化對象,策略模式則將選取相應對象的工作交給模式的使用者,它本身不去做選取工作。