Может быть, попытаться сделать вашу композицию немного дальше. Вам действительно нужен только один тип с разными способностями, например:
public class Hero
{
private readonly string name;
private readonly IEnumerable<IHeroAbility> abilities;
public Hero(string name, [Optional] IEnumerable<IHeroAbility> abilities)
{
this.name = name;
this.abilities = abilities ?? new List<IHeroAbility> { new OhCrap() };
}
public void Attack()
{
Console.WriteLine(name);
foreach (var ability in abilities) ability.Execute();
Console.WriteLine();
}
}
Теперь подготовьте доступные способности:
public interface IHeroAbility
{
void Execute();
}
public class SwingSwordAbility : IHeroAbility
{
public void Execute()
{
Console.WriteLine("And with all his might the hero swung his sword down onto his opponent...");
}
}
public class ShootArrowAbility : IHeroAbility
{
public void Execute()
{
Console.WriteLine("The hero loads an arrow into his bow without blinking and launches it with fierce speed towards his opponant...");
}
}
public class CastFireBallAbility : IHeroAbility
{
public void Execute()
{
Console.WriteLine("The hero reaches deep into the underverse and hurls a ball of fire towards his opponant...");
}
}
public class OhCrap : IHeroAbility
{
public void Execute()
{
Console.WriteLine("The hero pats his pockets as if he forgot something at home...");
}
}
Затем составьте типы ваших героев:
class Program
{
static void Main(string[] args)
{
IHeroAbility swingSwordAbility = new SwingSwordAbility();
IHeroAbility shootArrowAbility = new ShootArrowAbility();
IHeroAbility castFireBallAbility = new CastFireBallAbility();
var fighter = new Hero("The Fighter", new[] { swingSwordAbility });
fighter.Attack();
var mage = new Hero("The Mage", abilities: new[] { castFireBallAbility });
mage.Attack();
var archer = new Hero("The Archer", abilities: new[] { shootArrowAbility });
archer.Attack();
var knight = new Hero("The Knight", abilities: new[] { swingSwordAbility, shootArrowAbility });
knight.Attack();
var paladin = new Hero("The Paladin", abilities: new[] { swingSwordAbility, castFireBallAbility });
paladin.Attack();
var ranger = new Hero("The Ranger",abilities: new[] { shootArrowAbility, castFireBallAbility });
ranger.Attack();
}
}
Если вам нужны более явные группы действий, вы можете изменить свой класс Hero
на что-то вроде этого:
public class Hero
{
private readonly string name;
private readonly IEnumerable<IHeroAbility> meleeAbilities;
private readonly IEnumerable<IHeroAbility> magicAbilities;
private readonly IEnumerable<IHeroAbility> rangedAbilities;
public Hero(
string name,
[Optional] IEnumerable<IHeroAbility> meleeAbilities,
[Optional] IEnumerable<IHeroAbility> magicAbilities,
[Optional] IEnumerable<IHeroAbility> rangedAbilities)
{
this.name = name;
var defaultAbilities = new List<IHeroAbility> { new OhCrap() };
this.meleeAbilities = meleeAbilities ?? defaultAbilities;
this.magicAbilities = magicAbilities ?? defaultAbilities;
this.rangedAbilities = rangedAbilities ?? defaultAbilities;
}
public void MeleeAttack()
{
var ability = meleeAbilities.First();
Console.WriteLine(name);
ability.Execute();
}
public void MagicAttack()
{
var ability = magicAbilities.First();
Console.WriteLine(name);
ability.Execute();
}
public void RangedAttack()
{
var ability = rangedAbilities.First();
Console.WriteLine(name);
ability.Execute();
}
}
Затем вы можете начать строить его так, чтобы включать более сложные логи c вроде расходы, связанные со способностями, перезарядкой, выбором способностей и т. д. c. et c.
Надеюсь, это поможет!