@konbraphat51

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

循環参照を解決するクラス設計を検討したい

ソフトウェア設計についての質問です。

現在考えているクラス構造が下記のような感じです
image.png
→で「1対多」のつもりです。

Managerが全体統括としてStudentTeacherのメソッドを呼んでいく、という構造ですが、Teacherが教え子のStudentを取得するというときに循環参照が起きてしまいます。

というのは、3つの方針を思いついたのですが、

TeachingクラスがもしTeacherインスタンスやStudentインスタンスを持てばその間で循環参照。

TeachingクラスがTeacherStudentのID値のみを持っていたとしても(これはこれで更新時異状が起きてダメですけど)、対応するStudentを探すべくTeacherManagerに問い合わせをし、そこで循環参照。

TeacherTeachingに対応するStudentを持つ場合(冗長ですが)、StudentTeacherを取得しようとすると循環参照。

という問題で行き詰まっています。

クラス構造を改善することで解決したいのですが、いいアイデアはありますでしょうか?

クラス設計の勉強として取り組んでいるため、あまり「弱い参照」を使わないようにしたいです。

0 likes

4Answer

「TeachingクラスがもしTeacherインスタンスやStudentインスタンスを持てばその間で循環参照」が一番いいと思います。

理由はTeacherとStudentがお互いに直接依存してなくてTeachingを通じて間接依存するからです。

ちなみに、Personというインターフェースを作ってTeacherとStudentに継承させたら、TeachingクラスでのTeacherとStudentインスタンスの管理がもっと上手くできると思います。

2Like

Comments

  1. @konbraphat51

    Questioner

    ありがとうございます。
    循環参照を許容するという思想もあるのですね。勉強になります。

先生は学校から学生名簿を渡されて、出席確認したり授業するといいのでは?
それなら一方方向アクセスで循環しません。
循環してしまうときは、@heesukim998 さんが書かれているようにインタフェースを作って両方から参照するといいですよ。例えば「担任インタフェース」を作って、先生は実装し、生徒はインタフェースを参照することで循環せずに済みます。

2Like

Comments

  1. @konbraphat51

    Questioner

    メモリ効率が落ちるかもしれませんが、確かに名簿を渡す方法だと一方向アクセスになりますね。
    ありがとうございます。
    インターフェースの案もすごくいいですね。考えてみます。

のモデルでTeachingがTeacherとStudentに直接関連するのか?疑問です。

Teaching=LearningなのでClasswork授業に変更しました。

mermaidのgraphで記述してます。
’’’mermaid
graph LR
  Manager-->Classwork
  Classwork-->Teacher
  Classwork-->Student
  Student-->Member
’’’

TeacherとStudentの関係を会話で定義するのは蛇足とおもいます。

1Like

Comments

  1. @konbraphat51

    Questioner

    ありがとうございます。
    確かに、Manager -> Classwork
    のように変更してみるのも面白いですね。考えてみます。

質問からは具体的に何の話か分からないのでハズレかもしれませんが・・・

データベースがあって、それに Manager, Teacher, Student などのテーブルがあって、質問者さんが言うクラスとはエンティティクラスのことではなかろうかと想像してレスします。

Microsoft の Entity Framework Core 関係のチュートリアルに、質問に書いてある Teacher, Student と似たような構造のエンティティクラスの例があるので紹介します。下の画像を見てください。

diagram.png

出典:
チュートリアル: 複合データ モデルを作成する
https://learn.microsoft.com/ja-jp/aspnet/core/data/ef-mvc/complex-data-model?view=aspnetcore-6.0

Teacherが教え子のStudentを取得するというときに循環参照が起きてしまいます。

ある Teacher が教えているすべての Student 一覧を取得したいということだと想像してます。

上の画像の例では、Instructor クラスの CourseAssignments ナビゲーションプロパティでその Instructor が担当している Couese を取得し、Course クラスの Enrollments ナビゲーションプロパティをたどってその Course に参加している Student を取得するということができます。

なので、

TeachingクラスがもしTeacherインスタンスやStudentインスタンスを持てばその間で循環参照。

上の画像の例では、あるクラスが他のクラスのインスタンスを参照しているということはありません。

質問者さんの言う「循環参照」という意味が理解できていませんが、何にせよ「インスタンスを持てば」というのが根本的な問題の原因であるということなら、そこは回避できるはずです。

1Like

Comments

  1. @konbraphat51

    Questioner

    ありがとうございます。
    言葉足らずですみませんでした。エンティティクラスのご認識であっています。
    ご例示していただいた設計図、見事に循環をせず設計できていいですね。

    もしかすると私の循環参照の解釈を誤っているかもしれませんが、「クラスAのコード記述の中にクラスB型の値が存在すること」を「AがBを参照している」として、それが循環する、ということを指していました。

  2. もしかすると私の循環参照の解釈を誤っているかもしれませんが、

    そうではないかと思いますけど。

    Teacherが教え子のStudentを取得するというときに循環参照が起きてしまいます。

    ということですが、相互の情報を参照し合ってループを成していて「Teacherが教え子のStudentを取得する」という操作を行う際に無限ループに陥ってしまい、ループから脱出できないというようなことがあるのでしょうか? そうでなければ特に問題ないのでは?

Your answer might help someone💌