• 締切済み

誘導可能なコンポジションの循環参照について。

Javaの設計についての基本的な質問です。 企業を表すCompanyクラスのフィールドに、そこで働く従業員を表すEmployerクラスのSetを保持していたとします。 Employerクラスは自身の所属するCompanyを取得するためのメソッドgetCompany()を持っていたとします。 public class Company{   Set<Employer> employers; } public class Employer{   public Company getCompany(){   } } 実現したいのは「従業員から自身の所属する企業を知る」ということです。 このgetCompany()を実現するためにはEmployerのフィールドに所属するCompanyのインスタンスを保持することになると思います。 また、特にDIなどは考えないとすると、Employerクラスのインスタンス生成時等には所属するCompanyクラスのインスタンスを渡すなどの必要があります。 上記のようにすれば実現自体は可能なことはわかるのですが、循環参照のような形となり適切でないような気がします。 Company has employers. は正しいと思いますが、 Employer has a company. は何か違う気がします。 EmployerのコンストラクタにCompanyを渡して、生成したEmployerをそのCompanyにaddするのも不自然に感じます。 これらを実現するためにはどのような形が適切と言えるのでしょうか。 上記は最も正しい・美しい形といえるのでしょうか。 そもそも何か根本的なところが誤っていますでしょうか。 これはあくまで例ですが、回答いただくには情報が足りないのであればご指摘ください。 結果、 http://okwave.jp/qa/q2652715.html こちらの質問と全く同じになってしまいましたが、Javaでも同様でしょうか。

みんなの回答

回答No.2

NO.1 にも書きましたが DIP を使うという手段もあります。 組織の骨組み(構造)を定義するパッケージを 一つも設け、Employee や Company はそこで インターフェースとして定義します。 本当の Employee や Company はインターフェースを実装します。 こうすると、インターフェース間の相互参照は残りますが、 クラス間の相互参照は消えてしまいますので好きなパッケージで Employee や Company 実装することが可能になり、jarの相互残照 などが起こることも無くなります。 Employee や Companyの具象クラスが様々なパッケージに 分散するようでしたら、検討してみるべきです。

回答No.1

has は相手を「所有する」強い依存関係ですが、 Employee から Company への関係はもっと弱い より「一般的な依存関係」です。 この区別を学びましょう。 相互参照は注意すべきですが、Java は 相互参照を認めている言語なので そう神経質になることはないでしょう。 ただ、jarを超えて循環参照などはできないので そういう時は DIPなどを使うことになると思います。

mmmosa
質問者

お礼

ご回答ありがとうございます。 依存関係の強度についてあまり考えていませんでした。 勉強してみます。 ただどうしても相互参照に起因する不整合のリスクが発生してしまうのが心配です。

関連するQ&A