(両方の言語で同じ質問なので、これをC#とJavaの両方としてタグ付けしました。)
私はこれらのクラスを持っていると言います
interface IKernel
{
// Useful members, e.g. AvailableMemory, TotalMemory, etc.
}
class Kernel : IKernel
{
private /*readonly*/ FileManager fileManager; // Every kernel has 1 file manager
public Kernel() { this.fileManager = new FileManager(this); /* etc. */ }
// implements the interface; members are overridable
}
class FileManager
{
private /*readonly*/ IKernel kernel; // Every file manager belongs to 1 kernel
public FileManager(IKernel kernel) { this.kernel = kernel; /* etc. */ }
}
この設計の問題は、コンストラクター内で何かFileManager
を実行しようとすると(合理的に必要になる可能性があります)、コンストラクターがまだ呼び出されていない潜在的なサブクラスインスタンスで仮想メソッドを呼び出すことです。kernel
この問題は、(C#/ Javaのような初期化子ではなく)真のコンストラクターを定義できる言語では発生しません。これは、コンストラクターが呼び出される前にサブクラスが存在しないためです...しかし、ここでこの問題が発生します。
では、これが起こらないようにするための最良/適切な設計/実践は何ですか?
編集:
必ずしも循環参照が必要だと言っているわけではありませんが、実際には、両方が相互Kernel
にFileManager
依存しています。循環参照を使用せずにこの問題を軽減する方法について提案がある場合は、それも素晴らしいことです。