3

パブリック メソッドの事前条件事後条件は、このメソッドとそのクライアントの間の契約を形成します。

1.によると呼び出し元は事後条件を検証してはならず、呼び出されたメソッドは事前条件を検証してはなりません:

プログラム 49.2 に示すように、平方根関数 sqrt の事前条件と事後条件を思い出してください。sqrt を呼び出す関数は、負でない数値を関数に渡す必要があります。負の数が渡された場合、平方根関数はそれを処理するために何もしません。一方、負でない数値が sqrt に渡された場合、事後条件を満たす結果を返すのは sqrt の責任です。したがって、sqrt の呼び出し元は、結果を確認または修正するために何もする必要はありません。

操作の事前条件が失敗した場合、呼び出し元を非難する 操作の事後条件が失敗した場合、呼び出された操作を非難する

しかし、別の記事に含まれるコードに見られるように、呼び出されたメソッドは前提条件を検証します:

/// <summary>Gets the user for the given ID.</summary>
public User GetUserWithIdOf(int id,
        UserRepository userRepository) {
  // Pre-conditions
  if (userRepository == null)
      throw new ArgumentNullException(
          "userRepository");
  if (id <= 0)
      throw new ArgumentOutOfRangeException(
          "id must be > 0");

  User foundUser = userRepository.GetById(id);

  // Post-conditions
  if (foundUser == null)
      throw new KeyNotFoundException("No user with " +
          "an ID of " + id.ToString() +
          " could be located.");

  return foundUser;
}

a)メソッド の前提条件を満たすことはクライアントの責任であるため、呼び出されたメソッド前提条件が満たされているかどうかを確認する必要がありますか?

b)事後条件を満たす結果を提供するのは呼び出されたメソッドの責任であるため、呼び出し元は事後条件をチェックする必要がありますか?

2.最初の記事で述べた利点の 1 つは、「事前条件と事後条件を使用して、OOP のクラス間で責任を分割できる」ことです。これは、呼び出されたメソッドが前提条件を検証する責任を負わないことも理解しています。 postconditionを検証する呼び出し元の責任ではありません。

しかし、そのような哲学に固執すると、コードがより脆弱になるのではないでしょうか? コードは相手 (呼び出し元またはメソッドのいずれか) が約束を果たすことを盲目的に信頼するからです。

3.呼び出し元/呼び出されたメソッドが相手を盲目的に信頼していない場合、事後条件事前条件によって提供される利点の多くを失うことはありません。これは、呼び出されたメソッドが前提条件もチェックする責任を負い、呼び出し元が責任を負う必要があるためです。事後条件を確認するには?

ありがとう

編集

3.

呼び出し元/呼び出されたメソッドが other party を盲目的に信頼していない場合、事後条件と事前条件によって提供される利点の多くを失うことはありません。これは、呼び出されたメソッドが前提条件もチェックする責任を負い、呼び出し元が検証する責任を負う必要があるためです。事後条件?

事後条件は呼び出されたメソッドによって保証される必要があるため、呼び出し元は事後条件を検証する必要はありません。コントラクトを強制する他の方法がないため、呼び出されたメソッドは前提条件を確認する必要があります。

a)事後条件は、戻り値が指定された型であること、またはnull( 戻り値nullableの場合)であることのみを述べる/保証する必要があると想定していますか? 戻り値がどのタイプになるかの他に、戻り値が指定された範囲内にあるかどうかなど、他のことを事後条件で指定することはできませ(これは type system では検証できません) (例:事後条件でその戻り値を指定することもできません)の範囲内になります)? この場合、クライアントはpostconditionもチェックする必要があるのではないでしょうか?int10-20

b) それでは、最初の記事は、呼び出されたメソッドが前提条件をチェックしてはならないという主張が間違っていると言えますか?

2.編集

いいえ、事後条件は null チェックだけでなく、何でもかまいません。どちらの方法でも、クライアントは事後条件が検証済みであると想定できるため、たとえば、契約で保証されていると記載されている場合、int 範囲を検証する必要はありません。

a) 以前、コードの脆弱性を軽減するために、呼び出されたメソッドによって事前条件をチェックする必要があると述べましたが、呼び出し元が事後条件を検証する必要があることも理由にできませんでした(たとえば、返された値が事後条件によって約束された範囲内にあることを検証します)呼び出し元のコードの脆弱性を軽減するには?int

b)クライアントが事後条件によって行われたクレームを盲目的に信頼できる場合事後条件が戻り値がある範囲内にあるなどのクレームを作成する場合、それは盲目的な信頼だと思います)、呼び出されたメソッドも、呼び出し元が呼び出されたメソッドの前提条件を満たすことを信頼できないのはなぜですか?

4

1 に答える 1

3

a) メソッドの前提条件を満たすことはクライアントの責任であるため、呼び出されたメソッドも前提条件が満たされているかどうかを確認する必要がありますか?

はい、前提条件が満たされていることを確認するのはクライアントの責任ですが、呼び出されたメソッドはこれを確認する必要があるため、この例では null チェックが行われています。

b) 事後条件を満たす結果を配信するのは呼び出されたメソッドの責任であるため、呼び出し元は事後条件をチェックする必要がありますか?

呼び出し元は、呼び出されたメソッドのコントラクトに依存できる必要があります。あなたが提供した例では、メソッドGetUserWithIdOfは事後条件が満たされていることを確認し、それ以外の場合は例外をスローします。リポジトリ自体には、ユーザーが見つからない可能性があるため、常にユーザーを返すという事後条件はありません。

2.最初の記事で述べた利点の 1 つは、「事前条件と事後条件を使用して、OOP のクラス間の責任を分割できる」ことです。これは、呼び出されたメソッドが事前条件を検証する責任を負わないことも理解しています。事後条件を検証する呼び出し元の責任ではありません。

通常、事前条件は型システムでは検証できないため、事前条件を検証するのは呼び出されたメソッドの責任です。Eiffelなどの言語は、より高度な静的コントラクト検証を提供します。この場合、言語を利用して前提条件を適用できます。Java/C# と同様に、メソッド パラメーターが特定の型であることを強制できます。Eiffel は、この型の検証をより複雑な契約宣言に拡張します。

しかし、そのような哲学に固執すると、コードがより脆弱になるのではないでしょうか? コードは相手 (呼び出し元またはメソッドのいずれか) が約束を果たすことを盲目的に信頼するからです。

はい、そのため、前提条件を検証する必要があります。

3.呼び出し元/呼び出されたメソッドが相手を盲目的に信頼していない場合、事後条件と事前条件によって提供される利点の多くを失うことはありません。これは、呼び出されたメソッドが前提条件もチェックする責任を負い、呼び出し元が責任を負う必要があるためです。事後条件を確認するには?

事後条件は呼び出されたメソッドによって保証される必要があるため、呼び出し元は事後条件を検証する必要はありません。コントラクトを強制する他の方法がないため、呼び出されたメソッドは前提条件を確認する必要があります。

アップデート

a) いいえ、事後条件は null チェックだけでなく、何でもかまいません。どちらの方法でも、クライアントは事後条件が検証済みであると想定できるため、たとえば、契約で保証されていると記載されている場合、int 範囲を検証する必要はありません。

b) そうです。引用するには:

負の数が渡された場合、平方根関数はそれを処理するために何もしません。

ifは、呼び出されたメソッドがすでに何らかの検証を行っていることを示しています。何もしないことは暗黙の失敗であり、アンチパターンになる可能性があります。

その後の引用:

操作の事前条件が失敗した場合、呼び出し元を非難する 操作の事後条件が失敗した場合、呼び出された操作を非難する

前提条件が失敗したことを呼び出し元のせいにする唯一の方法は、最初に前提条件が失敗したことを確認することです。呼び出されたメソッドはこの前提条件を「所有」しているため、失敗のフラグを立てる最後の停止にする必要があります。

更新 2

a,b) 呼び出し元が事後条件を信頼できる理由は、呼び出されたメソッドによって事後条件が保証されるためです。呼び出されたメソッドは、コントラクトを宣言して所有するものです。呼び出されたメソッドが呼び出し元を信頼できない理由は、事前条件が満たされることを保証する人がいないためです。呼び出されたメソッドは、さまざまな呼び出し元をすべて認識しているわけではないため、独自に検証する必要があります。

于 2013-05-01T18:57:02.417 に答える