我应该如何抽象另一个对象拥有的对象集合?

时间:2011-11-06 09:25:15

标签: c# .net oop ooad

在一个管理职业培训的系统中,我有一个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. 完全省略抽象基础中的主题,并仅向派生类添加特定类型的集合属性。
  2. 在抽象基础中实现ISubjectCollectionOwner等接口以及具体类。
  3. 请原谅我的朦胧,已经有一段时间了,因为我很高兴遇到这样的设计问题。

2 个答案:

答案 0 :(得分: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>
{
}

如果Subject是课程实体的重要部分,您也应该将其保留在ICourse和CourseBase中,否则我建议通过ISubjectAware界面对其进行抽象

答案 1 :(得分: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继承者的集合。但是,如果是这种情况,这似乎是一个并行的继承层次结构,它有时可能是代码气味(不是说它必然是 - 我不知道你正在建模的域的所有细节)。 / p>