如何在C#中使用策略模式?

时间:2010-08-10 13:51:03

标签: c# strategy-pattern

这是我到目前为止所拥有的:

namespace Strategy
{
    interface IWeaponBehavior
    {
        void UseWeapon();
    }
}

namespace Strategy
{
    class Knife : IWeaponBehavior
    {
        public void UseWeapon()
        {
            Console.WriteLine("You used the knife to slash the enemy! SLASH SLASH!");
        }
    }
}

namespace Strategy
{
    class Pan : IWeaponBehavior
    {
        public void UseWeapon()
        {
            Console.WriteLine("You use the pan! 100% Adamantium power! BONG!");
        }
    }
}

现在,如果我有一个Character.cs超类。该超类如何实现武器行为,以便子类可以更具体。

namespace Strategy
{
    class Character
    {
        public IWeaponBehavior weapon;

        public Character(IWeaponBehavior specificWeapon)
        {
            weapon = specificWeapon;
        }        
    }
}

namespace Strategy
{
    class Thief : Character
    {

    }
}

我该如何实现?我对实际代码需要的内容非常困惑。

我知道这可能要求太多,但如果你能写出实际的代码以便我可以研究它,那对你们来说会很好。我通过看代码来学习。 :P很多人都可以从这个问题中受益。

7 个答案:

答案 0 :(得分:26)

在班级Character中使用依赖注入?

public class Character
{
    public Character(IWeaponBehavior weapon) 
    {
        this.weapon = weapon;
    }

    public void Attack()
    {
        weapon.UseWeapon();
    }

    IWeaponBehavior weapon;
}

public class Princess: Character
{
    public Princess() : base(new Pan()) { }
}

public class Thief: Character
{
    public Thief() : base(new Knife()) { }
}

...

Princess p = new Princess();
Thief t = new Thief();

p.Attack(); // pan
t.Attack(); // knife

按要求编辑。

答案 1 :(得分:5)

有几种可能性。你真正要问的是,“特定角色应该如何知道使用哪种武器?”。

你可以有一个角色工厂,可以在角色中创建并注入正确类型的武器(听起来不对:)),或者让特定角色的构造者负责创建武器。

答案 2 :(得分:3)

  class Character
  {
    private IWeaponBehavior _weapon;

    // Constructor
    public Character(IWeaponBehavior strategy)
    {
      this._weapon = strategy;
    }

    public void WeaponInterface()
    {
      _weapon.UseWeapon();
    }
  }

答案 3 :(得分:1)

public class Character
{
    IWeaponBehavior Weapon;
}

public class Princess : Character
{
    Weapon = new Pan();
}

public class Thief : Character
{
    Weapon = new Knife();
}

答案 4 :(得分:1)

看一下依赖注射&然后还要研究控制反转。

TekPub使用与您非常相似的样本,对这两个想法有很好的免费情节。这应该可以帮助您获得具体的样本。 : - )

http://tekpub.com/view/concepts/1

视频中的示例代码:

class Samurai {
  IWeapon _weapon;

  public Samurai() {
   _weapon = new Sword();
  }

  public Samurai(IWeapon weapon) {
   _weapon = weapon;
  }

  public void Attack(string target) {
    _weapon.Hit(target);
  }
}

以上是DI(使用IWeapon构造函数)。现在添加Inversion of Control可以获得更多控制权。

使用IOC容器,您可以通过注射而不是类本身来控制IWeapon。

该视频使用NInject作为IOC,并展示如何消除IWeapon构造函数并获得对类和所有需要使用IWeapon的类的控制权,以便在一个位置/配置区域中使用您想要的内容。

来自视频的示例:

class WarriorModule: NinjectModule {
  public override void Load() {
   Bind<IWarrior>().To<Samurai>();
   Bind<IWeapon>().To<Sword>();
}

以上配置告诉NInject每当遇到使用武士的IWarrior时,以及每当它鼓励IWeapon使用Sword时。

该视频继续解释这一小改变如何提高您的灵活性。它为使用远程武器等的Samuria添加了另一个模块....

您可以根据需要/想要更改这些。

答案 5 :(得分:0)

这是一篇关于在C#中使用此模式的非常专注的文章:http://www.lowendahl.net/showShout.aspx?id=115

答案 6 :(得分:0)

如果你的角色都有自己特定的武器,你实际上并不需要使用战略模式。您可以使用普通多态。但无论如何,战略模式可能更清洁。

你只需要对武器进行初始化:

public class Character
{
     IWeapenBehavior weapon;

     public Attack()
     {
          weapon.UseWeapon();
     }
}


public class Thief : Character
{
      Thief()
      {
           weapon = new Knife();
      }
}

在控制角色的代码中,您可以调用Attack()方法。