10

こんにちは、ユーザーに多くの制限を課すことなく、読み取り可能でエラーを防止する Fluent-API を構築する方法を理解しようとしています。

簡単にするために、次のクラスを流暢に変更したいとしましょう

public class Car
{
    public int Gallons { get; private set; }
    public int Tons { get; private set; }
    public int Bhp { get; private set; }
    public string Make { get; private set; }
    public string Model { get; private set; }

    public Car(string make, string model)
    {
        Make = make;
        Model = model;
    }

    public void WithHorsePower(int bhp)
    {
        Bhp = bhp;
        return this;
    }

    public void WithFuel(int gallons)
    {
        Gallons = gallons;
    }

    public void WithWeight(int tons)
    {
        Tons = tons;
    }

    public int Mpg()
    {
        return Gallons/Tons;
    }
}

この場合の問題は、ユーザーが最初に呼び出されたMpg()場合Weight()にのみアクセスできるようにする必要Fuel()があり、その位置もHorsePower()関係ありません。

サンプル:

int mpg =Car.Create().HorsePower().Fuel().Weight().Mpg();
int mpg =Car.Create().Fuel().HorsePower().Weight().Mpg();
int mpg =Car.Create().HorsePower().Fuel().HorsePower().Weight().Mpg();// <- no typo
int mpg =Car.Create().Fuel().Weight().HorsePower().Mpg();
int mpg =Car.Create().Weight().HorsePower().Fuel().Mpg();
int mpg =Car.Create().Weight().Fuel().Mpg();

大量のインターフェースなしでこれを行う簡単な方法はありますか?
また、このネストされたインターフェイスを正しい方法で実装する方法もわかりません

ここに私が現在作成しているインターフェースがあります

interface Start
{
    IFuelWeight1 HorsePower();

    IHorsePowerWeight1 Fuel();

    IHorsePowerFuel1 Weight();
}

interface IFuelWeight1 // Start.HorsePower()
{
    IHorsePowerWeight1 Fuel();

    IHorsePowerFuel1 Weight();
}

interface IHorsePowerWeight1 // Start.Fuel()
{
    IHorsePowerWeight1 HorsePower();

    IHorsePowerFuelMpg Weight();
}

interface IHorsePowerFuel1 // Start.Weight()
{
    IHorsePowerFuel1 HorsePower();

    IHorsePowerWeightMpg Fuel();
}

#region End

interface IHorsePowerFuelMpg
{
    IFuelWeightMpg HorsePower();

    IHorsePowerWeightMpg Fuel();

    int Mpg();
}

interface IHorsePowerWeightMpg
{
    IFuelWeightMpg HorsePower();

    IHorsePowerFuelMpg Weight();

    int Mpg();
}

interface IFuelWeightMpg
{
    IHorsePowerWeightMpg Fuel();

    IHorsePowerFuelMpg Weight();

    int Mpg();
}

#endregion

Adam Houldsworthの編集:-)

  • 上記のインターフェースは良いものですか、それともこれを行う簡単な方法はあります 、Mpg() の制限を保持していますか?
  • これを行うために上記のインターフェースを実装する方法は?:

        var k = myMiracle as Start;
        k.Fuel().Weight();
        k.Weight().Fuel();
        k.HorsePower().Fuel().Weight();
        k.HorsePower().Weight().Fuel();
        k.Fuel().HorsePower().Weight();
        k.Weight().HorsePower().Fuel();
    
4

2 に答える 2

9

1 つの代替手段として、Mpg() ですべての操作を呼び出し、他の操作を条件付きにすることができます。

これは、コードサンプルを使用して SO で既に回答されています。条件付きビルダー メソッド チェーンの流暢なインターフェイスを参照してください。

投稿は、インターフェイスの代わりに、コンストラクターを使用して、他のすべての操作を条件付きにする呼び出しメソッドを使用して同じことが達成される可能性があることを示しています。

于 2013-12-19T16:03:47.700 に答える