一个实用的面向对象设计问题
我正在切换到更面向对象的 ASP.NET 网络方法我正在开发的新系统中的应用程序。
我有一个大多数人都会熟悉的通用结构。我的学校结构中有多个部门;属于单个系的课程;以及属于多个课程的学生。
在部门视图中,我列出了属于该部门的所有课程,并且我想要每门课程的汇总数据,例如注册人数、退学人数、男性/女性人数等。
但是,在单个课程视图中,我需要实际的学生列表以及他们的详细信息,例如是否注册、通过课程、性别等。
然后是单个学生视图,其中显示有关学生的所有详细信息,包括其他课程的注册情况、地址等。
以前,我可以访问数据层返回我在每种情况下需要的任何数据,并将其作为 SQLDataReader
或 DataSet
返回(在 VB.NET 中工作)。现在,我尝试以面向对象的方法对此进行建模,我在 DAL< 中创建对象/a> 并将它们返回到 BLL。当我需要对象中的聚合详细信息时,我不确定如何处理这个问题。例如,在包含课程列表的部门视图中,我将对每门课程进行聚合。我是否会将一些轻量级课程对象的集合存储在这些轻量级课程对象存储聚合值的部门中?
我想不同的场景需要不同的抽象级别,我不确定处理这个问题的最佳方法。我是否应该有一个对象模型,其中有一个存储聚合的非常基本的课程对象和一个存储完整详细信息的子对象?
另外,如果有任何有用的资源可以帮助我理解如何对此类事物进行建模,那就太好了。
I'm making the switch to a more object-oriented approach to ASP.NET web applications in a new system I'm developing.
I have a common structure which most people will be familiar with. I have a school structure where there are multiple departments; courses belonging to a single department; and students belonging to multiple courses.
In a department view I list all courses belonging to the department and I want aggregated figures for each course such as number of enrolments, withdrawals, number male/female etc.
In an individual course view however, I'll need the actual list of students along with their details such as whether they are enrolled, passed course, gender etc.
And then the individual student view where all detail about a student is displayed including enrolments on other courses, address, etc.
Previously, I would have had a data access layer returning whatever data I needed in each case and returning it as an SQLDataReader
or DataSet
(working in VB.NET). Now, I'm trying to model this in an object-oriented approach I'm creating objects in the DAL and returning these to the BLL. I'm not sure how to handle this though when I need aggregated details in objects. For example, in the department view with the list of courses I'll have aggregates for each of the courses. Would I store a collection of some lightweight course objects in the department where those lightweight course objects store the aggregated values?
I guess there are different levels of abstraction needed in different scenarios and I'm not sure the best way to handle this. Should I have an object model where there's a very basic course object which stores aggregates, and a child object which would store the full detail?
Also, if there are any useful resources that may help my understanding of how to model these kind of things that'd be great.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不要把事情搞得太复杂,不要做不必要的工作。数据库在数据操作方面是完美的,所以让数据库来做聚合。在代码方面,再向您的对象模型添加一个对象,您就会感觉一切都很好:
执行聚合的 SQL 非常简单。但是,请务必使用 ORM(例如 NHibernate)或不太复杂的结果集映射器(例如 BLToolkit):您并不真的想手动水化这些对象。
另一个好处是您可以缓存两个查询结果(并且一旦与课程相关的内容发生更改,缓存就会失效)。
Do not overcomplicate things and do not do unneccessary work. Databases are perfect when it comes to data manipulation, so let the DB do the aggregation. On the code side of things, add one more object to your object model and you'll be just fine and dandy:
The SQL to do the aggregation is pretty straightforward. Be sure, however, to use an ORM (think NHibernate) or a less sophisticated Result-Set Mapper (think BLToolkit): you don't really want to manually hydrate these objects.
An added benefit is that you can cache both query results (and invalidate cache as soon as something course-related changes).
这实际上是一个很大的问题,很多人都在努力解决。
据我所知,关于这个问题至少有两种思想流派:
Jeremy Miller 在 MSDN 杂志中发表了一篇文章,调查了一些持久性模式。
领域驱动设计一书对聚合建模进行了很好的讨论。
That's actually a pretty big issue that many people are struggling with.
As far as I've been able to identify, there are at least two schools of thought on this issue:
Jeremy Miller has an article in MSDN Magazine that surveys some persistence patterns.
The book Domain-Driven Design has a good discussion on modeling Aggregates.
如果部门很少并且每个部门的课程数量也很少,则只需加载所有内容并让您的对象进行数学计算(即部门迭代课程列表并总结您需要的内容)。
另一种方法是使用一些自定义的本机 SQL 对数据库运行求和。您可以将其隐藏在 DAL 中。然后,DAL 将返回一个虚拟课程(数据库中不存在,但包含总和)。
第三种方法是将这些值保留在部门对象中的某个位置,并在每次更改/添加/删除课程时更新它们。
If there are few departments and each has a small number of courses, just load everything and have your objects do the math (i.e. the department iterates over the list of courses and just sums up what you need).
An alternative approach would be to run the sums against the database with some custom, native SQL. You can hide this in the DAL. The DAL would then return, for example, a virtual course (which doesn't exist in the database but which contains the sums).
A third approach is to keep these values somewhere in the department object and update them every time a course is changed/added/removed.
如果您使用 .NET,您应该调查的一件事是 LINQ to SQL。它将允许您在 DAL 中拥有一个非常优雅的界面。 LINQ 将允许您在 BLL 中制作聚合查询,保存管道代码以及散布在整个源代码中的令人讨厌的 SQL 片段。上一个链接中使用 LINQ 表达的聚合 SQL 查询的示例:
我已将数据库层切换到 LINQ,尽管在我的
如果我不使用 MS SQL Server,因此我使用了 DbLinq 库。
您最不想做的事情就是必须修改您的类以适应您的数据库访问层,这样做将使您的解决方案变得非常脆弱。
One thing you should investigate if you are working with .NET is LINQ to SQL. It will allow you to have a very elegant interface into your DAL. LINQ will allow you to craft aggregate queries in your BLL which saves plumbing code as well as nasty SQL snippets spread throughout your source. An example from the previous link of an aggregate SQL query expressed with LINQ:
I've switched over my database layer to LINQ although in my
case I don't use MS SQL Server so I have instead used the DbLinq library.
The very last thing you want to be doing is having to modify your classes to accommodate your database access layer, doing that approach will make your solution very fragile.