【问题标题】:WCF/Client apps - where should business logic go?WCF/客户端应用程序 - 业务逻辑应该去哪里?
【发布时间】:2010-12-22 06:13:17
【问题描述】:

我们正在使用 WSSF 构建 WCF Web 服务。这个想法是,它将通过服务公开我们的主数据库,并允许我们在服务之上构建各种应用程序和网站。目前我正在构建一个简单的客户端应用程序,该应用程序将从该服务下载一些数据,对其进行操作,然后将其作为报告 CSV 文件提供给用户。

现在的问题是(操作数据的)业务逻辑应该放在哪里?我想我会把它放在服务中。我已经有一个业务层,其中包含与数据库(客户、订单等)几乎一一对应的简单对象。我想我会制作一些“更高级别”的对象来操作数据。例如,通过使用客户、订单和其他对象并生成报告等。我认为最好的地方是服务的业务层。这样,如果需要,我们可以将这个逻辑重用于各种不同的应用程序。

很遗憾,我的老板不同意。他想要“关注点分离”,并表示此逻辑的正确位置应该是在客户端应用程序内部的业务层中,而不是在服务中。我想这可能更简单,但我想在服务业务层中使用我强大的对象模型来编写这段代码。服务公开的对象不是“真正的”对象,实际上只是轻量级数据结构,没有服务业务层内部存在的完整对象模型的力量。

你们怎么看?

【问题讨论】:

  • 问他:如果我们需要另一个客户端,我们应该复制所有的业务逻辑,还是使用一个集中的版本?
  • 继续@Rubens Farias 的逻辑,如果需要修复业务逻辑并且它驻留在客户端中,则需要更新所有 个客户端。如果它在服务中,则只需更新服务。
  • 感谢您的回复。是的,我也认为可重用性很酷。我想主要的缺点是更新服务可能会破坏所有现有客户端。

标签: c# wcf design-patterns wssf


【解决方案1】:

我的投票很明确:

  • 将尽可能多的数据完整性检查放入数据库中
  • 将任何其他业务逻辑检查放入服务服务器端的业务逻辑层
  • 仅将“必填字段”等简单检查放入客户端层,由数据库模型或您的业务模型自动确定

为什么选择数据库?
任何形式或形式的 SQL 都有一些非常基本且非常强大的检查功能 - 确保内容是唯一的,确保表之间的关系完整性是给定的等等 - 使用它!如果您在数据库中进行这些检查,那么无论您的用户最终如何连接到您的数据(可怕的场景:经理能够使用 Excel 直接连接到您的表以执行一些商业智能工作......),那些检查将到位并将执行。强制数据完整性是任何系统的最高要求。

为什么要在服务器上执行业务逻辑?
其他回答者提到的相同原因:集中化。您不希望仅在客户端中拥有业务逻辑和检查。如果您公司的其他部门或第三方外部顾问突然开始使用您的服务,但所有的验证和业务检查都没有到位,因为他们不知道怎么办?不是什么好事……

客户端中的逻辑
是的,当然 - 您还想在客户端中进行一些简单的检查,特别是如果它是一个 Web 应用程序。应尽早强制执行诸如“此字段是必需的”或“此字段的最大长度”等内容。理想情况下,这将由客户端从数据库/服务层自动获取。 ASP.NET 服务器控件具有可以自动打开的客户端验证,Silverlight RIA 服务可以在您的后端数据模型中获取数据限制并将它们传输到客户端层。

