我们应该在服务器和客户端上使用相同的业务类吗?

时间:2009-11-16 14:46:04

标签: .net architecture orm

想象一下,您在服务器应用程序上拥有业务领域模型,并且您将开发富客户端应用程序。

您可以使用DTO将数据传输到客户端并更改为服务器或使用WCF服务并在客户端上生成新类。

另一种方法是在业务逻辑层中传输与服务器上使用的相同对象。这些也可以是ORM使用的类。在这种情况下,类不应包含特定于服务器的逻辑,但它们可以包含一些通用逻辑。

我的问题是:

  • 您使用哪种变体,建议您在新项目中使用哪种变体?
  • 哪个更好?
  • 在某些情况下,第二个更好吗?你怎么能描述这些情况呢?
  • 有多少应用程序使用第一种/第二种方法?
  • 如何在特定应用中选择?

3 个答案:

答案 0 :(得分:4)

我们很难在项目中找到这个问题的答案。这就是故事:

我们认为重用类很棒,会减少许多重复的东西。 NHibernate允许从会话中分离和重新附加类,因此它似乎是微不足道的。

  • 我们遇到的第一个也是最大的问题是你无法发送整个数据库,所以我们不得不将实体模型拆分成碎片并用guid而不是普通的引用来链接它们。这使查询变得非常复杂。

  • 我们不得不实施一些技巧,因为序列化,持久性和数据绑定都存在问题。这个相当丑陋的黑客进入了同一个班级。它们变得越来越大。

  • 属性似乎无害,直到您在每个类和每个属性上看到大量属性,因为每个层都会添加其属性。

  • 实体隐式开始支持两种“模式”: DTO模式持久模式。当PrepareSerializationAfterDatabaseRetrieval等类型的方法出现时,这一点就很明显了。某些属性只能在服务器中使用,其他属性只能在客户端中使用。

显然,维护变成了一场噩梦。没有人冒更换实体的风险,因为你必须改变整个系统中的东西。

然后我们开始切换到Dtos。

经过大量的工作,我们设法重写系统的一些重要部分以使用Dtos。而且 - 突然间每个人都开心了。

您可以维护序列化。您可以维护数据库模型并优化查询。您可以在不破坏任何内容的情况下对cient模型进行更改。

结论:与在所有层中使用相同类的可维护性损失相比,为每个层维护类似类的努力是荒谬的。

仍有一些普通的实体和值类型的类同时用作实体和Dtos。

我可以想象一个只包含普通实体的小应用程序可以在没有Dtos的情况下生存。

答案 1 :(得分:2)

您应该编写尽可能少的符合您要求的课程。这样你就不太可能重复自己了,测试的次数减少了,而且当你需要更改代码时,可能会出错的事情会更少。

如果您的客户端代码实际上需要执行域逻辑,您应该:

1)直接反序列化到域模型类中(特别是如果你使用支持持久性无知的ORM)。

// Customer is a business object / aggregate root with domain logic
ICustomer customer = customerRepository.Get<Customer>(customerId);

2)使用数据传输对象初始化域模型类:

// Given a customer data transfer object
ICustomer customer = new Customer(customerDto);

如果我不需要,我宁愿不写DTO,所以我更喜欢第一种方法。但有时候DTO是必要的,就像你正在使用服务代理生成的自动生成类一样 - 或者你是一个暴露自己的DTO的服务。

如果客户端不应该执行业务逻辑,则永远不需要了解您的域模型类。在这些情况下,客户端应使用数据传输对象或自定义视图模型类。

答案 2 :(得分:0)

我必须同意前两个答案。但是,请注意保持BO / DTO类同步的努力(我会考虑使用代码生成)。

对于想要向另一个方向前进的人,请参阅我的回答here - 他们希望在他们的系统中整合众多DTO / BO。