1

如果有如下3个接口

public interface IWeapon {
void Kill();
}

public interface ISword:IWeapon {
void Slice();
}

public interface IShuriken: IWeapon {
void Pierce();
}

public class Ninja {
public IWeapon Weapon {get;set;}
public void BrutalKill() {

/* warrior must pierce, pierce, pierce and then kill 


*/

}
public void HonorKill {
/* warrior must kill by one slice */
}
}

对于这样的场景,您将如何连接容器以及 BrutalKill 和 HonorKill 的方法主体是什么样的?

编辑:根据评论,我在想忍者应该装备武器......如果它想装备剑或手里剑......应该稍后决定......不确定我是否在想对 .. 也许我们需要将 Ninja 子类化为 NinjaWithShuriken 和 NinjaWithSword

4

4 回答 4

3

不确定这是否是您要找的东西,但我会这样做:

// 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.
于 2009-12-17T22:56:36.020 回答
1

如果你的忍者能够野蛮杀戮和荣誉杀戮,他绝对必须有一个ISword和一个IShuriken。Ninja 依赖于这些,所以我们在 ctor 中声明它们:

public class Ninja
{
    readonly IShuriken shuriken;
    readonly ISword sword;

    public Ninja(IShuriken sh, ISword sw)
    {
        shuriken = sh;
        sword = sw;
    }

    public void BrutalKill()
    {
        shuriken.Pierce();
        shuriken.Pierce();
        shuriken.Pierce();
        sword.Slice();
        shuriken.Kill();
    }

    public void HonorKill()
    {
        sword.Slice();
        sword.Kill();
    }
}

这是我们的武器:

public interface IWeapon
{
    void Kill();
}

public interface IShuriken : IWeapon
{
    void Pierce();
}

public interface ISword : IWeapon
{
    void Slice();
}

让我们来看看这些依赖项的几个实现:

using System;

public class BronzeShuriken : IShuriken
{
    public void Pierce()
    {
        Console.WriteLine("Bronze shuriken pierce time now!");
    }

    public void Kill()
    {
        Console.WriteLine("Bronze shuriken kill!!!");
    }
}

public class RustySword : ISword
{
    public void Slice()
    {
        Console.WriteLine("Rusty sword slice time now!");
    }

    public void Kill()
    {
        Console.WriteLine("Rusty sword kill!!!");
    }
}

我们的配置如下所示:

using Ninject.Modules;

class DefaultModule : NinjectModule
{
    public override void Load()
    {
        Bind<IShuriken>().To<BronzeShuriken>();
        Bind<ISword>().To<RustySword>();
    }
}

我们的入口点如下所示:

    static void Main()
    {
        using (var kernel = new StandardKernel())
        {
            kernel.Load(new DefaultModule());

            kernel.Get<Ninja>().BrutalKill();
        }
    }
于 2009-12-17T23:31:10.993 回答
1

Kill(),没有参数,好像你在命令忍者自杀。我会定义Ninja对其他忍者采取行动:

public interface INinja
{
    void KillBrutally(INinja otherNinja);

    void KillHonorably(INinja otherNinja);
}

然后,提高从武器到杀招的抽象级别:

public interface IKillMove
{
    void Kill(INinja ninja);
}

并让忍者支持杀戮类型:

public sealed class Ninja : INinja
{
    private readonly IKillMove _brutalKillMove;
    private readonly IKillMove _honorableKillMove;

    public Ninja(IKillMove brutalKillMove, IKillMove honorableKillMove)
    {
        _brutalKillMove = brutalKillMove;
        _honorableKillMove = honorableKillMove;
    }

    #region INinja

    public void KillBrutally(INinja otherNinja)
    {
        _brutalKillMove.Kill(otherNinja);
    }

    public void KillHonorably(INinja otherNinja)
    {
        _honorableKillMove.Kill(otherNinja);
    }
    #endregion
}

现在我们可以担心武器了:

public interface IWeapon
{
    void Attack(INinja ninja);

    void Finish(INinja ninja);
}

并杀死动作:

public sealed class MoveInKillMove : IKillMove
{
    private readonly IWeapon _shortRangeWeapon;
    private readonly IWeapon _longRangeWeapon;

    public MoveInKillMove(IWeapon shortRangeWeapon, IWeapon longRangeWeapon)
    {
        _shortRangeWeapon = shortRangeWeapon;
        _longRangeWeapon = longRangeWeapon;
    }

    #region IKillMove

    public void Kill(INinja ninja)
    {
        _longRangeWeapon.Attack(ninja);
        _longRangeWeapon.Attack(ninja);
        _longRangeWeapon.Attack(ninja);

        _shortRangeWeapon.Finish(ninja);
    }
    #endregion
}

public sealed class FinishingMove : IKillMove
{
    private readonly IWeapon _weapon;

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

    #region IKillMove

    public void Kill(INinja ninja)
    {
        _weapon.Finish(ninja);
    }
    #endregion
}

这是一个示例接线(根据需要转换为您的 IoC 容器):

var sword = new Sword();

var ninja = new Ninja(
    new MoveInKillMove(sword, new Shuriken()),
    new FinishingMove(sword));
于 2009-12-18T01:58:18.543 回答
0

团结一致:

Container.RegisterType<INinja,Ninja>();
Container.RegisterType<ISword,Sword>();
Container.RegisterType<IShuriken,Shuriken>();

假设忍者同时拥有剑和手里剑,因为只有剑可以切割,只有手里剑可以刺穿。

此外,Ninja 有一个接受 IShuriken 和 ISword 作为参数的构造函数。

所以为了得到忍者,

var ninja= Container.Resolve<INinja>();
于 2009-12-18T00:09:04.783 回答