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>());

更新 PhilSandlerのコメントが好きなので、それを反映するための簡単な更新:

// 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

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 に答える
1

あなたの忍者が BrutalKill と HonorableKill を実行できる場合、彼は絶対に ISword と ISShuriken を持っている必要があります。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 に答える
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 に答える