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>
{
}

如果 Subject 是 Course 实体的重要组成部分,您也应该将其保留在 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 回答