私はCoders at Workを読んでいますが、その中には不変条件について多くの話があります。私が理解した限りでは、不変式とは式の前後両方に当てはまる条件です。Logicコースを正しく覚えていれば、ループが正しいことを証明するのに役立ちます。
私の説明は正しいですか、何か見落としていませんか?プログラムでそれらを使用したことがありますか?もしそうなら、彼らはどのように利益を得ましたか?
私はCoders at Workを読んでいますが、その中には不変条件について多くの話があります。私が理解した限りでは、不変式とは式の前後両方に当てはまる条件です。Logicコースを正しく覚えていれば、ループが正しいことを証明するのに役立ちます。
私の説明は正しいですか、何か見落としていませんか?プログラムでそれらを使用したことがありますか?もしそうなら、彼らはどのように利益を得ましたか?
回答:
OOPでは、不変式は、プログラムが有効であるためにオブジェクトの存続期間中、常に真でなければならない一連のアサーションです。オブジェクトがその状態を変更するメソッドを現在実行していないときはいつでも、コンストラクタの終わりからデストラクタの始まりまで成立するはずです。
不変式の例としては、2つのメンバー変数の正確に1つがnullである必要があります。または、一方に特定の値がある場合、もう一方に許可される値のセットはthisまたはthatです...
オブジェクトのメンバー関数を使用して、不変式が保持されていることを確認することもあります。そうでない場合は、アサートが発生します。そして、このメソッドは、オブジェクトを変更する各メソッドの開始および終了時に呼び出されます(C ++では、これは1行のみです...)
さて、このスレッドで見ているものはすべて素晴らしいですが、仕事で私にとって非常に役立つ「不変式」の定義があります。
不変式とは、プログラムの実行を通じて従わなければならない論理的な規則であり、人間には伝達できますが、コンパイラには伝達できません。
この定義は、条件を2つのグループに分割するので役立ちます:コンパイラーが強制的に信頼できるものと、バグを導入せずにコードベースと対話するために文書化、議論、コメント、または貢献者に伝達する必要があるもの。
また、この定義は、「不変式が悪い」という一般化を使用できるため便利です。
例として、マニュアルトランスミッション車のシフターは、不変条件を回避するように設計されています。必要に応じて、ギアごとに1つのレバーを持つトランスミッションを構築できます。このレバーは、前方(「係合」)または後方(「係合解除」)にすることができます。そのようなシステムでは、「不変式」を作成しました。
「別のギアが噛み合う前に、現在噛み合っているギアを外すことが重要です。2つのギアを同時に噛み合わせると、機械的ストレスが発生し、トランスミッションが引き裂かれます。
そして、だらしない運転で壊れたトランスミッションを非難するかもしれません。しかし、現代の車は、ギアの間を旋回する1本のスティックを使用しています。現代のスティックシフト車では、同時に2つのギアを噛み合わせることができないように設計されています。
このように、論理規則に違反する方法でそれ自体を機械的に構成することを許可しないため、伝送は「不変式を除去する」ように設計されていると言えます。
コードから削除するこの種のすべての不変式は、コードを操作する認知的負荷を軽減するため、改善されます。
不変式(常識)は、ある時点で、またはプログラムの実行中に常に真である必要がある条件を意味します。たとえば、PreConditionsとPostConditionsを使用して、関数が呼び出されたときと戻るときに真でなければならない条件をアサートできます。オブジェクト不変式を使用して、オブジェクトが存在する間ずっと有効な状態でなければならないことをアサートできます。これは、契約原則による設計です。
コード内のチェックを使用して非公式に不変式を使用しました。しかし最近では、不変式を直接サポートする.Netのコードコントラクトライブラリで遊んでいます。
Coders At Workからの次の引用に基づいて...
しかし、それが維持している不変式を知ると、ああ、その不変式を維持すれば、ログ検索時間が得られることがわかります。
...私は「不変」=「望ましい効果を保証するために維持したい条件」を推測します。
不変式には微妙に異なる2つの感覚があるようです。
1はアサーションのようなものです。2は、正確性、パフォーマンス、またはその他の特性を証明するためのツールのようなものです。2の例については、Wikipediaの記事を参照してください(MUパズルの解の正確性を証明します)。
実際、不変量の第3の意味は次のとおりです。
.3。プログラム(またはモジュールまたは機能)が行うべきこと。言い換えれば、その目的。
同じCoders At Workインタビューから:
しかし、大きなソフトウェアを管理しやすくするのは、それが何をすべきであり、どのようなことが真実であると想定されるかについて、いくつかのグローバルな不変式または大局的な記述を持っていることです。
不変式は、プログラムのロジックを決定するために使用できるルールまたは仮定のようなものです。
たとえば、ユーザーアカウントを追跡するソフトウェアアプリケーションがあるとします。ユーザーが複数のアカウントを持つこともできますが、何らかの理由でユーザーのメインアカウントと「エイリアス」アカウントを区別する必要があるとします。
これはDBレコードまたは他の何かかもしれませんが、ここでは各ユーザーアカウントがクラスオブジェクトによって表されると仮定します。
クラスuserAccount {private char * pUserName; private char * pParentAccountUserName;
...}
不変条件は、pParentAccountUserNameがNULLまたは空の場合、このオブジェクトが親アカウントであるという仮定かもしれません。この不変式を使用して、さまざまなタイプのアカウントを区別できます。おそらく、さまざまな種類のユーザーアカウントを区別するためのより良い方法があるので、これはインバリアントがどのように使用されるかを示す例にすぎないことに留意してください。
物理学の背景から言えば、物理学には不変量があります。不変量は、本質的に計算/シミュレーション全体を通して変化しない量です。たとえば、物理学では、閉じたシステムの場合、総エネルギーが節約されます。または、物理学でも、2つの粒子が衝突する場合、結果のフラグメントには、開始時のエネルギーと正確に同じ運動量(ベクトル量)が含まれている必要があります。通常、結果を完全に指定するのに十分な不変式はありません。たとえば、2粒子衝突では、4つの不変量、3つの運動量成分、およびエネルギー成分がありますが、システムには6つの自由度があります(その状態を表す6つの数値)。不変量は丸め誤差内で保存されるべきですが、それらの保存は解が正しいことを証明しません。
したがって、通常、これらのことは健全性チェックとして重要ですが、それ自体では正当性を証明できません。