策略模式--红色警戒2之兵种设计
策略模式:针对同类算法的不同实现抽象成算法接口,并分别实现种具体的策略。此算法接口可以有多个。这样算法的变化就独立于算法的使用者。使用者使用的仅仅是策略接口。
下面给出一个实际的例子:
红色警戒2中的美国大病为例(大兵,火箭飞行兵,探亚,时空兵),这些兵种都有一个共性:能移动,会***。而他们移动和***的方式各不相同。
如何设计这样的兵种,让使用者不再关心具体的细节,只关心他们是兵就ok了。
思路:
设计一个***接口Attackable,设计一个移动接口Moveable,定义一个抽象的父类(Soldier)。
/**
* ***接口
*
* @author leizhimin 11-12-18 下午5:13
*/
public interface Attackable {
//***
void attacking();
}
* ***接口
*
* @author leizhimin 11-12-18 下午5:13
*/
public interface Attackable {
//***
void attacking();
}
/**
* 移动接口
*
* @author leizhimin 11-12-18 下午5:13
*/
public interface Moveable {
void moving();
}
* 移动接口
*
* @author leizhimin 11-12-18 下午5:13
*/
public interface Moveable {
void moving();
}
/**
* 士兵抽象类
*
* @author leizhimin 11-12-18 下午5:14
*/
public abstract class Soldier {
private Attackable attackable; //***接口对象
private Moveable moveable; //移动接口对象
public Soldier(Attackable attackable, Moveable moveable) {
this.attackable = attackable;
this.moveable = moveable;
}
//每个士兵都会挂掉,惨叫一声、挂了后从单元集合中移除
public void dead() {
doScreech(); //惨叫一声
System.out.println( "挂了,被系统从单元队列中移除!");
}
//所有的兵死前都会惨叫,这个是惨叫声,需要具体的士兵实现
abstract void doScreech();
public Attackable getAttackable() {
return attackable;
}
public Moveable getMoveable() {
return moveable;
}
}
* 士兵抽象类
*
* @author leizhimin 11-12-18 下午5:14
*/
public abstract class Soldier {
private Attackable attackable; //***接口对象
private Moveable moveable; //移动接口对象
public Soldier(Attackable attackable, Moveable moveable) {
this.attackable = attackable;
this.moveable = moveable;
}
//每个士兵都会挂掉,惨叫一声、挂了后从单元集合中移除
public void dead() {
doScreech(); //惨叫一声
System.out.println( "挂了,被系统从单元队列中移除!");
}
//所有的兵死前都会惨叫,这个是惨叫声,需要具体的士兵实现
abstract void doScreech();
public Attackable getAttackable() {
return attackable;
}
public Moveable getMoveable() {
return moveable;
}
}
具体的***方式:
/**
* 小×××***
*
* @author leizhimin 11-12-18 下午6:00
*/
public class HandgunAttack implements Attackable {
public void attacking() {
System.out.println( "小×××***,噼~噼~噼~~~");
}
}
* 小×××***
*
* @author leizhimin 11-12-18 下午6:00
*/
public class HandgunAttack implements Attackable {
public void attacking() {
System.out.println( "小×××***,噼~噼~噼~~~");
}
}
/**
* AK47***
*
* @author leizhimin 11-12-18 下午5:57
*/
public class Ak47Attack implements Attackable{
public void attacking() {
System.out.println( "AK47***,哒哒哒......");
}
}
* AK47***
*
* @author leizhimin 11-12-18 下午5:57
*/
public class Ak47Attack implements Attackable{
public void attacking() {
System.out.println( "AK47***,哒哒哒......");
}
}
具体的移动方式:
/**
* 天上飞行
*
* @author leizhimin 11-12-18 下午6:05
*/
public class SkyMove implements Moveable{
public void moving() {
System.out.println( "天上飞行!");
}
}
* 天上飞行
*
* @author leizhimin 11-12-18 下午6:05
*/
public class SkyMove implements Moveable{
public void moving() {
System.out.println( "天上飞行!");
}
}
/**
* 陆地走动
*
* @author leizhimin 11-12-18 下午6:04
*/
public class WalkMove implements Moveable{
public void moving() {
System.out.println( "陆地走动!");
}
}
* 陆地走动
*
* @author leizhimin 11-12-18 下午6:04
*/
public class WalkMove implements Moveable{
public void moving() {
System.out.println( "陆地走动!");
}
}
/**
* 陆地走动或者水里游动
*
* @author leizhimin 11-12-18 下午6:07
*/
public class WalkOrSwimMove implements Moveable{
public void moving() {
System.out.println( "陆地走动或者水里游动!");
}
}
* 陆地走动或者水里游动
*
* @author leizhimin 11-12-18 下午6:07
*/
public class WalkOrSwimMove implements Moveable{
public void moving() {
System.out.println( "陆地走动或者水里游动!");
}
}
然后定义三种类型的士兵:
/**
* 探亚
*
* @author leizhimin 11-12-18 下午5:50
*/
public class TanyaSoldier extends Soldier {
public TanyaSoldier(Attackable attackable, Moveable moveable) {
super(attackable, moveable);
}
@Override
void doScreech() {
System.out.println( "(探亚)呃~~~~~");
}
}
* 探亚
*
* @author leizhimin 11-12-18 下午5:50
*/
public class TanyaSoldier extends Soldier {
public TanyaSoldier(Attackable attackable, Moveable moveable) {
super(attackable, moveable);
}
@Override
void doScreech() {
System.out.println( "(探亚)呃~~~~~");
}
}
/**
* 飞行兵
*
* @author leizhimin 11-12-18 下午6:19
*/
public class SkySoldier extends Soldier {
public SkySoldier(Attackable attackable, Moveable moveable) {
super(attackable, moveable);
}
@Override
void doScreech() {
System.out.println( "(飞行兵)噗——");
}
}
* 飞行兵
*
* @author leizhimin 11-12-18 下午6:19
*/
public class SkySoldier extends Soldier {
public SkySoldier(Attackable attackable, Moveable moveable) {
super(attackable, moveable);
}
@Override
void doScreech() {
System.out.println( "(飞行兵)噗——");
}
}
/**
* 美国大兵
*
* @author leizhimin 11-12-18 下午6:15
*/
public class UsSoldier extends Soldier{
public UsSoldier(Attackable attackable, Moveable moveable) {
super(attackable, moveable);
}
@Override
void doScreech() {
System.out.println( "(美国大兵)啊————");
}
}
* 美国大兵
*
* @author leizhimin 11-12-18 下午6:15
*/
public class UsSoldier extends Soldier{
public UsSoldier(Attackable attackable, Moveable moveable) {
super(attackable, moveable);
}
@Override
void doScreech() {
System.out.println( "(美国大兵)啊————");
}
}
客户端测试:
import java.util.ArrayList;
import java.util.List;
/**
* 客户端
*
* @author leizhimin 11-12-18 下午6:09
*/
public class Test {
public static void main(String[] args) {
//具体的***策略
Attackable ak47Attack = new Ak47Attack();
Attackable handgunAttack = new HandgunAttack();
//具体的移动策略
Moveable walkMove = new WalkMove();
Moveable walkOrSwimMove = new WalkOrSwimMove();
Moveable skyMove = new SkyMove();
//构建具体的兵种
Soldier tanyaSoldier = new TanyaSoldier(handgunAttack, walkOrSwimMove);
Soldier usSoldier = new UsSoldier(ak47Attack, walkMove);
Soldier skySoldier = new SkySoldier(handgunAttack, skyMove);
List soldierList =
new ArrayList();
soldierList.add(tanyaSoldier);
soldierList.add(usSoldier);
soldierList.add(skySoldier);
for (Soldier soldier : soldierList) {
doSomething(soldier);
}
}
/**
* 做事
*
* @param soldier
*/
public static void doSomething(Soldier soldier) {
System.out.println( "------------------------------------");
soldier.getMoveable().moving();
soldier.getAttackable().attacking();
soldier.dead();
}
}
import java.util.List;
/**
* 客户端
*
* @author leizhimin 11-12-18 下午6:09
*/
public class Test {
public static void main(String[] args) {
//具体的***策略
Attackable ak47Attack = new Ak47Attack();
Attackable handgunAttack = new HandgunAttack();
//具体的移动策略
Moveable walkMove = new WalkMove();
Moveable walkOrSwimMove = new WalkOrSwimMove();
Moveable skyMove = new SkyMove();
//构建具体的兵种
Soldier tanyaSoldier = new TanyaSoldier(handgunAttack, walkOrSwimMove);
Soldier usSoldier = new UsSoldier(ak47Attack, walkMove);
Soldier skySoldier = new SkySoldier(handgunAttack, skyMove);
List
soldierList.add(tanyaSoldier);
soldierList.add(usSoldier);
soldierList.add(skySoldier);
for (Soldier soldier : soldierList) {
doSomething(soldier);
}
}
/**
* 做事
*
* @param soldier
*/
public static void doSomething(Soldier soldier) {
System.out.println( "------------------------------------");
soldier.getMoveable().moving();
soldier.getAttackable().attacking();
soldier.dead();
}
}
------------------------------------
陆地走动或者水里游动!
小×××***,噼~噼~噼~~~
(探亚)呃~~~~~
挂了,被系统从单元队列中移除!
------------------------------------
陆地走动!
AK47***,哒哒哒......
(美国大兵)啊————
挂了,被系统从单元队列中移除!
------------------------------------
天上飞行!
小×××***,噼~噼~噼~~~
(飞行兵)噗——
挂了,被系统从单元队列中移除!
Process finished with exit code 0
陆地走动或者水里游动!
小×××***,噼~噼~噼~~~
(探亚)呃~~~~~
挂了,被系统从单元队列中移除!
------------------------------------
陆地走动!
AK47***,哒哒哒......
(美国大兵)啊————
挂了,被系统从单元队列中移除!
------------------------------------
天上飞行!
小×××***,噼~噼~噼~~~
(飞行兵)噗——
挂了,被系统从单元队列中移除!
Process finished with exit code 0
呵呵,只为深入理解下策略模式,粗糙之处还请拍砖。