How to use the Strategy Pattern with C#?

浪子不回头ぞ 提交于 2019-11-29 12:18:07

问题


Here's what I have so far:

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!");
        }
    }
}

Now if I have a Character.cs superclass. how can that superclass implement a weaponbehavior so that children classes can be more specific.

namespace Strategy
{
    class Character
    {
        public IWeaponBehavior weapon;

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

namespace Strategy
{
    class Thief : Character
    {

    }
}

How can I implement this? I'm very confused on what the actual code needs to be.

I know this might be asking too much, but if you could write the actual code so I could study it, that would be very nice of you guys. I learn by seeing code. :P Many people could benefit from this question.


回答1:


Use dependency injection in class 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

Edited as requested.




回答2:


There's a few possibilities. What you're really asking is, "how should a specific character know which weapon to use?".

You could either have a Character factory that would create and inject the right type of weapon into the character (That sounded wrong :) ), or let the constructor of a specific character take care of creating the weapon.




回答3:


  class Character
  {
    private IWeaponBehavior _weapon;

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

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



回答4:


public class Character
{
    IWeaponBehavior Weapon;
}

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

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



回答5:


Take a look at dependency injection & then also look into Inversion of Control.

TekPub has a great free episode on these two ideas using a sample very similar to yours. This should help you with a concrete sample. :-)

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

Sample code from video:

class Samurai {
  IWeapon _weapon;

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

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

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

The above is DI (with IWeapon constructor). Now adding Inversion of Control you gain even more control.

Using an IOC container you will be able to control the IWeapon via injection instead of in the class itself.

The video uses NInject as it's IOC and shows how you can eliminate the IWeapon Constructor and gain control over the class and all classes needing to use IWeapon to use what you want in one location/configuration area.

Sample from video:

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

The above configuration tells NInject that whenever it encounters an IWarrior to use Samurai and whenever it encourters an IWeapon to use Sword.

The video goes on to explain how this little change increases your flexibility. It adds another Module for a Samuria who uses a ranged weapon, etc....

You can change these as needed/wanted.




回答6:


Here's a very focused article on using this pattern in C#: http://www.lowendahl.net/showShout.aspx?id=115




回答7:


If your characters all have their own specific weapon, you don't actually need to use the strategy pattern. You could use plain polymorphism. But the strategy pattern could be cleaner anyway.

You just need to intitialize the weapon:

public class Character
{
     IWeapenBehavior weapon;

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


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

In the code that controls your Characters, you can call the Attack() method.



来源:https://stackoverflow.com/questions/3449634/how-to-use-the-strategy-pattern-with-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!