为什么Web架构应该松散耦合?

时间:2010-05-19 19:14:15

标签: asp.net asp.net-mvc architecture loose-coupling

当我看到ASP.NET MVC项目时,我每次都看到松耦合架构。

我需要在Web架构中使用松散耦合(如果我不进行单元测试)?

这有什么优点缺点

解析图层/类的主要原因是什么?

如果我不想改变我的DAL怎么办?我的意思是什么时候才能改变我的整个DAL?!所以我可以将我的DAL耦合到UI。这有什么不好的?

13 个答案:

答案 0 :(得分:31)

松散耦合允许您在应用程序的一个区域中进行更改而不会影响其他区域。从理论上讲,它允许您执行更改数据访问层而无需重建业务或UI层的操作。

它确实使您的应用程序更灵活,更擅长变更,并且更易于维护(因为您不必担心应用程序的某个区域发生变化而导致另一个区域发生变化)。

答案 1 :(得分:18)

对于任何非常小的项目,它都会为您节省大量时间,在这些项目中,我将这些项目定义为少于几千行代码(取决于语言)。

原因是,一旦你超越了超级小项目,每次更改或更新都会变得越来越紧密。松散耦合使您可以继续前进,添加功能,修复错误等。

在某一点上,我认为任何程序都成为维护,更新和添加的噩梦。设计越松散耦合,这一点就会延迟。如果它是紧密耦合的,可能在大约10,000行代码之后它变得不可维护,添加一些功能变得不可能,而不是从头开始重写。

松散耦合允许它增长到1,000,000 - 10,000,000行代码,同时仍然能够在合理的时间内进行更改和添加新功能。

这些数字不是字面意思,只是因为它们只是组成,而是为了让它感觉它有用。

如果你永远不需要更新程序而且它非常简单,那么可以紧密耦合。甚至可以这样开始但是知道什么时候将它们分开,但是你仍然需要编写松散耦合代码的经验来知道它在什么时候变得有益。

Enterprise Fizzbuzz是一个故意幽默的例子,说明如何过度使用过度工程,并不是每个项目都需要相同级别的解耦。

MVC通常被认为是一个很好的起点,因为大多数项目都会变得足够大以使其有所帮助。当项目变大时,这种解耦水平是不够的,M部分本身需要分成几层,依此类推。没有一个适合所有人,但MVC对于大多数项目来说是一个很好的解耦。

答案 2 :(得分:12)

在论文中,松散耦合有许多优点,但在实践中,很难使其正确恕我直言。以下是一些优点:

  • 系统可以在生命周期方面独立发展。

  • 系统可以用不同的语言编写,最终在不同的操作系统上运行。

  • 系统可以(而且应该)由不同的团队构建。您可以外包系统的开发。事实上,这几乎是扩展软件开发组织的唯一方法。

