码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-05-30 13:37:47      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:策略模式   设计模式   strategy   

五分钟一个设计模式,用最简单的方法来描述设计模式。

开发一个小游戏

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

  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接口,两组类相互缠绵,甚有意思。总之,我们的代码是足够领过的,老板/客户你就尽管发挥想象力吧。

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

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

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

标签:策略模式   设计模式   strategy   

原文地址:http://blog.csdn.net/daguanjia11/article/details/46272711

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!