Как использовать шаблон стратегии с C #? - PullRequest
16 голосов
/ 10 августа 2010

Вот что у меня есть:

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 ]

26 голосов
/ 10 августа 2010

Использовать внедрение зависимостей в классе 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

Отредактировано по запросу.

5 голосов
/ 10 августа 2010

Есть несколько возможностей.То, что вы на самом деле спрашиваете: «Как конкретный персонаж должен знать, какое оружие использовать?».

У вас может быть фабрика персонажей, которая будет создавать и вводить правильный тип оружия в персонажа (То естьзвучит неправильно :)), или пусть конструктор конкретного персонажа позаботится о создании оружия.

3 голосов
/ 10 августа 2010
  class Character
  {
    private IWeaponBehavior _weapon;

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

    public void WeaponInterface()
    {
      _weapon.UseWeapon();
    }
  }
1 голос
/ 10 августа 2010

Посмотрите на внедрение зависимостей, а затем посмотрите на Inversion of Control.

У 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 Constructor и получить контроль над классом и всеми классами, которым необходимо использовать IWeapon для использования того, что вы хотите, в одной области / конфигурации.

Пример из видео:

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

Приведенная выше конфигурация сообщает NInject, что всякий раз, когда он встречает IWarrior для использования самураев, и всякий раз, когда он использует IWeapon для использования Sword.

В видео рассказывается, как это небольшое изменение повышает вашу гибкость.Он добавляет еще один модуль для самурии, которая использует оружие дальнего боя и т. Д.

1025 * Вы можете изменить их по мере необходимости / *. 1026 *
1 голос
/ 10 августа 2010
public class Character
{
    IWeaponBehavior Weapon;
}

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

public class Thief : Character
{
    Weapon = new Knife();
}
0 голосов
/ 10 августа 2010

Если у всех ваших персонажей есть свое собственное оружие, вам на самом деле не нужно использовать шаблон стратегии. Вы могли бы использовать простой полиморфизм. Но шаблон стратегии в любом случае может быть чище.

Вам просто нужно инициализировать оружие:

public class Character
{
     IWeapenBehavior weapon;

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


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

В коде, который управляет вашими персонажами, вы можете вызвать метод Attack().

0 голосов
/ 10 августа 2010

Вот очень сфокусированная статья об использовании этого шаблона в C #: http://www.lowendahl.net/showShout.aspx?id=115

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...