以下是一些缺点:

  • 一开始就是更多的工作,如果你做得不好,你可能永远也看不到它的好处。

  • 定义API /合同非常困难,需要经验丰富的开发人员。最初很容易做,但从长远来看很难。

  • 松散耦合的推广实际上可能导致各处的打字松散。您可以观察到添加到每个类或接口的泛型类型的“对象”参数或返回类型的使用增加,而不是使用明确定义的有意义的对象。这种不良影响是普通开发人员可能会在任何地方添加狂野转换操作,假设所谓的松散耦合系统的两侧都有类型。

  • 一些松散耦合技术基于接口定义的泛化,旨在避免直接依赖。请记住,界面应该在定义和发布时刻在石头上。现在,这不是我所谓的松散耦合。 .NET类利用JIT和方法过载等技术可以成为更好的松散耦合工具。因此,这些接口和工厂无处不在的问题是它会导致类型,组件,测试用例等的倍增......而且还会带来更多的工作和复杂性。而不是简化事物,而不是建立一个系统,你将不得不建立许多。 “N层系统是工作的N倍”: - )

  • 松散耦合以某种方式绕过了有史以来最强大的工具之一:编译器(C#或其他)。这实际上就是它的全部目的,但它肯定有一些缺点,因为编译器所做的所有基础工作(类型检查等等)都需要在其他地方(测试)完成,这将产生成本。

  • 许多开箱即用的工具可能不再适用。您将无法使用Visual Studio“转到定义”或“查找所有引用”等内容。

答案 3 :(得分:8)

松散耦合的体系结构将在您的应用程序需要更改或增长时为您提供帮助。 任何非平凡的应用最终都需要改变或增长。

如果使用松散耦合的体系结构进行设计,则在需求发生变化时,应该只影响应用程序的一小部分。由于耦合架构太紧,许多部件需要更改,并且很难准确识别哪些部件会受到影响。

在我看来,TDD的一个主要好处是有助于促进松散耦合的架构。

答案 4 :(得分:5)

我认为在其他答案中解释了“正确”的方式。但我现在可以根据自己的经验写作。

在决定架构时,您必须考虑几件事情。

一个。的 客户端

你有足够的时间让一切都“正确”(伟大的架构,测试等......)?有时客户希望快速查看结果。我们可以抱怨时间很短,产品不会达到最高标准,但最终这是我们的问题。在这种情况下,我们向客户解释他将得到什么,并写下我们都知道的意大利面条代码。

客户要求是什么(在可靠性,可扩展性,可扩展性,速度方面)?我认为这是自我解释的。有时客户指示“正确”的方式。我们可以为客户提供“正确”的方式,但最终客户将决定(当然,取决于时间和金钱)。

开发后谁将支持该系统?我想支持一个很好的解耦代码。因此,当我编写代码时,我会尽力使其“正确”。有时候,我可能会将视图和控制器结合起来,或者结合一些服务并对它感到满意。知道我自己的代码很容易支持它。

湾的 项目

项目的规模是多少?有些项目非常小,任何复杂的架构都是不合理的。

软件是否有可能在未来迅速发展(更多功能)?这是最大的挑战之一。但如果软件增长,则意味着它是成功的。您可能有更多资源可供使用。重构代码并使其“正确”是相对容易的。

项目是否可能存在可扩展性问题?在用户和数据方面,有些项目永远不会增长。我已经看到过使用Oracle RAC数据库设置试图看起来很严肃的项目,当一个简单的嵌入式数据库工作得很好!

您是否启动了该项目,或者您是从其他开发人员那里接管的?这是谁将支持软件以及软件增长的问题的组合。您可能会从其他开发人员那里获得意大利面条代码。你有时间和资源使它“正确”吗?

℃。 开发团队

团队是否经验足以使脱钩正确?当我缺乏经验时,我试图编写“正确”的代码。我失败了。关键是要真正了解您的开发团队,他们的技能和知识。不要低估这个问题。与经验不足的开发人员合作时,我通常会对架构做出一些牺牲。将要做出的牺牲是我所拥有的最好的教育猜测。你可以牺牲的建筑有一些点,有些你不能。通常你先前做出的一个或多个牺牲会回来并咬你。

开发人员是否经历过编写自动测试?仅进行自动测试是不够的。它们应该是完整的(尽可能的)并且做得恰到好处。如果你的测试很弱,那么你最好不要使用它们。你不会想要靠在满是洞的墙上。

结论

我知道我们都想成为专业人士。作为专业人士,我们必须考虑所有因素。我们不能浪费时间和精力以“正确”的方式做事。有时我们必须考虑其他因素(现实)并做出我们的选择。最重要的是和它一起生活。

答案 5 :(得分:4)

优点:

  • 可伸缩性 - 允许您扩展数据库访问层
  • 可交换性 - 例如电子邮件提供商代码
  • 可维护性 - 只需在一个地方更改代码
  • 轻松设置单元测试 - 您可以模拟像数据库
  • 这样的对象

Disavantages:

  • 可能还有几行额外的代码
  • 一些额外的接口类

答案 6 :(得分:3)

首先,您应该编写单元测试;)

假设您最终需要更改基础数据库。如果您的数据访问代码与业务逻辑紧密耦合,那么这可能是一项巨大的努力。使用松散耦合的代码,您的业务逻辑将不受影响。

如果您决定编写一些利用后端组件的命令行实用程序,该怎么办?使用松散耦合的代码可以更轻松地为系统提供多个入口点。

答案 7 :(得分:3)

它将为您提供可扩展性。例如,如果您有服务层,则可以在多个服务器中将其分开。此外,您将具有更少的依赖性,并且修改将更容易。代码支持也会更容易。

在这里,您可以看到有趣的小文章:SOA - Loosely Coupled...What?

