N层架构

6
我处于从零开始设计和实现系统的情况中。关于架构,我有一些问题,希望得到您的评论和想法。
项目简介:这是一个以数据为中心的Web应用程序。
该应用程序将在Microsoft .NET Framework 4.0上构建,使用MS SQL SERVER 2008数据库。
要求:
1.富UI和强大
2.多设备支持(每个浏览器和每个设备)
3.松散耦合
以下是我建立的架构图:
简述架构
1.演示层:HTML5 / ASP.NET MVC + JQuery(第一版的多设备支持Web应用程序)
2.分布式服务:WCF(XML / JSON / JSONP)
3.域层(业务层):所有业务逻辑
4.数据持久性(DAL层):Entity Framework 4.0采用数据库优先方法。 POCO实体通过T4模板生成并分离出来
5.基础结构层:包含常见库,如POCO实体,异常处理,日志记录等
我的担忧:
1.由于应用程序需要“松散耦合”,因此如果业务需求增长,则可以轻松插入新模块而不影响架构。因此,我考虑使用存储库模式以及IoC和DI(可以是Unity / Ninject / Sprint.NET或任何其他)
2.WCF同时支持XML和JSON
3.分布式服务层放置IoC和DI
4.使用Enterprise Library 5.0进行异常处理和日志记录
期待有价值的评论和建议。如果我做错了什么,请指出正确的方向。

1
FYI - “Tier”和“Layer”不是等价术语。Layer指的是逻辑分离,就像你所描述的那样。而Tier通常指的是硬件的物理分离,例如数据库服务器、Web服务器。 - MattDavey
只是出于好奇,你用什么软件创建了这个图表? - henginy
我正在使用Visual Studio 2010(旗舰版)。 - coddey
4个回答

6
我建议以下评论:从一开始,您的方法将创建紧密耦合。这直接违反了您的第三个要求“松散耦合”。
在您的图表中,您定义了两个模块。主模块和模块2。我猜这两个模块彼此非常不同。我的意思是,您可以完全分别开发它们,然后插入它们,因为它们所涉及的业务问题是不同的。
但是,您当前的架构方法:
- 将主模块和模块2数据耦合到同一个数据库中 - 将主模块和模块2业务对象耦合到同一个业务层中 - 将主模块和模块2服务耦合到同一个服务层中 - 耦合主模块和模块2的部署和管理
值得考虑的是:将主模块和模块2构建为单独的垂直服务堆栈。
我的意思是,主模块和模块2成为“主服务”和“服务2”。
每个服务都有自己的数据库、业务层、服务层和UI组件。
然而,这引出了一个问题:“如何让主服务和服务2一起工作来创建我的产品?”
为了解决这个问题:
1. 在UI端,您可以使用客户端代码将Main Service和Service 2的响应加载到一个视图中。 2. 在后端,您可以使用发布-订阅消息传递,允许Main Service订阅在Service 2中发生的事件,反之亦然。
这将导致基于松散耦合的垂直服务堆栈构建的应用程序,通过异步交换消息来保持一致性。
如果您需要向应用程序添加新模块,则可以创建支持所需功能的新服务堆栈,并将其连接起来,而无需或只需进行很少更改其他堆栈(理想情况下,更改现有堆栈的唯一原因是它们希望订阅来自新模块的事件)。
这是与您提出的方法非常不同的方法,但在我看来,这样可以更好地满足松散耦合的要求。

你好,感谢您的建议。您介意再详细说明一下“每个服务都有自己的数据库、业务层和用户界面组件”吗? - coddey
1
这些是在开发服务堆栈时可以应用的独立关注点。在我看来,控制反转(IOC)与解决方案设计关系不大,更多的是技术架构问题。 - tom redfern
3
我主要观点是:为什么要计划将不同功能耦合成一个应用程序?如果应用程序中的两个部分垂直不同,则应该将它们作为独立的问题进行规划、开发、部署和管理。 - tom redfern
这大部分是从Udi Dahan的演讲中直接摘抄过来的(链接在我上面的第一个评论中)。他比我更好地解释了这一切。 - tom redfern

1

理论上,WPF、WinForm等UI应该调用WCF层。我假设您需要有多个UI以满足业务需求,否则,如果只能使用一个UI,则响应式Web UI是最灵活的选择。

但是,我认为您的MVC UI不需要使用WCF层。它可以直接调用领域层。这样会更快,且可以去掉无用的一层。

显然,只要您的WCF层中不包含任何逻辑,这种方法才可行。并且WCF层确实不应该有任何逻辑。

您还表示希望在分布式服务层中放置IoC和DI。从您的MVC UI角度来看,这不太合理。您需要在MVC项目中使用DI以便测试控制器。


完全不需要,如果领域层拥有所有的逻辑,而WCF层只是一个门面,那么当调用它没有意义时,绕过WCF层是有道理的。 - Joe Ratzer
需要比领域层中所包含的更多逻辑。应用层应该封装构成平台的各种交易,并协调领域层中存在的逻辑单元的工作流程。 - MattDavey
请参见http://martinfowler.com/eaaCatalog/serviceLayer.html。具体来说,“在每个操作中协调应用程序的响应。”这是它在领域模型中调用一系列操作的关键点。这些工作流程是应用程序的重要组成部分,不应被绕过。 - MattDavey
我完全没有谈论WCF。从你最初的回复“去掉一个无意义的层”,我认为你是在主张UI直接与域模型通信 - 这将导致每个UI中都有大量的事务逻辑重复。我认为我们可以达成共识,确实需要一个服务/应用程序层(无论它是否具有WCF、ServiceStack或其他外观)。 - MattDavey
我认为我们的误解是对原帖作者的提示,他的架构有点模糊;) - MattDavey
显示剩余4条评论

1

为什么架构图中没有使用ASP.NET的领域层?

看起来你可能过度设计了你的应用程序。此外,虽然支持6种(左右)不同的前端技术看起来很棒,但维护所有这些技术的工作量将是可怕的。我建议你只使用一种前端技术 - 最有可能是带有客户端MVC或类似功能的HTML5。


0

看了你的图表,我有几个问题不太清楚:

  • 领域模型在哪里?是在领域核心还是持久层中的“模型”?
  • 领域层如何与数据访问层交互?与服务/应用程序层和领域层之间的交互不太清晰。
  • 领域层中的存储库和数据访问层中的存储库有什么区别?我通常将领域层中的“模型存储库”作为对领域模型对象进行操作的存储库,而将数据访问层中的“数据网关”作为对DTO进行操作的存储库。
  • 什么是领域核心?这是应用程序层事务的实现吗?
  • 是否需要进一步抽象持久性框架?(EF)

  1. 领域层是业务层,包含纯粹的业务逻辑。
- coddey
放置在基础设施层的POCO实体是没有任何逻辑的模型。目前,领域层直接依赖于它们(您知道其他方法吗?)。 - coddey
我建议从贫血领域模型(http://en.wikipedia.org/wiki/Anemic_domain_model)转换为丰富的领域模型。 - MattDavey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接