五分钟一个设计模式之策略模式

来源:互联网 发布:tomcat 源码分析 编辑:程序博客网 时间:2024/06/08 16:00

五分钟一个设计模式,用最简单的方法来描述设计模式。查看更多设计模式,请点击五分钟一个设计模式系列
http://blog.csdn.net/daguanjia11/article/category/3259443

开发一个小游戏

还是先来看个例子吧。
有一天老板一拍脑袋,想做一个游戏,于是把你找来,告诉你他的想法:

  1. 做一个最简单的闯关游戏,每个关卡都有一些小怪兽,而游戏的角色通过打死所有小怪兽来通关
  2. 角色可以使用武器,先做三四个简单的武器,有一般的武器,有厉害的武器,每个武器的伤害值不一样
  3. 游戏过程中,角色可以更换武器
  4. 先做一个角色,以后可能增加新角色,但不同角色之间的区别现在还没想好。

你作为这个新游戏的主程序员,要做的就是使程序的架构足够灵活,能够为老板的想法提供支持,而不是让老板为了迁就技术的实现而对自己的想法妥协。

这个东西对于你来说应该是小菜一碟,下面直入正题。
这个程序在架构设计上的难点在于武器。武器这一块肯定要抽象出来一个抽象类或接口,因为武器以后肯定会越来越多,有一个统一的父类或接口的话,比较好管理。

public interface IWeapon{    int GetDamage();}

上面是武器接口,返回一个整型数值,表示该武器有多大的威力。下面来实现几个武器。

/// <summary>/// 小刀/// </summary>public class Knife : IWeapon{    public int GetDamage()    {        return 100;    }}
/// <summary>/// 大剑/// </summary>public class Sword:IWeapon{    public int GetDamage()    {        return 200;    }}
/// <summary>////// </summary>public class Gun:IWeapon{    public int GetDamage()    {        return 500;    }}

好,武器有了,下面就得上角色了。角色拥有武器,还可以随时更换武器。

public class Role{    private IWeapon weapon;    /// <summary>    /// 在角色初始化时,需要传递进来一个武器对象    /// </summary>    /// <param name="weapon"></param>    public Role(IWeapon weapon)    {        this.weapon = weapon;    }    public void Kill()    {        int damage = weapon.GetDamage();        Console.WriteLine("对小怪兽造成了{0}点伤害", damage);    }    /// <summary>    /// 更换武器    /// </summary>    /// <param name="weapon"></param>    public void ReplaceWeapon(IWeapon weapon)    {        this.weapon = weapon;    }}

类都写好了,下面来看使用场景

class Program{    static void Main(string[] args)    {        //先搞出来几件装备        Knife knife=new Knife();        Sword sword=new Sword();        Gun gun=new Gun();        //实例化一个新角色,配一把小刀        Role role = new Role(knife);        role.Kill();        role.Kill();        Console.WriteLine("-----------------------------------------------");        //经过一系列精彩的搏杀,升级了        //给换一把大剑        role.ReplaceWeapon(sword);        role.Kill();        role.Kill();        Console.WriteLine("-----------------------------------------------");        //经过一系列精彩的搏杀,又升级了        //给换一把枪        role.ReplaceWeapon(gun);        role.Kill();        role.Kill();    }}

到这里就已经基本满足老板的要求了。运行结果如下:

对小怪兽造成了100点伤害
对小怪兽造成了100点伤害
———————————————–
对小怪兽造成了200点伤害
对小怪兽造成了200点伤害
———————————————–
对小怪兽造成了500点伤害
对小怪兽造成了500点伤害

我们这个例子是使用策略模式的一个简单且完整的例子。

认识策略模式

策略模式的定义是:定义一系列的算法,把他们一个个封装起来,并且使他们可以相互替换。本模式使得算法可独立于使用它的客户端而变化。

而在上面的小游戏例子中,每一个武器都是一个封装起来的算法,为了简单起见,我们直接返回伤害值。但如果以后计算伤害值的具体方法发生变化了,我们可以直接在特定的算法中修改逻辑,不会影响到使用它的客户端。在游戏中,角色还可以替换武器。如果以后老板要增加新武器,只需要增加一个对应的IWeapon的实现类就好了,客户端的代码的逻辑不需要修改,就可以使用新武器。

继续扩展

我上面也说了,程序写到这里,只是基本满足了老板目前的要求,因为在要求的第四点,老板以后可能会增加新角色,但不同角色之间的区别现在还没想好。在我们目前的程序中,Role是一个具体类,并拥有一个IWeapon实例,如果以后增加角色了,这个类肯定要改,但是怎么改,就要看具体的需求了,如果不同的角色只是皮肤不一样,那就增加一个属性就搞定了,如果打斗的姿势、技能设置等都不一样,那就把角色抽象为一个抽象类,组合IWeapon,并包括打斗姿势和释放技能等方法,留给所有的具体角色去实现。大概如下:

public abstract class IRole{    IWeapon weapon;    public IRole(IWeapon weapon)    {        this.weapon = weapon;    }    /// <summary>    /// 秀一下打斗姿势    /// </summary>    public abstract void ShowPose();    /// <summary>    /// 释放Q技能    /// </summary>    public abstract void Skills_Q();    /// <summary>    /// 释放W技能    /// </summary>    public abstract void Skills_W();    /// <summary>    /// 释放E技能    /// </summary>    public abstract void Skills_E();    /// <summary>    /// 释放R技能(大招)    /// </summary>    public abstract void Skills_R();}

上面的这段代码的逼格很高,IRole抽象类中组合了IWeapon接口,两组类相互缠绵,甚有意思。总之,我们的代码是足够灵活的,老板/客户你就尽管发挥想象力吧。

到这里,有人就有疑问了,你这还是策略模式吗?我想告诉你,这不重要。设计模式不是生搬硬套的东西,重在理解和应用。

你都看到这里了,给个赞吧,骚年?

6 0
原创粉丝点击