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的子类的构造方法中,选择性的实现这些行为(移动,攻击,死亡等),这样就使得即使增加新的行为(例如加血),前面已经实现的英雄可以不必具体实现这个行为,根据需要实现即可
相关文章推荐
- C# Math.Round
- C# windows服务:通过cmd命令安装、卸载、启动和停止Windows Service(InstallUtil.exe)
- 重新学习C# 之 数据类型(一)
- C#之Socket编程
- C#的List排序
- 关于C#地球转火星坐标,以及火星转地球坐标
- 分钟学会 log4net(c#) 配置及使用
- C#实现TreeView节点拖拽的方法
- C#类库中log4net的配置
- C#之接口
- .NET基础--异常处理
- .NET基础--继承
- C#学习笔记(二)
- C#搜索TreeView子节点,保留父节点的方法
- C#实现刷新桌面的方法
- (C# 基础) Datatable
- C#_在VS2010下进行单元测试
- c#中动态输入和计算 代数表达式
- C#中通过Process启动的外部第三方程序MainWindowHandle句柄为0
- C#句柄使用