Не уверен, что это то, что вы ищете, но у меня было бы следующее:
// first some implementations
public class Sword : ISword {
public void Kill() { // imp }
public void Slice() { // imp }
}
public class Shuriken : IShuriken {
public void Kill() { // imp }
public void Pierce() { // imp }
}
// and I would change the Ninja class to
public class Ninja {
public ISword Sword { get; private set; }
public IShuriken Shuriken { get; private set; }
public Ninja(ISword sword, IShuriken shuriken) {
this.Sword = sword;
this.Shuriken = shuriken;
}
public void BrutalKill() {
Shuriken.Pierce();
Shuriken.Pierce();
Shuriken.Pierce();
// either weapon can kill
// so lets close the distance and use the sword
Sword.Kill();
}
public void HonorKill {
Sword.Slice();
}
}
// creating the class
// where Ioc.Resolve is specific to the container implementation
var ninja = new Ninja(IoC.Resolve<ISword>(), IoC.Resolve<IShuriken>());
Обновление
Мне нравится комментарий Фила Сэндлера, поэтому быстрое обновление, чтобы отразить это:
// a ninja interface
public interface INinja {
void BrutalKill();
void HonorKill();
}
// and then update the ninja class to
public Ninja : INinja {
...
}
// and have the ninja class created like this with the container
// resolving the dependencies:
var ninja = IoC.Resolve<INinja>();
Обновление
Основываясь на обновлении исходного вопроса, я бы сказал:
public interface IWeapon {
void Attack();
void Kill();
}
public class Sword : ISword {
public void Attack() {
// implement as a slash
}
...
}
public class Shuriken : IShuriken {
public void Attack() {
// implement as a pierce
}
...
}
Идея в том, что нам все равно, как Меч и Сюрикен реализуют Атаку, до тех пор, пока ниндзя может использовать их для выполнения своих обязанностей при вызове. Убийство может быть осуществлено так, как того желает конкретный субъект, если работа будет выполнена в рамках указанного соглашения, в данном случае - Атакующим.
// create the specific ninja
var swordNinja = new Ninja(IoC.Resolve<ISword>());
var shurikenNinja = new Ninja(IoC.Resolve<IShuriken>());
// with the ninja class updated to only have an IWeapon
// property that gets set in the constructor.