业务实体 - 应该仅将列表公开为ReadOnlyCollections吗?

时间:2011-03-23 21:11:00

标签: oop design-patterns business-objects

在尝试集中项目的添加方式或从业务实体类中删除项目时,我已经转移到模型,其中所有列表仅作为ReadOnlyCollections公开,并且我提供了Add和Remove方法来操作列表中的对象。 / p>

以下是一个例子:

public class Course
{
    public string Name{get; set;}
}

public class Student
{
    private List<Course>_courses = new List<Course>();
    public string Name{get; set;}
    public ReadOnlyCollection<Course> Courses {
        get{ return _courses.AsReadOnly();}
    }
    public void Add(Course course)
    {
        if (course != null && _courses.Count <= 3)
        {
            _courses.Add(course);
        }
    }
    public bool Remove(Course course)
    {
        bool removed = false;
        if (course != null && _courses.Count <= 3)
        {
            removed = _courses.Remove(course);
        }
        return removed;
    }
}

我执行上述操作的部分目标是不使用Anemic数据模型(反模式),并避免使用在整个地方添加和删除课程的逻辑。

一些背景:我正在使用的应用程序是一个Asp.net应用程序,其中列表以前曾作为列表公开,这导致了各种方式将课程添加到学生(有些地方检查已经完成,其他人没有检查。

但我的问题是:以上是一个好主意吗?

3 个答案:

答案 0 :(得分:1)

我想说,添加/删除需要以您建议的方式进行控制时,这是一个好主意,例如业务规则验证。否则,正如您在之前的代码中所知,实际上无法确保执行验证。

然而,您可能希望达到的平衡是何时执行此操作以及何时不执行此操作。为每种类型的集合执行此操作似乎有点矫枉过正。但是,如果你这样做,然后需要添加这种守门代码,那么对于班级来说这将是一个重大改变,这可能是也可能不是时间。

我认为另一种方法可能是拥有一个IList<T>的自定义后代,它具有通用的Add()Remove()方法的通用守门代码,可以通知系统发生了什么。像调用在调用这些方法的内部逻辑之前引发的事件之类的东西。然后,Student类在实例化_courses以将业务逻辑应用于事件并取消操作时,会提供一个委托或某事(抱歉是模糊的,我今天非常编码)例外情况,我想)如果业务验证失败。

根据开发人员的处理情况,这也可能有些过分。但至少有一些像这样的工程设计,你可以获得一个通用的实现,可以根据需要随时添加/删除业务验证,而不会破坏更改。

答案 1 :(得分:1)

是的,这是一个很好的方法,在我看来,除了装饰你的列表之外你没有做任何事情,它比实现你自己的IList更好(因为你保存了很多行代码,即使你失去了更优雅的方式迭代你的课程对象。)

您可能会考虑接收验证策略对象,因为将来您可能会有新要求,例如:可以拥有3门以上课程的新型学生等等

答案 2 :(得分:0)

我过去做过这件事而后悔:更好的选择是使用不同的类来读取域对象,而不是用来修改它们的域对象。

例如,使用一个行为丰富的Student域类,它会小心地保护其对课程的所有权 - 如果学生对其负责,则不应该公开它们 - 以及StudentDataTransferObject(或ViewModel)提供一个简单的课程字符串列表(或需要ID时的字典),用于填充界面。