4

DbCメソッドでは、関数に事前条件と事後条件がついていることがわかりました。

私が疑問に思っているのは、それがメンバー関数にも当てはまるかどうかです。

たとえば、各パブリック関数の最初と最後で不変条件を使用すると仮定すると、メンバー関数は次のようになります。

編集:(私の例をクリーンアップ)

void Charcoal::LightOnFire() {
  invariant();
  in_LightOnFire();

  StartBurning();    
  m_Status = STATUS_BURNING;
  m_Color = 0xCCCCCC;

  return; // last return in body

  out_LightOnFire();
  invariant();
}

inline void Charcoal::in_LightOnFire() {
  #ifndef _RELEASE_
  assert (m_Status == STATUS_UNLIT);
  assert (m_OnTheGrill == true);
  assert (m_DousedInLighterFluid == true);
  #endif
}

inline void Charcoal::out_LightOnFire() {
  #ifndef _RELEASE_
  assert(m_Status == STATUS_BURNING);
  assert(m_Color == 0xCCCCCC);
  #endif
}

// class invariant
inline void Charcoal::invariant() {
  assert(m_Status == STATUS_UNLIT || m_Status == STATUS_BURNING || m_Status == STATUS_ASHY);
  assert(m_Color == 0x000000 || m_Color == 0xCCCCCC || m_Color == 0xEEEEEE);
}

グローバル/ジェネリック関数のみで事前条件と事後条件を使用し、クラス内で不変条件を使用しても問題ありませんか?

これはやり過ぎのように思えますが、私の例が悪いのかもしれません。

編集:

事後条件は、不変条件のサブセットをチェックしているだけではありませんか?

上記では、 http://www.digitalmars.com/ctg/contract.htmlの指示に従っています。「クラス コンストラクターが完了すると、クラス デストラクタの開始時、public の前に不変式がチェックされます。メンバーが実行され、パブリック関数が終了した後。」

ありがとう。

4

3 に答える 3

5

クラス内のコントラクトを不変条件に制限することは最適ではありません。

事前条件と事後条件は、単なる不変条件のサブセットではありません。

不変条件、事前条件、および事後条件には、非常に異なる役割があります。

不変条件は、オブジェクトの内部コヒーレンスを確認します。これらは、コンストラクターの最後と、各メソッド呼び出しの前後で有効である必要があります。

前提条件は、オブジェクトのステータスと引数がメソッドの実行に適していることを確認しています。前提条件は、不変条件を補完します。それらは引数のチェック (型自体、つまり、null でない、> 0 などのより強力なチェック) をカバーしますが、オブジェクトの内部ステータス (つまり、file.write( "hello" ) への呼び出しがfile.is_rw と file.is_open が true の場合にのみ有効な呼び出しです)。

事後条件は、メソッドがその義務を満たしていることを確認しています。事後条件は、不変条件を補完するものでもあります。もちろん、オブジェクトのステータスはメソッドの実行後に一貫している必要がありますが、事後条件は、期待されるアクションが実行されたことを確認しています (つまり、list.add(i) は、list.has(i) が true であることを結果として持つ必要があります)。および list.count = 古い list.count + 1)。

于 2009-09-19T21:27:15.753 に答える
2

さて、不変条件のポイントは、常にオブジェクトに当てはまることを説明しているということです。この場合、何かがグリルの上にあるかどうか (間に何もない)。それらは通常、オブジェクトの状態全体のプロパティを記述します。

事前条件と事後条件は、メソッドが実行される直前と直後に真であることを記述し、メソッドによって処理されるべき状態にのみ関係します。これはおそらく、オブジェクトの状態とは異なります。事前条件と事後条件は、メソッドのフットプリントを記述するものと考えることができます。つまり、メソッドが必要としているもの、メソッドが触れたものだけです。

したがって、特定の質問に対して、アイデアは異なることを行うため、両方が必要になる場合があります。確かに、事前条件と事後条件の代わりに不変条件を使用することはできません。この場合、オブジェクトの不変条件の一部は「何かがグリルの上にあるかどうか」ですが、lightOnFire の前提条件は、アイテムがグリルの上にあることを知る必要があります。オブジェクトの不変式からこれを推測することはできません。事前条件と事後条件、および既知の開始状態から、(オブジェクト構造がメソッドによってのみ変更可能であり、事前条件と事後条件がすべての環境変化を記述すると仮定して) オブジェクト不変を推測できることは事実です。ただし、これは複雑になる可能性があり、「言葉で」物事を述べる場合は、両方を提供する方が簡単です。

もちろん、ブール項目が true または false のいずれかであると述べるバリアントで行うことは、少し無意味です。型システムがそれを保証します。

于 2009-08-02T20:17:13.350 に答える