不久它说:

  

松散耦合系统提供了许多优势,包括支持在运行时延迟或动态绑定到其他组件,并且可以调解组件结构,安全模型,协议和语义的差异,从而抽象出波动性......

答案 8 :(得分:2)

因为即使它没有与基于浏览器的HTTP Web UI进行通信,后面的内容也可能有用。因此,您希望能够将其与特定UI断开连接。

答案 9 :(得分:2)

耦合和解耦类的主要原因是可扩展性。一个人的变化不应该影响其他人。

如果构建当前使用MYSql数据库存储数据的应用程序。现在我们有新的要求将数据存储在MSSQL中作为他的后端系统。如果您构建的系统与MYSQL库更加集成,那么您将离开什么解决方案。重写MSSQL的整个应用程序。现在怎么样我们基于MSSQL构建一个新的DAL并将Dal插入系统而不对系统(UI)进行任何更改。

应用程序基于接口调用例程,接口不受实现限制。

尝试阅读Unity或MEF,这些主题将为您提供良好的洞察力

答案 10 :(得分:2)

这完全取决于制作应用程序的意图以及商业利益。如果企业热衷于扩展它并且涉及足够的燃料(阅读语料库),这给了建筑师足够的思考,使应用程序获得长期利益。

所以优点是: -

1)如果您正在使用第三方控件/代码:始终写一个“包装器/适配器层”,以便出于任何原因,如果它不可用,您可以获得其他内容并更改适配器层,不会干扰您的应用程序存储库代码。

2)在“服务层”中封装特定的复杂功能,这可能需要也可能不需要数据库请求:这是有益的,因为请求和响应保持不变(它肯定会随着时间的推移而变化)好吧),你总是可以在不改变输出的情况下处理特定代码的性能。有了单位案例,我们还可以衡量代码的性能。

3)让特定的角色编写特定的代码:如果我们创建了很多角色,团队中的人就可以更容易地专注于他们的特定存储库,而不是迷失在一堆不相关的代码中。

4)专注的质量保证:如果我们有分层架构,它总是有助于更好地将质量保证作为重点。

5)查找/解决错误:使用分层架构并假设您具有良好的日志记录,它总是可以节省时间来查找错误并解决它。

缺点是: -

1)使用这种框架设置应用程序将花费额外的时间。所以“上市”会被推迟。

2)如果你太过技术爱好者,它最终可能会被杀死。

3)额外的交易延迟:当数据传播到各个层时,每次交易都会增加额外的延迟。

关于更改DAL: -

当然,有一段时间,当性能优先于当时的功能时,您将不得不开始考虑导致DAL更改的数据提供者。

如果您将DAL与UI结合,每次更改DAL(如果有的话,根本不更改)时,您始终需要在生产中重新发布整个二进制文件。其中有一系列问题(如果你需要的话,我可以随便解释一下这个问题)

这就是原因,最初花费时间并总结出应用程序“自毁”的时间总是更好。我的意思是应用程序的生命是什么,如果答案得当,休息一切都会落实到位。

答案 11 :(得分:1)

分工,即人与人分离的关注点。您的HTML专家应该能够独立于您的SQL女神工作。

前端的戏剧性变化应该能够在不撕毁后端的情况下继续进行,反之亦然。换句话说,你应该只雇用一个人而不是两个人。

答案 12 :(得分:0)

以一个没有人讨论的角度回应; 时间解耦。它可以通过以下几种方式完成:

使用上述内容(异步monad除外)时,通常会显式处理消息而不是方法调用。这导致思考与消息传递的工作方式(处理它们的幂等性,在传输中存储它们的队列,附加到其包络的安全数据,在处理程序而不是请求者中重试逻辑......)。

通过逐步解耦的面向消息的体系结构,您可以更轻松地扩展应用程序 - 特别是如果您主要进行发布 - 订阅(参见事件驱动的体系结构) - 任何事情都可以监听事件并做出反应他们并没有将集成商的实现绑定到初始调用站点。

将工作推送到队列的网站通常会更具响应性,因为它们不会让工作线程等待IO发生。从长远来看,它们的维护成本通常也更低。

对于不同类型的编译类型耦合(以及其他指标),请浏览http://www.ndepend.com/Metrics.aspx并自己阅读一些内容。