业务层包含多个对象(所有属性均从数据库填充)或一个对象(仅填充子集)
我正在构建一个中型系统,我面临着一个问题,可能你们中的一些人以前也遇到过。在我的业务层中,我返回具有对该业务方法很重要的属性子集的业务对象,我很担心,因为我最终可能会得到很多具有无意义名称的对象,或者只有一个对象,其中仅填充了给定属性的子集方法。让我举个例子。
情况 1
例如,用户属于一个城市,而该城市又属于一个州和一个国家,User
, City
, State
和 Country
是我的数据库中包含很多字段的表,但我想要一个包含订单列表的用户列表,因此我创建了一个名为 UserWithOthers
仅包含重要属性(UserId、UserName、CityName、StateName、CountryName、List
),并且我的 DAL 仅从数据库检索这些字段。
情况 2
我现在想返回一个具有订单数量的用户,我以业务对象中的以下字段结尾(UserId、UserName、CityName、StateName、CountryName、OrdersCount
) 并且该类可以被调用,例如 UserWithOrderCount
我考虑过一些选项:
- 制作两个业务类并在每个 DAL 方法中分别填充它们(这个对象很简单,但考虑到该方法可以有一个复杂的选择查询需要封装以供重用,因此存储库模式不太适合这里,至少我认为是这样)。
- 仅创建一个包含所有属性(
UserId、UserName、CityName、StateName、CountryName、OrdersCount、List
)的对象User
,并仅填充每个 DAL 方法中的一个子集,但这意味着当您使用方法时存在语义耦合,因为您必须知道哪些字段子集是从数据库填充的,而语义耦合是所有耦合中最差的。 - 如果我稍后需要在另一个视图中使用
List
和OrdersCount
属性,则选项 1 无法很好地处理。 - 现在考虑一下,如果您使用 ASP.NET MVC 良好实践告诉您需要一个 ViewModel 来传递给视图,我想从我的 Businnes Layer 返回 ViewModels,但我认为这不是一个好主意,感觉就像我违反了某些规定,而且也是不可能的,因为我的业务层位于另一个程序集中,而不是 Web 应用程序中。
- 我不想一遍又一遍地编写相同的 Linq 查询,但如果使用 NHibernate 或 EFCodeFirst 是“类似”选项一,我将需要创建大量小型业务对象。
你如何处理这种情况?我认为这是一个高层设计决策。
I am building a middle size system and I am facing a problem that probably some of you have faced before. In my business layer I return business objects with a subset of properties that are important for that business method, I am worried because I can end up with to much objects with meaningless names or only one where only a subset of properties are filled in a given method. Let me put an example.
Case 1
For example, a user belongs to a city, which in turns belongs to a state and a country, User
, City
, State
and Country
are tables on my database with a lot of fields, but I want a list of users with a list of Orders, so I create a business object called for example UserWithOthers
with only the important properties (UserId, UserName, CityName, StateName, CountryName, List<Order>
) and my DAL retrieves only that fields from Database.
Case 2
I want to return now a user with the amount of orders, I end with the following fields in my business object (UserId, UserName, CityName, StateName, CountryName, OrdersCount
) and the class could be called for example UserWithOrderCount
I have thought in some options:
- Make that two business classes and fill them separately in each DAL method (this objects are simple but consider that method can have a complex select query that needs to be encapsulated for reuse so repository pattern doesn't fit well here, at least I think that).
- Create only one object
User
with all the properties (UserId, UserName, CityName, StateName, CountryName, OrdersCount, List<Order>
) and fill only a subset in each DAL method, but that implies Semantic Coupling when you use a method, because you must know which subset of fields are filled from database, and semantic coupling is the worst of all coupling. - Option 1 doesn't handle well if I need later in another view, both,
List<Order>
andOrdersCount
properties. - Consider now that if you use ASP.NET MVC good practices tells that you need a ViewModel to pass to the view, I thought to return ViewModels from my Businnes Layer, but I don't think is a good idea, it feels like I am violating something, and also is not possible because my business layer is in another assembly and not the web application.
- I don't want to write the same Linq query over and over again, but if use NHibernate or EFCodeFirst is "like" option one, and I will need to create tons of small business objects.
How do you handle this situation? I think this is a high level design decision.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,我绝对同意您关于一些不应该做的事情的看法:
不要部分填充业务对象,因为然后您将负责了解哪些属性填充到业务层的客户端上,这是非常糟糕的做法。
不要从业务层返回 ViewModel;您的业务层应该代表应用程序域的业务概念,而 ViewModel 是一个数据对象,其中包含显示该域一部分的特定视图所需的数据 - 两者是非常不同的东西,业务层应该完全不知道其业务对象用于任何类型的 GUI。
我会同意你的第一个建议 - 创建一个单独的业务对象来代表每个业务概念。然后,我将使用 ORM(如 EF 或 NHibernate)为我填充这些对象,并为每组对象提供专用存储库。然后,我将使用一个应用程序层来调用存储库来返回所需的任何对象。为此,当您知道需要一起使用这两种类型时,您的存储库可以包含返回连接的用户和订单的方法。这允许您在一个查询中返回用户及其所有订单,同时保留单独的、有意义的实体来表示用户和订单。
First of all, I definitely agree with you about some things not do:
Don't partially-populate business objects, as you then put responsibility for knowing which properties are populated onto the business layer's clients, which is very bad practice.
Don't return ViewModels from your business layer; your business layer is supposed to represent the business concepts of your application's domain, and a ViewModel is a data object which contains the data necessary to display a particular view of one part of that domain - the two are very different things and the business layer should be completely unaware that its business objects are used in any kind of GUI.
I would go with your first suggestion - create one separate business object to represent each business concept. I would then use an ORM (like EF or NHibernate) to populate those objects for me, with dedicated Repositories for each group of objects. I'd then use an application layer which calls the repositories to return whatever objects are required. to this end your Repository can include methods which return joined Users and Orders for times when you know you need to have those two types used together. This allows you to return a User with all their Orders in one query, while retaining separate, meaningful entities to represent Users and Orders.