您的位置:首页 > 编程语言 > C#

C# 策略模式

2015-09-17 16:36 309 查看

C# 策略模式

假如有一款游戏中有多种英雄,每个英雄都有移动和攻击行为,我们很容易想到用继承来实现,代码大致如下
using System;
using System.Collections.Generic;
public abstract class Hero
{
public abstract void showname();
public abstract void attack();
public abstract void move();
//修改的部分 (新增加死亡动作)
public abstract void death();

}

public class Fashi : Hero
{
public override void showname()
{
Console.WriteLine("法师");
}
public override void attack()
{
Console.WriteLine("正在攻击");
}
public override void move()
{
Console.WriteLine("正在移动");
}
//修改的部分
public override void death()
{
Console.WriteLine("正在死亡");
}
}

public class Gongjianshou : Hero
{
public override void showname()
{
Console.WriteLine("弓箭手");
}
public override void attack()
{
Console.WriteLine("正在攻击");
}
public override void move()
{
Console.WriteLine("正在移动");
}
//修改的部分
public override void death()
{
Console.WriteLine("正在死亡");
}
}

public class Example
{

public static void Main()
{
Hero hero1 = new Fashi();

Hero hero2 = new Gongjianshou();

List<Hero> heroList = new List<Hero>();
heroList.Add(hero1);
heroList.Add(hero2);
for (int i = 0; i < heroList.Count; i++)
{
//所有英雄直接执行相应动作 如果在英雄初始化注册了动作就会执行这个动作
Hero currentHero = heroList[i] as Hero;
currentHero.showname();
currentHero.attack();
currentHero.move();
currentHero.death();
}

}
}


可以看到,如果我们增加了一个死亡的行为,所有继承Hero的类就都要实现death()函数, 这个很烦哎~后期每增加一个新的行为,不管这个行为前面已经实现的英雄是否会用到(有些行为只有特定英雄能用到,比跳跃),都要重新实现这个新增的函数.这就有点头疼了啊

那么聪明的你可能会想到用接口啊~~

定义一个跳跃的接口 , 可以跳跃的英雄实现这个接口,不可以跳跃的英雄就不用实现不就好了

这的确实个好办法,但是如果有很多种英雄都可以跳跃,并且如果跳跃后期要改动的话,就要到每个具体实现跳跃的类当中一个一个的修改了,这样无非没有很好的支持重用
那么有没有一种模式可以方便拓展新的行为, 又可以很好的重用呢?

这个时候策略模式就闪亮登场了 ^ _ ^

//策略模式是使用继承和多态建立一套可以自由切换算法的模式

using System;
using System.Collections.Generic;

public interface IMoveType
{
void move();
}
public interface IAttackType
{
void attack();
}

public interface IJiaxueType
{
void jiaxue();
}

public abstract class Hero
{
public string heroName = null;
public string HeroName
{
set { heroName = value; }
get { return heroName; }
}
private IMoveType moveAction = null;
public IMoveType MoveAction
{
set { moveAction = value; }
get { return moveAction; }
}

private IAttackType attackAction = null;
public IAttackType AttackAction
{
set { attackAction = value; }
get { return attackAction; }
}
private IJiaxueType jiaxueAction = null;
public IJiaxueType JiaxueAction
{
set { jiaxueAction = value; }
get { return jiaxueAction; }
}

public void displayName()
{
if (this.heroName == null)
return;
Console.WriteLine(this.heroName);
}

public void onMove()
{
if (moveAction == null)
return;
moveAction.move();

}
public void onAttack()
{
if (attackAction == null)
return;
attackAction.attack();

}
public void onJiaxue()
{
if (jiaxueAction == null)
return;
jiaxueAction.jiaxue();

}

}

public class GroundMove : IMoveType
{
public void move()
{
Console.WriteLine("正在地面移动");
}
}

public class FlyMove : IMoveType
{
public void move()
{
Console.WriteLine("正在空中移动");
}
}

public class NearAttack : IAttackType
{
public void attack()
{
Console.WriteLine("近程攻击");
}
}

public class FarAttack : IAttackType
{
public void attack()
{
Console.WriteLine("远程攻击");
}
}
public class CannotAttack : IAttackType
{
public void attack()
{
Console.WriteLine("不会攻击");
}
}
public class NaimaJiaxue : IJiaxueType
{
public void jiaxue()
{
Console.WriteLine("奶妈正在加血");
}
}

public class Fashi : Hero
{
public Fashi()
{
//构造方法动态添加各种动作接口
base.MoveAction = new GroundMove();
base.AttackAction = new FarAttack();
}

}

public class Gongjianshou : Hero
{
public Gongjianshou()
{
//构造方法动态添加各种动作接口
base.MoveAction = new GroundMove();
base.AttackAction = new FarAttack();
}

}
public class Naima : Hero
{
public Naima()
{
//构造方法动态添加各种动作接口
base.MoveAction = new FlyMove();
base.AttackAction = new CannotAttack();
base.JiaxueAction = new NaimaJiaxue();
}

}

public class Juren : Hero
{
public Juren()
{
//构造方法动态添加各种动作接口
base.MoveAction = new GroundMove();
base.AttackAction = new NearAttack();
}

}

public class Example
{
public static void Main()
{
Hero hero1 = new Fashi();
hero1.HeroName = "法师 1";

Hero hero1_2 = new Fashi();
hero1_2.HeroName = "法师 2";

Hero hero2 = new Gongjianshou();
hero2.HeroName = "弓箭手1";

Hero hero3 = new Naima();
hero3.HeroName = "奶妈1";

Hero hero4 = new Juren();
hero4.HeroName = "巨人1";

List<Hero> heroList = new List<Hero>();
heroList.Add(hero1);
heroList.Add(hero1_2);
heroList.Add(hero2);
heroList.Add(hero3);
heroList.Add(hero4);
for (int i = 0; i < heroList.Count; i++)
{

//所有英雄直接执行相应动作 如果在英雄初始化注册了动作就会执行这个动作
Hero currentHero = heroList[i] as Hero;
currentHero.displayName();
currentHero.onMove();
currentHero.onAttack();
currentHero.onJiaxue();
}

}
}


可以看到在Hero类的实现当中,把攻击,移动,加血等行为作为了类的一个属性,在每个继承Hero的子类的构造方法中,选择性的实现这些行为(移动,攻击,死亡等),这样就使得即使增加新的行为(例如加血),前面已经实现的英雄可以不必具体实现这个行为,根据需要实现即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: