策略模式--红色警戒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 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 下午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***,哒哒哒......");
        }
}
 
具体的移动方式:
 
/**
* 天上飞行
*
* @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: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 下午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("(美国大兵)啊————");
        }
}
 
客户端测试:
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<Soldier> soldierList = new ArrayList<Soldier>();
                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
 
 
呵呵,只为深入理解下策略模式,粗糙之处还请拍砖。