1

新しい Web API 用の C# ラッパー ライブラリを作成しています。

このサービスは、いくつかの API のセットを提供します。各メソッドは、いくつかの必須パラメーターといくつかのオプションのパラメーターを受け取ります (各メソッドは、異なる必須/オプションのパラメーターを受け取る場合があります)。

パラメータは、param=value¶m2=value2&....の長い文字列として POST メソッドで送信されます。

インターフェイス ベースの設計に慣れてきたので、この場合に適していますか?

メソッドのオーバーロードを作成せずに、API のすべてのメソッドとパラメーターを単一のインターフェイスにマッピングするための適切なソリューションを見つけることができず、ユーザーが使用するのが難しくなります。

それがどのように見えるかの例:

public interface IServiceAPI
{
    void MethodA(string mandatory, string mandatory2);
    void MethodA(string mandatory, string mandatory2, int optional);
    void MethodB(string mandatory);

    ... etc
}
  • .NET 4 で導入されたオプションのパラメーターを認識しています。このライブラリは .NET の下位バージョンを対象としているため、これは適切な解決策ではありません。また、「オプションのパラメーター」は実際にはデフォルト値を設定する方法にすぎないため、パラメータの値を送信しないためではありません。

インターフェイスベースのデザインはここに適していますか? または別の言い方をすれば、インターフェイス ベースのデザインが最も適しているのはどこでしょうか?

4

5 に答える 5

2

まず、多くのオーバーロードを使用してインターフェイスを設計することは良い考えではないと思います。関数が何か違うことをしない限り、インターフェイスを使用する人がデフォルト値を入れたい場合は、それをそのままにしておく必要があります。

とはいえ、次に、あなたが書いているエンティティは、基本クラスとしてより役立つようです。ServiceAPI という名前は、少なくともある程度の標準機能を暗示しています。このようにして、複数のオーバーロードを作成し、子クラスにプライマリ メソッドをオーバーライドさせることができます。

于 2012-05-09T15:55:54.483 に答える
1

インターフェースは正しい方法ですが、間違ったインターフェースを使用していると思います。次のようにIOptionalParameterインターフェイスを作成します。

interface IOptionalParameter<T>
{
    public bool IsSet {get;}
    public T Value {get;}
}

次に、APIで1つのメソッドのみを公開し、各引数のタイプをIOptionalParameterにすることができます。

これにより、URLリクエスト文字列を作成するために使用するコードもすっきりします。理にかなっている場合は、インターフェイスにNameプロパティを追加して、さらに単純化することもできます。

アップデート

3つの異なるアプローチとそれらの間のトレードオフを要約すると、次のようになります。

  1. 過負荷-パラメータがオプションであることは明らかですが、実装の潜在的な違いに関して混乱を招き、実装を少し混乱させます
  2. null許容型-パラメーターがオプションであることはあまり明確ではありませんが、実装側ではよりクリーンです
  3. IOptionalParameter-パラメーターがオプションであるかどうかを明示的に示し、実装はクリーンですが、クライアント側から呼び出すのは恐ろしいです
于 2012-05-09T16:00:33.843 に答える
1

メソッドには複数のパラメーターがある傾向があるようです。私の経験では、最大 3 つの引数が必要です。この問題を解決するには (そして副作用として、オプション/必須パラメーターの解決策を見つけます)、パラメーターをクラスにパックすることをお勧めします。

class MethodAParameters
{
    public string Required1 {get;set;} //add validation in setter (nulls are not allowed)
    public string Required2 {get;set;} //add validation in setter (nulls are not allowed)
    public int? Optional1 {get;set;} //nulls allowed

    public MethodAParameters(string required1, string required2)
    {
        Required1 = required1;
        Required2 = required2;
    }
}

ご覧のとおり、このような設計では、必須パラメーターを渡すことが強制され (パラメーターを指定せずに引数インスタンスを作成することはできません)、オプションのパラメーターを追加できます。もちろん、一部のメソッドが同じ引数のサブセットを共有している場合は、パラメーター クラスを継承する必要があります。

null 値も関連する場合は、前述の IOptionalParameter が必要と思われます (このパラメーター クラスのアプローチと組み合わせる)。

コードはSOLIDである必要があることに注意してください。あなたが提供した例を見ると、単一責任の原則が気になります。もちろん、実際のコードを知らずに推測しているだけなので、アドバイスとして扱ってください。

于 2012-05-12T00:37:11.837 に答える
0

Null許容データ型?

たとえば、代わりに

void MethodA(string mandatory, string mandatory2);
void MethodA(string mandatory, string mandatory2, int optional);

これを次のように単純化できます

void MethodA(string mandatory, string mandatory2, int? optional);

ただし、オプションのパラメーターが参照型の場合、null を渡すだけでよいことが呼び出し元には明らかではない可能性があります。

v のように多くのオプションのパラメーターがある場合oid MethodC(string mandatory, string mandatory2, string optional1, int? optional1, string optional2);、考えられるすべての組み合わせに対して署名を提供したくない場合は、次のように単純に提供できます。

MethodC(string mandatory, string mandatory2) // for people that just want the basic functionality
MethodC(string mandatory, string mandatory2, string optional1, int? optional1, string optional2); // for people that want to specify extra, and they can pass null for some of the optional ones if they like.
于 2012-05-09T15:56:20.520 に答える
0

通常のクラスではなく、なぜインターフェイスとして必要なのかわかりません。他のクラスがこのインターフェースを実装する予定ですか、それとも API にアクセスするための標準的な方法を探しているだけですか?

API にアクセスするための標準的な方法を探しているだけなら、ビルダー パターンのバリエーションをお勧めします。ビルダー パターンは通常、クラスに使用されますが、メソッドにも使用できない理由がわかりません。クラスベースの例については、http://cdmckay.org/blog/2009/07/03/joshua-blochs-builder-pattern-in-csharp/を参照してください。

あなたが提供したものを考えると、これが私の試みです。構文エラーがある場合は申し訳ありませんが、自宅のエディターはやや不足しています...

public class AccessServiceAPI
{
    private void MethodA(string mandatory, string mandatory2, string optional)
    {
        // do stuff
    }

    public class MethodABuilder
    {
        private string Mandatory { get; set; }
        private string Mandatory2 { get; set; }
        private string Optional { get; set; }

        public MethodABuilder( string mandatory, string mandatory2)
        {
            Mandatory = mandatory;
            Mandatory2 = mandatory;
            Optional = "default value";
        }

        public MethodABuilder Optional( string optional )
        {
            Optional = optional;
            return this;
        }

        public void Build()
        {
            MethodA(mandatory, mandatory2, optional);
        }
    }
}

クライアントは、次のようにメソッドを呼び出します。

MethodABuilder.Builder(mandatory, mandatory2).Optional(optional).Build();

オプションのパラメーターに値を設定したくない場合は、スキップできます。

于 2012-06-08T05:05:29.443 に答える