2

非常に頻繁に、同様のアーキテクチャの問題に遭遇します。入力された引数の妥当性をどのくらいの頻度でチェックする必要がありますか? 次の例を確認してみましょう (コードの正確性やコンパイル可能性は気にしないでください)。

public void DoSth()
{
    context.DbPerform((SQLiteConnection connection) =>
        {
            // *** 1 ***
            if (connection == null)
                throw new ArgumentNullException("connection");
            if (!connection.IsOpen)
                connection.Open();

            try
            {
                Data.Insert(data, connection);
            }
            finally
            {
                connection.Close();
            }
        });
}

// ----

public static void Insert(Data data, SQLiteConnection connection)
{
    // *** 2 ***

    if (data == null)
        throw new ArgumentNullException("data");
    if (connection == null)
        throw new ArgumentNullException("connection");

    if (!connection.IsOpen)
        connection.Open();

    try
    {
        using (var cmd = connection.CreateCommand())
        {
            cmd.CommandText = SQL.InsertData;

            FillParameters(data, connection, cmd);

            cmd.ExecuteNonQuery();
        }
    }
    finally
    {
        connection.Close();
    }
}

// ----

public static void FillParameters(Data data,
    SQLiteConnection connection,
    SQLiteCommand cmd)
{
     // *** 3 ***
     if (connection == null)
         throw new ArgumentNullException("connection");

     // And so on, you get the idea
}

前のスニペットでは、接続が null またはクローズされているかどうかが 3 回チェックされています。これは私には少しやり過ぎのように思えます。メソッド本体の 50% がセキュリティ チェックである場合もあります。それほど多くのセキュリティチェックが必要だとは思いませんが、一方で、他の誰かが常にこれらのメソッドを使用する可能性があり、彼が有効なパラメーターを渡したかどうかはわかりません.

だから私の質問は:

  • 渡されたパラメーターに関するセキュリティチェックをどのくらいの頻度で作成する必要がありますか?
  • セキュリティのレベルを維持するために使用できる技術は何ですか?
  • 無効な入力をチェックしている間、どの程度偏執的である必要がありますか? 別の例を考えてみましょう:
class C
{
    private Obj obj;

    public C (Obj newObj)
    {
        if (newObj == null)
            throw new ArgumentNullException("newObj");

        obj = newObj;
    }

    public void DoSth()
    {
        // Should I check, whether obj is not null?
    }
}
4

2 に答える 2

3

最初の例に関しては、 is でInsert()あるため、チェックインは良い考えInsert()ですpublic。チェックが行われなかった別のコンテキストから呼び出される可能性があります。

一般に、常にパブリック インターフェイス ポイントで検証します。これは、コードを疎結合にして再利用可能にするのに役立ちます。

そして、すべてのレイヤー (層、メソッド) には独自の要件があります。そのため、そのタスクの開始時に、特定のタスクを実行するために必要なことを検証します。

于 2013-07-15T08:54:55.173 に答える
1

私はヘンクに同意します。さらに、コードで事前条件、事後条件、およびオブジェクト不変条件を指定する方法を提供する Visual Studio の Code Contracts 拡張機能を検討してみてください: http://visualstudiogallery.msdn.microsoft.com/1ec7db13-3363-46c9-851f-1ce455f66970。コードを保護するための非常に一貫した方法を強制し、ツール「Pex」を使用してコントラクトに基づいてテストを自動生成できます。

于 2013-07-15T08:58:56.543 に答える