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

本文关键字:一个对象 拥有 集合 对象 何抽象 抽象 我应该 | 更新日期: 2023-09-27 18:13:34

在管理职业培训的系统中,我有一个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. 从抽象基中完全省略Subject,只向派生类添加特定类型的集合属性
  2. 在抽象库和具体类中实现ISubjectCollectionOwner之类的接口

请原谅我在这里的昏暗,我已经有一段时间没有幸遇到这样的设计问题了。

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

为什么不引入一个通用接口来抽象课程?抱歉,如果我错过了一些明显的

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接口

对其进行抽象

你就不能这么做吗:

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继承人的集合,这将实现你的短期目标。但是,如果是这样的话,这看起来像是一个并行继承层次结构,有时可能是一种代码气味(并不是说它一定是——我不知道你正在建模的域的所有细节(。