問題タブ [invariants]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java でメソッド本体に制約または制限を課す
コンテキスト (編集)
いくつかの明確化はオンデマンドで行われたので、質問に影響を与えるものを要約しようとします.
このプロジェクトの目標は、プログラマーに特定の機能を提供することです。ほとんどの場合、ライブラリ (クラス ファイルを含む JAR と思われます) の形で提供します。
上記の機能を使用するには、プログラマーは満たさなければならない(すべき)制約に準拠する必要があります。そうしないと、期待どおりに機能しません ( のロックと同様
java.util.concurrent
に、適切な時間と場所で取得/解放する必要があります)。このコードは、それを使用するアプリケーションへのエントリ ポイントにはなりません (つまり、何もありません
main
)。API で公開される操作の量は限られています (そして少量です)。
例:
ほとんどすべてが実装済みのクラスによって実装および管理される小さなゲームを考えてみてください。プログラマーに残された唯一のことは、キャラクターが何をするか (歩く、方向を変える、停止する、オブジェクトを検査する) を記述するメソッドを 1 つまたはいくつか記述することです。それらのメソッド (おそらく注釈でマークされていますか?) が
walk
、 またはchangeDirection
、または calculateだけであることを確認しdiff = desiredValue - x
、たとえば、ファイルに書き込んだり、ソケット接続を開いたりしないようにしたいと思います。トランザクションマネージャーを考えてみてください。マネージャは、このライブラリによって提供されるほか、トランザクションのいくつかの一定の属性 (分離レベル、タイムアウトなど) も提供されます。ここで、プログラマーはトランザクションを持ち、このマネージャーを使用したいと考えています。、 、、または一部のリソースでのみ
read
、マネージャーに知られていることを確認したいと思います。マネージャーがロケットの発射を制御していない場合、トランザクションの途中で彼らを望んでいません。write
commit
rollback
launchRocket
問題
メソッド(またはメソッドのグループ)の本体にいくつかの不変条件/制限/制約を課し、後で他のプログラマーによって他のパッケージ/場所に実装されるようにしたいと考えています。たとえば、私は彼らに次のようなものを与えます。
このプロジェクトの目的のために、メソッド本体がいくつかの不変条件を満たしていることが重要です (おそらく必須です)。むしろ、このメソッドの実装で使用するコマンドのセットを制限することが不可欠です。これらの制約の例:
- このメソッドは I/O を実行してはなりません。
- このメソッドは、未知の (潜在的に危険な) オブジェクトをインスタンス化してはなりません。
- ...
別の言い方をすれば:
- このメソッドは、既知の (特定の) クラスのメソッドを呼び出すことができます。
- このメソッドは、いくつかの基本的な命令 (数学、ローカル変数の割り当て、
if
s、ループなど) を実行できます。
私は注釈を調べてきましたが、これに近いものはないようです。
これまでの私のオプション:
いくつかの注釈を定義
@SafeAnnotation
し、それをメソッドに適用して、実装者との契約を定義し、課された規則に従うか、システムが誤動作するかを決定します。Enum
許可された操作で を定義します。許可されたメソッドを公開する代わりに、これらの列挙型オブジェクト (または制御フロー グラフに似たもの) のリストを受け入れて実行するメソッドのみが公開され、何ができるかを制御できます。
例:
私の質問
メソッドが有効かどうか (つまり、制約を満たしているかどうか)を (コンパイル時または実行時に) 調べることができる、注釈、リフレクションなどの機能が言語にあるか?
むしろ、他のメソッドの限られたセットのみを呼び出すように強制する方法はありますか?
そうでない場合 (そして私はそうではないと思います)、この 2 番目のアプローチは適切な代替手段でしょうか?
直感的で、よく設計された、および/または優れた実践のように、適切です。
更新(進捗)
関連するいくつかの質問を見た後、この質問の受け入れられた回答に記載されている手順に従うことも検討しています(おそらく3番目のオプションとして)。ただし、これにはアーキテクチャの再考が必要になる場合があります。
注釈を使用して制限を課すという全体的なアイデアには、独自の注釈プロセッサを実装する必要があるようです。これが本当なら、プログラマーがこれらの限られた操作を使用し、後でコードを Java に変換できるように、小規模なドメイン固有言語を検討することもできます。このようにして、指定されたものを制御することもできます。
c# - この操作が無効である理由を誰かが説明できますか?
今日、共分散と反分散について調べていたところ、Jon Skeet がクラス レベルでの不変性を説明しているスタック交換に関する投稿に出くわしました。彼は果物の例を使用し、そのレベルで共分散を許可することがなぜ悪いことなのかを説明しました。
では、Fruit から継承するクラスのインスタンスを追加するために、Fruit のリストがあることはどのように説明されるのでしょうか? 例えば:
過去にこれを行ったことがありますが、常に期待どおりに動作します。CLR が fruitBowl の型を調べないのはなぜですか? それは、最初に FruitBowl の値を Bananas のリストに設定し、それが Fruit のリストに対して共変であり、次にタイプが本当に であるコレクションに Apple を追加しようとしているからList<Banana>
ですか?
以下のマットに感謝します。参照型を扱っていることを覚えておくと役立ちます。これを永遠に反対票を投じてください。
java - Javaのネストされた2つのwhileループのループ不変式を見つける
私は不変式に少し精通しており、小さなループについて多かれ少なかれ見つけることができます。次のJavaの疑似コードの不変式を解くときに、私はとても混乱しています。誰でも助けてください:
java - Java 不変例外
特定のデータに、言語構造を使用して強制できない不変条件があるプロジェクトがありますが、それらが維持されるようにコードを作成するつもりでした。何らかの理由でそれらが壊れている場合、それは私のコードにバグがあることを意味します。これらの不変条件が壊れているかどうかを検出できるサニティチェックコードがありますが、そのような状態に対応するための標準的な Java アプローチが何であるかわかりません-スローする必要がある標準例外はありますか? アサートを使用しますか?
これは、ある時点で値が正しく設定されていないという問題であることに注意してください。エラー自体はサニティ チェック時に発生するのではなく、過去に発生したエラーであり、サニティ チェックが現在それを発見している (つまり、サニティ チェック自体が実行されていることは悪いことではありません。チェックに失敗しました)。
ありがとう!
domain-driven-design - DDD - 集合根が小さい不変条件を適用する
DDD を初めて試みたのですが、集約設計で問題が発生しました。
私のアプリケーションには 3 つのエンティティが含まれています。グラフ、ノード、リンク。これらの各エンティティには、ユーザーが変更できる name プロパティがあります (これにより、'name' はエンティティ ID として不適切になると思います)。グラフにはノードのコレクションが含まれ、ノードには発信リンクのコレクションがあります (この問題の目的のために、着信リンクを無視しても問題ありません)。各ノードは、一度に 1 つのグラフにのみ関連付けることができます (ただし、グラフ間で移動できます)。同様に、各リンクは、任意の時点で 1 つのノードにのみ関連付けることができます (ただし、移動することはできます)。
私が強制しようとしている不変条件は、すべてのエンティティ名が親コレクション内で一意であることです。上記のアーキテクチャでは、不変条件は実際のコレクションにあるため、コレクションの所有者 (グラフとノード) は両方とも集約ルートにする必要があると判断しました。
私が抱えている問題は、ノードで名前の不変をどのように強制するかということです? リンクでは、ノード AR 内に隠されているため簡単です。そのため、ノードはすべてのリンクの名前変更/移動がこの不変条件を破らないことを確認できます。しかし、私が見る限り、不変条件を壊す可能性のある Node の直接の名前変更を妨げるものは何もありません。ここでは結果整合性は受け入れられるオプションではありません。これは真のシステム不変条件でなければなりません。
私が検討しているアプローチは、Node.Rename() に実際に不変条件を適用させることですが、私の懸念は、これには親グラフ内を調べて、名前の変更が有効かどうかを確認することです。これは正しく「感じられない」 - グラフがこの名前空間の制約を強制するものであるべきであり、その Node はそれについて何も知らなくてもよいように感じます。
これが理にかなっていることを願っており、人々の考えを聞くことを楽しみにしています.
編集: 上記のドメイン モデルは、ドメイン全体の単純化されたサブセットです。すべてのエンティティを 1 つの AR 内に保持するには複雑すぎます........