4

職業訓練を管理するためのシステムには、CourseBase抽象クラスがあります。これは、仮想の基本エンティティICourseから派生したすべてのクラスの実装コードの重複を避けたいため、インターフェイスを優先して使用することにしました。Course各コースには、科目のリストがあり、任意の科目がSubjectBase抽象クラスによって定義されています。だから、私は例えば

public abstract class CourseBase : BaseObject
{
    public IEnumerable<SubjectBase> Subjects
    {
        get { return new List<SubjectBase>(); }
    }   
}

public abstract class SubjectBase
{
    public string Name { get; set; }
    public string Description { get; set; }
    public int ValidityPeriod { get; set; }
}

LocalCourseここで、オブジェクトのコレクションを含む具象クラスを追加したいのですLocalCourseSubjectが、のインターフェイスを使用していないためCourseBase、共分散を失いSubjects、新しいもので抽象ベースのプロパティを非表示にする必要があります。

public class LocalCourse: CourseBase
{
    public IEnumerable<LocalCourseSubject> Subjects
    {
        get { throw new NotImplementedException(); }
    }
}

OOの観点から、ここで非常に明白な何かが欠けていると確信していますが、私が見ることができる唯一の解決策は次のとおりです。

  1. 抽象ベースからSubjectsを完全に省略し、派生クラスに特別に型指定されたコレクションプロパティのみを追加します。
  2. ISubjectCollectionOwner抽象ベースや具象クラスなどのインターフェースを実装します。

ここでぼんやりとすみません。このようなデザインの問題に遭遇することができて久しぶりです。

4

2 に答える 2

2

コースを抽象化するための汎用インターフェースを導入してみませんか?明らかなことを見逃してしまったらごめんなさい

public interface ICourse<TSubject>
{
   IEnumerable<TSubject> Subjects { get; }
}

public abstract class CourseBase<TSubject> 
   : BaseObject, 
     ICourse<TSubject>
{
    public IEnumerable<TSubject> Subjects
    {
        get { return new List<TSubject>(); }
    }   
}

public class LocalCourse 
   : CourseBase<LocalCourseSubject>
{
}

サブジェクトがコースエンティティの重要な部分である場合は、ICourseとCourseBaseの両方内に保持する必要があります。そうでない場合は、ISubjectAwareインターフェイスで抽象化することをお勧めします。

于 2011-11-06T11:25:03.133 に答える
1

あなたはこれをすることはできません:

public abstract class CourseBase<T> where T : SubjectBase
{
    public virtual IEnumerable<T> Subjects
    {
        get { return new List<T>(); }
    }
}

public abstract class SubjectBase
{
    public string Name { get; set; }
    public string Description { get; set; }
    public int ValidityPeriod { get; set; }
}

public class LocalCourse : CourseBase<LocalCourseSubject>
{
    public override IEnumerable<LocalCourseSubject> Subjects
    {
        get { throw new NotImplementedException(); }
    }
}

いずれにせよ、各CourseBase継承者が同じタイプのSubjectBase継承者のコレクションを持つという一般的なパターンを想定すると、これで短期的な目標を達成できると思います。しかし、その場合、これは並列継承階層のように見えます。これは、コードの臭いになる場合があります(必ずしもそうであるとは限りませんが、モデリングしているドメインの詳細をすべて把握しているわけではありません)。

于 2011-11-07T16:52:03.397 に答える