设计模式——策略模式.md
作者:云都小生
引言
在某款游戏中,游戏角色所持的武器会根据它的等级去升级,一位普通程序员经过设计后实现了该功能,下面是精简版的代码。
public class Soldier {
private int level = 1; //等级
private String arms = "木棍"; //武器
public void SetLevel(int level)
{
this.level = level;
}
public int GetLevel()
{
return level;
}
public String GetArms()
{
return arms;
}
public String CheckArms()
{
if(level < 5)
{
arms = "木棍";
}
else if(level < 10)
{
arms = "铁棒";
}
return arms;
}
}
public class Test {
public static void main(String[] args) {
Soldier soldier = new Soldier();
soldier.SetLevel(8);
System.out.println("士兵的武器是" + soldier.CheckArms());
}
}
这样看起来有什么毛病?我记得我的教员在教我们的时候,直接明了的说,一个程序如果太多if判断,就说明开发该程序的程序员水平并不高。
为什么呢?因为“开闭原则”,一旦我想要设计该士兵对象在15级以上的时候拿“蓝牙棒”,那就得去修改原来士兵类的代码。
上面的代码,不利于维护、扩展,复用性也很差,所以我们引入策略模式。
概述
策略模式主要是将每个策略的行为和环境类分离,这样我们确保了策略的可扩展性。引入一个抽象的策略类,所有的策略类都继承了这个抽象类,这样我们就能通过多态去动态的绑定行为了。
在策略模式中,有下列角色:
环境类:环境类是各种策略的使用者,它需要持有一个对抽象策略类的引用,用于动态绑定。
抽象策略类:它为所支持的算法声明了抽象方法,是所有策略类的父类,可以是抽象类也可以是接口。
具体策略类:它继承抽象策略类,并且实现了抽象策略类中的抽象方法。
案例
我们用策略模式来重构刚刚的代码。
//环境类
public class Soldier {
private int level = 1; //等级
Arms arms;
Soldier(Arms arms)
{
this.arms = arms;
}
public void SetLevel(int level)
{
this.level = level;
}
public int GetLevel()
{
return level;
}
public void SetArms(Arms arms)
{
this.arms = arms;
}
public void ShowArms()
{
arms.Show();
}
}
//抽象武器类
abstract class Arms {
abstract void Show();
}
//具体武器类:大长刀
public class LongKnife extends Arms
{
void Show()
{
System.out.println("士兵举起了它的大长刀");
}
}
//测试类
public class Test {
public static void main(String[] args) {
Soldier soldier = new Soldier(new LongKnife());
soldier.SetLevel(8);
soldier.ShowArms();
}
}
总结
策略模式的使用场景,通常是为了分离环境类和具体的策略类。就像上面的代码,我们就可以扩展更多的武器,而且这些武器类和士兵类之间的耦合度很低,不会相互影响。
如果我其他角色也想要用到这些武器类,就可以直接创建引用。提高了可扩展性、灵活性和复用性。
2018/3/23 23:32:40 @Author:云都小生