Как использовать шаблон стратегии с С#?
Вот что я до сих пор:
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 Многие люди могут воспользоваться этим вопросом.
Ответы
Ответ 1
Использовать инъекцию зависимостей в классе 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
Отредактировано в соответствии с запросом.
Ответ 2
Есть несколько возможностей. То, о чем вы действительно спрашиваете, "как должен конкретный персонаж знать, какое оружие использовать?".
Вы можете либо иметь символ factory, который создавал бы и вводил правильный тип оружия в символ (это звучало неправильно:)), или пусть конструктор определенного персонажа позаботится о создании оружия.
Ответ 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
Взгляните на инъекцию зависимостей, а затем посмотрите на инверсию управления.
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.
Далее показано, как это небольшое изменение увеличивает вашу гибкость. Он добавляет еще один модуль для самурии, который использует оружие дальнего боя и т.д.
Вы можете изменить их по мере необходимости/желаемого.
Ответ 6
Вот очень целенаправленная статья об использовании этого шаблона в С#: http://www.lowendahl.net/showShout.aspx?id=115
Ответ 7
Если у ваших персонажей есть свое собственное специальное оружие, вам фактически не нужно использовать шаблон стратегии. Вы можете использовать простой полиморфизм. Но шаблон стратегии может быть чистым в любом случае.
Вам просто нужно ввести в заблуждение оружие:
public class Character
{
IWeapenBehavior weapon;
public Attack()
{
weapon.UseWeapon();
}
}
public class Thief : Character
{
Thief()
{
weapon = new Knife();
}
}
В коде, который управляет вашими символами, вы можете вызвать метод Attack()
.