具有多个对象的业务层,其中所有属性都从DB填充,或者一个对象仅填充了子集

时间:2011-05-18 16:34:55

标签: .net domain-driven-design class-design business-logic business-logic-layer

我正在建立一个中等规模的系统,我面临的问题可能是你们中的一些人以前遇到过的。在我的业务层中,我返回业务对象,其中包含对该业务方法很重要的属性子集,我很担心,因为我最终会得到很多没有意义的名称的对象,或者只有一个属性只在给定的属性中被填充的对象方法。让我举一个例子。

案例1

例如,用户属于某个城市,而该城市又属于某个州和国家/地区,UserCityStateCountry是表格我的数据库包含很多字段,但是我想要一个带有Orders列表的用户列表,所以我创建了一个名为UserWithOthers的业务对象,只包含重要的属性(UserId, UserName, CityName, StateName, CountryName, List<Order>)和我的DAL仅检索数据库中的那些字段。

案例2

我想现在返回一个订单数量的用户,我在我的业务对象(UserId, UserName, CityName, StateName, CountryName, OrdersCount)中以下列字段结束,并且可以调用该类,例如UserWithOrderCount

我想过一些选择:

  1. 创建这两个业务类并在每个DAL方法中单独填充它们(这个对象很简单但是考虑到该方法可以有一个复杂的选择查询,需要封装以便重用,因此存储库模式不适合这里,至少我想那个。)。
  2. 只创建一个包含所有属性(User)的对象UserId, UserName, CityName, StateName, CountryName, OrdersCount, List<Order>并在每个DAL方法中只填充一个子集,但这意味着在使用方法时会出现语义耦合,因为您必须知道哪个子集从数据库中填充字段,语义耦合是最差的耦合。
  3. 如果稍后我需要List<Order>OrdersCount属性,则选项1无法正常处理。
  4. 现在考虑如果你使用ASP.NET MVC好的做法告诉你需要一个ViewModel传递给视图,我想从我的Businnes Layer返回ViewModels,但我觉得不是一个好主意,感觉就像我违反了某些内容一样,也是不可能的,因为我的业务层位于另一个程序集而不是Web应用程序中。
  5. 我不想一遍又一遍地写同样的Linq查询,但如果使用NHibernate或EFCodeFirst是“喜欢”选项一,我将需要创建大量的小型业务对象。
  6. 你如何处理这种情况?我认为这是一个高级别的设计决定。

1 个答案:

答案 0 :(得分:2)

首先,我绝对同意你的一些事情:

  1. 不要部分填充业务对象,因为您负责了解哪些属性填充到业务层的客户端,这是非常糟糕的做法。

  2. 不要从业务层返回ViewModel;您的业​​务层应该代表应用程序域的业务概念,而ViewModel是一个数据对象,它包含显示该域的一部分的特定视图所需的数据 - 两者是非常不同的东西,业务层应该完全不知道其业务对象用于任何类型的GUI。

  3. 我会提出您的第一个建议 - 创建一个单独的业务对象来表示每个业务概念。然后我会使用ORM(如EF或NHibernate)为我填充这些对象,为每组对象配备专用的存储库。然后,我将使用一个应用程序层来调用存储库以返回所需的任何对象。为此,当您知道需要将这两种类型一起使用时,您的存储库可以包含返回已加入用户和订单的方法。这允许您在一个查询中返回一个包含所有订单的用户,同时保留单独的,有意义的实体来表示用户和订单。