【讨论】:

  • 感谢您的详细回复马克。我当然同意你所有的cmets!我想我正在谈论的那种逻辑是将来自多个地方的数据聚合到某种报告或导出文件中。与其说是检查完整性等。但是,从您的 cmets 和其他人看来,大多数开发人员似乎也会将这类事情放在服务业务层中。如果我可以访问这一层中成熟的业务对象,而不是服务公开的轻量级数据合约,那么开发也会容易得多。干杯马克
  • +1 有一个警告。您的客户是否有可能(现在足以担心)多样化,即​​客户需要稍微不同的逻辑、第三方对您的服务的使用或更广泛的使用。在这种情况下,单个集中式 BLL 最终可能会拥有大量控制逻辑来确定为每个客户端执行的操作。好的,因此在服务层中引入抽象层会有所帮助,并且通常可以解决问题。没有理由不能在逻辑上分离这些关注点,而是在物理/实施方面将它们放在一起。蛋糕吃吗?
  • @MattC:是的,是的——如果您需要支持多个客户端,您的要求可能会有所不同。但我仍然认为,即使在服务器上拥有三、五组不同的验证规则,也比拥有数十或数百个客户端要更新更容易管理......
【解决方案2】:

我认为什么是“正确”取决于您的应用程序架构。关注点分离当然是有价值的。听起来你老板觉得现在的模式是把服务器作为数据访问层,把数据库映射到业务对象,业务逻辑应该在客户端实现。

无论业务逻辑是在客户端还是服务器上实现,您仍然可以实现关注点分离。重要的不是您在哪里进行处理,而是您在应用程序各层之间设计的接口有多简洁。

了解更多有关客户的信息可能会有所帮助。您正在处理浏览器/Javascript 客户端吗?如果是这样,那么我会在服务器上保留尽可能多的处理,并或多或少地以您希望它显示的形式向客户端发送数据。

如果它是一个 C# 客户端,那么在这方面你可以使用更多的功能。您可能可以将 WCF 服务的响应重构为您在服务器端使用的相同业务对象类,并获得与服务器相同的功能。 (只需在两个解决方案之间共享业务对象类。)

【讨论】:

  • 感谢 cmets。将有 2 个客户端组件用于 WCF Web 服务的这种特殊用途。一个 Asp.NET Web 应用程序和一个 .NET Windows 服务。这意味着客户端不缺电。实际上,在我看来,您不能在 WCF Web 服务中公开标准业务对象(使用 Save() 等方法和按需加载的属性等)。它公开的对象是称为“数据契约”的简单数据结构。
  • DataContract/DataMember 东西本质上只是一个对象接口,它决定了它如何通过网络发送。您仍然可以将各种方法放在那里。这些方法本身不会通过您的 Web 服务请求发送,但只要两个应用程序使用相同的业务对象库,它们就作为类定义的一部分存在于两端。显然,像 Save() 这样的一些操作只能发生在一端或另一端(Save() 必须发生在服务器上)。另一方面,客户端可以有一个调用服务的保存方法的 ClientSave() 方法。
  • 这很有趣,内特。我没有考虑过这种可能性。我认为将业务对象保留在业务层等中可能会更好。尽管从数据层对象转换为业务层对象再到服务层对象是很痛苦的......
【解决方案3】:

对此没有硬性规定,但在这种情况下,我会说你的老板比你更错误:) 每个人对此的看法都会略有不同,可能有很多原因导致你的业务逻辑放在业务层以外的地方,但很少有理由将它放在客户端应用程序中 - 你可能会争辩说,当它在客户端应用程序中时,它是 UI 或表示规则而不是业务规则.

如果 Web 服务将被多个应用程序使用,那么您尽可能希望 Web 服务端的业务逻辑。我实际上会有一个非常薄的 web 服务层,它所做的只是接受调用,然后将执行传递给实际的业务层。我还将在数据库层而不是业务层中完成数据库数据和业务数据实体之间的映射。

【讨论】:

  • 嗨 Slugster 是的,这就是我正在使用的架构。数据层是 ADO 实体框架,我有一个业务层,其中包含使用实体框架对象填充的对象。该层包含大部分代码。 WCF Web 服务层是使用 WSSF(Web 服务软件工厂)构建的。该层只是将业务对象转换为 WCF 消息。
猜你喜欢
  • 2011-06-28
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
  • 2017-03-27
  • 2016-09-09
  • 1970-01-01
  • 2016-12-18
  • 2012-07-16
相关资源
最近更新 更多