策略模式:定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
先不管定义是如何,让我们先来看一个例子。假设你要设计一个游戏里的人物(包括玩家、NPC),如何进行设计呢?我们知道,一个游戏人物肯定有基本属性、动作(如血量的属性、行走的动作),能够拿不同的武器,能够换不同的装备......如何进行弹性的设计。在这里,我们就可以使用策略模式。
设计原则1:找出应用之中可能变化之处,把它们独立出来,不要和那些不要变化的代码混在一起。在这里,我们可以看到游戏人物可以拿不同的武器, 能够换不同的装备,属于变化的部分,可以独立出来;行走的动作等属于不变的部分,可以不需独立出来,可以先实现为一个类。
基本人物代码:
public class GamePerson{ private int bloodValue; public GamePerson(int value){ this.bloodValue=value; } public int getBloodValue(){ return bloodValue; } private void move(){ System.out.println("I'm moving"); }}
现在我们考虑的是如何实现装备、武器等的实现,使其能够具有弹性,在游戏时动态改变。所以,就需要设计原则2:针对接口编程,而不是针对实现编程。利用接口表示每个行为,比如EquipmentInterface,WeaponInterface.我们不用GamePerson实现这两个接口,而是自己创建具体的装备类、武器类实现各自的接口。如:ClothingEquipment,WristEquipment,SwordWeapton,GunWeapton.
具体代码如下:
装备接口:
public interface EquipmentInterface{ void equipment();}
衣服装备:
public class ClothingEquipment implement EquipmentInterface{ public void equipment(){ Systemout.out.println("I'm clothing"); } }
手腕装备
public class WristEquipment implement EquipmentInterface{ public void equipment(){ Systemout.out.println("I'm wrist"); } }
武器接口
public interface WeaptonInterface{ void weapton(); }
刀剑武器
public class SwordWeapton implement WeaptonInterface{ void weapton(){ System.out.println("I'm sword"); } }
枪武器
public class GunWeapton implement WeaptonInterface{ void weapton(){ System.out.println("I'm gun"); } }
好,最后我们就需要将这两个组合在一起了。具体的说,需要在游戏人物中加入WeaptonInterface与EquipmentInterface。如下:
public class GamePerson{ private int bloodValue; WeaptonInterface weapton; EquipmentInterfac equipment;
public void setWeapton(WeaptonInterface w){ this.weapton = w; }
public void setEquipment(EquipmentInterface w){ this.equipment = w; }
public GamePerson(int value,WeaptonInterface w,EquipmentInterface e){ this.bloodValue=value; this.weapton = w; this.equipment =e; } public int getBloodValue(){ return bloodValue; } private void move(){ System.out.println("I'm moving"); }}
所以,具体的人物类可以继承GamePerson,如:
public class NPCPerson extends GamePerson{ public void NPCPerson(int b,WeaptonInterface w,EquipmentInterface e){ super(b,w,e); } }
测试一下:
public class TestApp{ public static void main(String[] args){ NPCPerson p = new NPCPerson(100,new SwordWeapton(),new WristWeapton()); p.move(); p.setWeapton(new GunWeapton()); }}
在最后需要记住设计原则3:多用组合,少用继承。