首先上定義:策略模式定義了算法族缔逛,分別封裝起來,讓他們相互之間可以互相替換冰悠,此模式讓算法的變化獨(dú)立于使用算法的客戶堡妒。
從定義上看,策略模式中的策略指的就是算法溉卓,或者說方法皮迟,本質(zhì)上是一種對行為的封裝。既然是對行為的封裝桑寨,肯定是用接口而不是抽象類伏尼。
讓客戶代碼對具體實(shí)現(xiàn)透明,即常說的針對接口編程尉尾,也就是設(shè)計(jì)模式中的依賴倒轉(zhuǎn)原則爆阶。
舉個(gè)栗子:
有個(gè)戰(zhàn)士要出征打仗,需要使用武器沙咏,使用槍和使用劍辨图,或者弓箭,這些都可以作為備選策略肢藐。理論上故河,戰(zhàn)士肯定是希望在各種策略之間隨意切換,至于各種策略是如何實(shí)現(xiàn)的戰(zhàn)士其實(shí)不需要關(guān)心吆豹。
上代碼:
首先鱼的,使用武器作為策略理盆,這個(gè)是我們需要抽象的部分,戰(zhàn)士作為策略的使用者(方法調(diào)用者)凑阶,可能會有不同的戰(zhàn)士猿规,如國王,騎士:
UML看起來像下面這個(gè)樣子:
如圖所示:定義了武器使用的接口WeaponBehavior,其中有兩種實(shí)現(xiàn) ArrowBehavior晌砾、SwordBehavior坎拐。
接口的調(diào)用者戰(zhàn)士:Fighter烦磁,戰(zhàn)士也分不同類型养匈,國王( King)和騎士(Knight)。
其中都伪,武器是可以在使用者手中隨意切換的呕乎,國王可以用劍也可以用弓箭,我們用方法setWeapon來切換武器陨晶。
代碼如下:
/**
* 武器接口
* @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)士抽象類
* @author saisaimayi
*
*/
public abstract class Fighter {
protected WeaponBehavior weapon;
public void setWeapon(WeaponBehavior weapon){
this.weapon = weapon;
}
public abstract void fight();
}
/**
* 國王類
* @author saisaimayi
*
*/
public class King extends Fighter {
private void assembleArmy() {
System.out.println("Assembling the army...");
}
@Override
public void fight() {
assembleArmy();
weapon.useWeapon();
}
}
/**
* 騎士類
* @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;
/**
* 測試
* @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();
}
}