简体   繁体   English

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

[英]How should I abstract a collection of objects owned by another object?

In a system for managing vocational training, I have a CourseBase abstract class, which I decided on using in favour of an ICourse interface because I'd prefer to avoid duplicating implementation code for all classes derived from the hypothetical, base Course entity. 在一个管理职业培训的系统中,我有一个CourseBase抽象类,我决定使用它来支持ICourse接口,因为我宁愿避免重复从假设的基础Course实体派生的所有类的实现代码。 Each course has a list if subjects, with any subject defined by a SubjectBase abstract class. 每个课程都有一个列表,如果是主题,任何主题由SubjectBase抽象类定义。 So, I have eg 所以,我有例如

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

Now I want to add a concrete class, LocalCourse , which contains a collection of LocalCourseSubject objects, but because I'm not using an interface for CourseBase , I lose out on covariance, and I need to hide the abstract base's Subjects property with my new: 现在我想添加一个具体的类LocalCourse ,其中包含LocalCourseSubject对象的集合,但由于我没有使用CourseBase的接口,我失去了协方差,我需要用我的新隐藏抽象基数的Subjects属性:

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

I'm sure I'm missing something very obvious here from an OO point of view, but the only solutions I can see are: 从OO的角度来看,我确定我遗漏了一些非常明显的东西,但我能看到的唯一解决方案是:

  1. Completely omit Subjects from the abstract base, and only add a specifically typed collection property to derived classes. 完全省略抽象基础中的主题,并仅向派生类添加特定类型的集合属性。
  2. Implement an interface such as ISubjectCollectionOwner in the abstract base as well as concrete classes. 在抽象基础中实现诸如ISubjectCollectionOwner之类的接口以及具体类。

Please excuse my dimness here, it's been a while since I've had the pleasure of encountering a design issue like this. 请原谅我的朦胧,这已经有一段时间了,因为我很高兴遇到这样的设计问题。

Why just not introduce a generic interface to abstract a Course? 为什么不引入通用接口来抽象课程呢? Sorry if I missed something obvious 对不起,如果我错过了明显的事

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

If Subject is a vital part of Course entity you should keep it within both ICourse and CourseBase as well, otherwise I would suggects abstracting it by ISubjectAware interface 如果Subject是Course实体的重要部分,你应该将它保存在ICourse和CourseBase中,否则我会建议通过ISubjectAware接口来抽象它

Can't you just do this: 你能不能这样做:

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(); }
    }
}

I think that would accomplish your short term goal, at any rate, assuming that the general pattern is that each CourseBase inheritor will have a collection of the same type of SubjectBase inheritor. 我认为,无论如何,这将实现您的短期目标,假设一般模式是每个CourseBase继承者将拥有相同类型的SubjectBase继承者的集合。 But, if that is the case, this seems like a parallel inheritance hierarchy, which can sometimes be a code smell (not saying that it necessarily is -- I don't know all the details of the domain you're modeling). 但是,如果是这种情况,这似乎是一个并行的继承层次结构,有时可能是代码气味(不是说它必然是 - 我不知道你正在建模的域的所有细节)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM