我是一个小型组织的.NET Web开发人员。我们这里有一些熟练的开发人员,但我们没有的是那些为更大,更有组织的软件商店工作的人。我们做得很好,但我发现自己想要更好地构建我的代码,只需要很少的地方来寻求建议。
谈到这一点。在某些时候,我们组织中的某个人决定,无论何时我们都必须进行任何数据访问,我们将使用webservices。因此,我们的硬件架构是有条理的,这是我们访问数据库的唯一方式。理论上这听起来不错,但问题是我们的大多数应用都是这样的:
aspx.cs中的代码混乱代码 - >没有任何东西但只能调用存储过程的Web服务
除此之外没有太多分离。每当我开始尝试研究更好的结构实践时,我最终会阅读关于依赖注入,肮脏的属性和类工厂的事情,我的头开始游泳,我会沮丧地继续前进。
这是我的奇迹的一个基本例子。因此,假设我必须创建一个页面来从列表中选择员工,编辑它们并更新数据库。让Web服务在get上返回Employee对象,并在更新上接受Employee对象是否更好?或者让Employee对象调用webservice来自行填充是否更好?
换句话说:员工emp = svc.GetEmployee(42); vs Employee emp =新员工(42);
第二个例子似乎是更好的组织更新(更新相关属性并调用emp.Update()),但问题是如果我需要获取Employees列表? Employee emp = new Employee(id)会不一致;对于一个单一的员工,但请输入svc.GetAllEmployees()作为列表。
我觉得我有点乱,所以我会停止尝试解释,希望有人理解我的困惑。我感谢任何人都可以提供的任何建议。谢谢!
答案 0 :(得分:3)
与任何事情一样,您可以采取多种不同的方法。 (所以希望这里会有很多好的和不同的答案,因为这绝对是一个重要的问题。)
您应该问自己关于设计的一个问题是“应用程序之间需要共享多少逻辑?”使用您提供的小GetEmployee
示例,听起来您想知道将模型放在您的域中的位置。这些模型是否被多个应用程序使用?业务逻辑是否跨应用程序共享?
如果是这样,那么您可能希望您的域模型支持Web服务。也许通过其数据访问和外部依赖关系在这些服务背后构建一个富域(请记住依赖注入事项,最好的设计决策需要在服务层后面的域中,因为这是整个系统的核心)。
然后,当然,你如何访问这个逻辑?同样,有很多选择。我个人最喜欢的设计是有一种抽象服务层的请求/响应系统。对于真正断开连接的异步系统来说,像NServiceBus一样酷,像Agatha一样简单,只是抽象出实际的服务并将请求/响应逻辑放在代码中,或者可以使用{{3 (我一直有意做的事)或其他项目等等。天啊,你可以只滚动一个普通的旧WCF甚至SOAP服务层,仅此而已。这取决于你。
此时,您正在服务层查看一个相当程序化的系统。这不是一件可怕的事情。将服务层视为MVC站点。您向它发送一个请求,填充了某种传入的视图模型,它在其所有面向对象的优点中执行其域事务,并以传出视图模型的某种XML表示形式返回视图。现在你有一个重复的模式。您的客户端应用程序只是您的域的重要视图。他们的笨,越可互换和可更换,越好。
这允许您在服务边界的ServiceStack中封装各种“业务操作”。给定来自客户端应用程序的请求,要么整个事情成功,要么整个事情失败。将其包含在良好的错误处理和应用程序级错误/异常记录器中,以便为您提供失败请求的所有详细信息。 (想象一下,每个请求都可以序列化为一个字符串并包含在错误消息中。现在您拥有了在简单字符串中重新创建错误所需的一切,而不是要求用户“您点击了什么?”来尝试重新创建错误。)
相反,如果后端并不真正与不同的应用程序共享任何内容,并且每个应用程序都是完全独立的实体。此时,您并不需要共享服务层背后的所有逻辑,并且您完全有可能尝试进行任何类型的重叠。数据访问是服务背后唯一的东西吗?那么文件系统访问或外部Web服务访问等等呢?
如果服务背后唯一的东西是数据访问,那么您可以将您的模型和数据访问存储库保存在客户端应用程序中,就像您似乎已经习以为常,只需将存储库实现与内部引用和访问的实现交换出来服务层。 (这将是GetEmployee
示例中的第二个选项。)正确抽象,直接访问与服务访问存储库可以根据应用程序需要的位置进行简单的交换。
当然,这倾向于采用真正的持久性 - 无知方法,这可能是危险的。需要考虑性能影响。后端的某些逻辑或工作单元可能会多次命中数据库以执行多项操作。如果在服务中发生这种情况,则会增加每个数据库调用的服务开销。因此,您需要根据具体情况解决此问题。
我想我可能会在这一点上漫无目的,所以为了回到具体的事情,我们真的会问自己一些关于你的领域的问题。你能承受多久的无知?您的应用程序是否共享业务域逻辑?您是否只需要访问服务后面的其他非数据库外部依赖项?没有通用的设计始终是正确的答案。您可能最终会尝试各种设计并在适合您的开发人员和环境的设计上进行同质化。