循環参照は一般的に問題であると聞きましたが、他のインターフェイスを参照するインターフェイスにこれが当てはまるかどうか疑問に思いました。たとえば、次のようになります。
IQuestion{
IAnswer getCorrectAnswer();
IList<IAnswer> getAllAnswers();
}
IAnswer{
IQuestion getQuestionInResponseTo();
}
これが問題になるケースはありますか?解決できたとしても、私には解決できないようです。私の推測では、インターフェイスは参照に関してあまり要求しないため、これは問題にはならないでしょう。前もって感謝します。
どちらかが変更されるとすぐに両方の参照の整合性/有効性をチェックする必要がある限り、これは問題です(そして、そうすることで起こりうる無限の再帰に注意したいと思うかもしれません)。それらはかなり静的であるように見えるので、(ほとんどの)問題ではありません。おそらく、モデルオブジェクトの構築中にそれを再確認する必要があります。しかし、それをすることを忘れないでください。質問Aが回答Aを参照し、回答Aが質問Bを「親」として参照することは望ましくありません。
少し話題外:なぜ両方の参照を保持するのですか?答えが属する質問を取得するために時間を節約するだけですか?おそらく質問とその回答を使用しているコンテキストでは、コンテキストにはすでに質問と回答の両方への参照があるため、関係をそれらから抽出するのは難しくなく、モデルを作成すると思います。エラーが発生しにくく、保守が容易な設計。
技術的には循環参照ではないと思います。コンパイルされます。
ただし、この種の構造では注意が必要な問題がいくつかあります。たとえばシリアル化。
親オブジェクトに戻って参照すると、単純なアプローチで無限ループが発生する可能性があります。
さらに、多分null値を考慮する必要があります。これらのオブジェクトのツリーがある場合、最後のリーフはnull値になります。
私は、ツリー、リンクリスト、または再帰のために特別に設計された構造以外の構造は避けます。
親オブジェクトへの簡単な参照が必要な場合は、親をループして見つけます。
これは明らかに、インターフェースのレベルでの循環参照です。型レベルで循環参照を持つ再帰的なデータ型と同様に、インスタンスオブジェクト自体が循環参照に関与しているとは限りません(確かに可能です)。
多くの状況(すべてではありませんが)では、循環参照に「間違った」ものはありませんが、一般に、構築と破棄の順序の問題が発生します(つまり、関連するインスタンスオブジェクトの一部が不変オブジェクトであることが妨げられます)。
親と子の概念を持つのに役立ちます。親は子を参照し、子は親を参照しますが、通常、子を削除すると、1つの親子参照(親自体ではなく)のみが削除されることに同意しますが、親を削除すると、削除することを意味します。親子参照だけでなく、現在のすべての子も参照します。
これは、親と子の参照が方向性と非対称性を持っていることを意味し、ある意味では、一方には他方にはない所有権の概念が含まれているため、循環性にもかかわらず、一方は他方よりも効果的に「強力」です。
一部のデータベースでは、この「強さ」を制約の表現として指定できます。対照的に、私たちのプログラミング言語では、ほとんどの場合、親から子への参照と子から親への参照を区別できません(どちらも単なる参照です)。それらがそのような区別を可能にした場合、それらの非対称性に照らして、親/子および子/親の参照を非循環と見なすことができます。
一部の参照カウントアルゴリズムは、暗黙的にタグ付けされた、または明示的に宣言された強力な参照を介してサイクルを中断します。
小規模では、ガベージコレクション言語を使用する場合のサイクルはそれほど悪くありません。ただし、手動のメモリ管理、特に参照カウントの場合、サイクルが問題になります。
大規模な場合、たとえばライブラリでサイクルが発生した場合(1つのライブラリが別のライブラリに依存していて、それに依存している...)、これらは特に初期化の順序に関して問題になる可能性があります。このような問題は、ドライバーやサブシステムなどのオペレーティングシステムコンポーネント間の循環性によって悪化する傾向があります。実行できないわけではありませんが、複雑さが増すと同時に、サブセット化の機能も妨げられます。より小さなバージョンのオペレーティングシステムをより小さなバージョンで作成する環境。
循環参照がメモリリークを引き起こす可能性のある言語(C++など)を使用している場合、またはデータベースからこれらのオブジェクトをロードするなどの操作を行っている場合にのみ問題になり、ORMがそうでない場合は無限ループになります。これを適切に処理する方法を知っています。私が知っているすべての問題は、弱い/所有していないポインタや怠惰な初期化などを使用して、あなたがそれらを知っている限り回避することができます。