首先上定义:策略模式定义了算法族,分别封装起来,让他们相互之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
从定义上看,策略模式中的策略指的就是算法,或者说方法,本质上是一种对行为的封装。既然是对行为的封装,肯定是用接口而不是抽象类。
让客户代码对具体实现透明,即常说的针对接口编程,也就是设计模式中的依赖倒转原则。
举个栗子:
有个战士要出征打仗,需要使用武器,使用枪和使用剑,或者弓箭,这些都可以作为备选策略。理论上,战士肯定是希望在各种策略之间随意切换,至于各种策略是如何实现的战士其实不需要关心。
上代码:
首先,使用武器作为策略,这个是我们需要抽象的部分,战士作为策略的使用者(方法调用者),可能会有不同的战士,如国王,骑士:
UML看起来像下面这个样子:

image.png
如图所示:定义了武器使用的接口WeaponBehavior,其中有两种实现 ArrowBehavior、SwordBehavior。
接口的调用者战士:Fighter,战士也分不同类型,国王( King)和骑士(Knight)。
其中,武器是可以在使用者手中随意切换的,国王可以用剑也可以用弓箭,我们用方法setWeapon来切换武器。
代码如下:
/**
* 武器接口
* @author saisaimayi
*
*/
public interface WeaponBehavior {
public void useWeapon();
}
/**
* 剑实现武器的具体功能
* @author saisaimayi
*
*/
public class SwordBehavior implements WeaponBehavior {
public void useWeapon() {
System.out.println("fight with Sword...");
}
}
/**
* 实现弓箭
* @author saisaimayi
*
*/
public class ArrorBehavior implements WeaponBehavior {
public void useWeapon() {
System.out.println("fight with Arrow...");
}
}
/**
* 战士抽象类
* @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();
}
}