首先上定義:策略模式定義了算法族,分別封裝起來(lái),讓他們相互之間可以互相替換,此模式讓算法的變化獨(dú)立于使用算法的客戶。
從定義上看,策略模式中的策略指的就是算法,或者說(shuō)方法,本質(zhì)上是一種對(duì)行為的封裝。既然是對(duì)行為的封裝,肯定是用接口而不是抽象類(lèi)。
讓客戶代碼對(duì)具體實(shí)現(xiàn)透明,即常說(shuō)的針對(duì)接口編程,也就是設(shè)計(jì)模式中的依賴倒轉(zhuǎn)原則。
舉個(gè)栗子:
有個(gè)戰(zhàn)士要出征打仗,需要使用武器,使用槍和使用劍,或者弓箭,這些都可以作為備選策略。理論上,戰(zhàn)士肯定是希望在各種策略之間隨意切換,至于各種策略是如何實(shí)現(xiàn)的戰(zhàn)士其實(shí)不需要關(guān)心。
上代碼:
首先,使用武器作為策略,這個(gè)是我們需要抽象的部分,戰(zhàn)士作為策略的使用者(方法調(diào)用者),可能會(huì)有不同的戰(zhàn)士,如國(guó)王,騎士:
UML看起來(lái)像下面這個(gè)樣子:

image.png
如圖所示:定義了武器使用的接口WeaponBehavior,其中有兩種實(shí)現(xiàn) ArrowBehavior、SwordBehavior。
接口的調(diào)用者戰(zhàn)士:Fighter,戰(zhàn)士也分不同類(lèi)型,國(guó)王( King)和騎士(Knight)。
其中,武器是可以在使用者手中隨意切換的,國(guó)王可以用劍也可以用弓箭,我們用方法setWeapon來(lái)切換武器。
代碼如下:
/**
* 武器接口
* @author saisaimayi
*
*/
public interface WeaponBehavior {
public void useWeapon();
}
/**
* 劍實(shí)現(xiàn)武器的具體功能
* @author saisaimayi
*
*/
public class SwordBehavior implements WeaponBehavior {
public void useWeapon() {
System.out.println("fight with Sword...");
}
}
/**
* 實(shí)現(xiàn)弓箭
* @author saisaimayi
*
*/
public class ArrorBehavior implements WeaponBehavior {
public void useWeapon() {
System.out.println("fight with Arrow...");
}
}
/**
* 戰(zhàn)士抽象類(lèi)
* @author saisaimayi
*
*/
public abstract class Fighter {
protected WeaponBehavior weapon;
public void setWeapon(WeaponBehavior weapon){
this.weapon = weapon;
}
public abstract void fight();
}
/**
* 國(guó)王類(lèi)
* @author saisaimayi
*
*/
public class King extends Fighter {
private void assembleArmy() {
System.out.println("Assembling the army...");
}
@Override
public void fight() {
assembleArmy();
weapon.useWeapon();
}
}
/**
* 騎士類(lèi)
* @author saisaimayi
*
*/
public class Knight extends Fighter {
private void prepareHourse(){
System.out.println("prepare the hourse for battle...");
}
@Override
public void fight() {
prepareHourse();
weapon.useWeapon();
}
}
import junit.framework.TestCase;
/**
* 測(cè)試
* @author saisaimayi
*
*/
public class KingTest extends TestCase {
public void test(){
King king = new King();
king.setWeapon(new SwordBehavior());
king.fight();
king.setWeapon(new ArrorBehavior());
king.fight();
Knight knight = new Knight();
knight.setWeapon(new SwordBehavior());
knight.fight();
}
}