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

发布于 2024-09-02 01:18:55 字数 260 浏览 2 评论 0原文

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

为什么我需要 Web 架构中的松散耦合(如果我不进行单元测试)?

它的优点缺点是什么?

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

例如,如果我不想更改我的 DAL,该怎么办?我的意思是我什么时候应该改变我的整个 DAL?!这样我就可以将 DAL 耦合到 UI。这有什么不好呢?

When I look at ASP.NET MVC projects I everytime see loose coupled architecture.

For what do I need a loose coupling in a web architecture (if I do not make unit tests)?

What are advantages and disadvantages of this?

What is the main reason to decouple layers/classes?

What if I do not want to change my DAL for example? I mean when shall I change my whole DAL?! So I could couple my DAL to the UI. What is bad with this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

始终不够爱げ你 2024-09-09 01:18:55

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

它肯定会使您的应用程序更加灵活,更善于更改,并且更易于维护(因为您不必担心应用程序的一个区域的更改会破坏另一个区域)。

Loose Coupling allows you to make changes in one area of the application without affecting the others. Theoretically it allows you to do things like change your Data Access Layer without rebuilding your Business or UI Layers.

It definitely makes your applications more flexible, more adept at change, and easier to maintain (since you don't have to worry about a change in one area of the application breaking another).

栩栩如生 2024-09-09 01:18:55

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

原因是,一旦你完成了超小型项目,每次更改或更新都会变得更加困难,耦合越紧密。松散耦合使您能够不断前进,添加功能,修复错误等。

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

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

这些数字并不是按字面意思理解的,因为它们只是编造的,而是为了让人们了解它在哪里有用。

如果您从不需要更新程序并且它相当简单,那么当然,紧密耦合是可以的。甚至可以以这种方式开始,但要知道何时需要将内容分开,但您仍然需要编写松散耦合代码的经验才能知道它在什么时候变得有益。

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

MVC 通常被认为是一个很好的起点,因为大多数项目都会变得足够大,它会有所帮助。当项目变大时,这种程度的解耦是不够的,M 部分本身需要分成几个层,等等。没有一刀切的方法,但 MVC 对于大多数项目来说是一种很好的解耦方式。

It will save you a lot of time for any project that isn't trivially small, where I define trivially small as less than a couple thousand lines of code (depending on the language).

The reason is that once you get past super small projects, each change or update gets harder the more tightly coupled it is. Being loosely coupled enables you to keep moving forward, adding features, fixing bugs, etc.

At a certain point I think any program becomes a nightmare to maintain, update and add on to. The more loosely coupled the design is, the further that point is delayed. If it's tightly coupled, maybe after about 10,000 lines of code it becomes unmaintainable, adding some features become impossible without essentially rewriting from scratch.

Being loosely coupled allows it to grow to 1,000,000 - 10,000,000 lines of code while still being able to make changes and add new features within a reasonable amount of time.

These numbers aren't meant to be taken literally as they're just made up, but to give a sense of where it becomes helpful.

If you never need to update the program and it's fairly simple then sure, it's fine to be tightly coupled. It's even okay to start that way but know when it's time to separate stuff out, but you still need experience writing loosely coupled code to know at what point it becomes beneficial.

Enterprise Fizzbuzz is a intentionally humorous example of how it's possible to go overboard with overengineering, and not every project is going to need to same level of decoupling.

MVC is generally considered a good starting point because most projects will become big enough for it to be helpful. When the project gets bigger, that level of decoupling isn't enough and the M part needs to be split into several layers itself, and so forth. There isn't a one-size fit all, but MVC is a good amount of decoupling for most projects.

生活了然无味 2024-09-09 01:18:55

从理论上讲,松耦合有很多优点,但在实践中,恕我直言,很难做到正确。以下是一些优点:

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

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

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

不过,这里有一些缺点:

  • 如果你做得不好,你可能永远看不到它的好处。
  • 定义 API/合约非常困难,需要非常有经验的开发人员。一开始很容易做到,但从长远来看却很难。

  • 松散耦合的泛化实际上会导致各处的松散类型。您可能会发现添加到每个类或接口的“对象”参数或返回类型、泛型类型的使用有所增加,而不是使用明确定义的有意义的对象。这样做的坏影响是,普通开发人员可能会在各处添加疯狂的转换操作,假设所谓松散耦合系统两侧的类型。

  • 一些松散耦合技术基于接口定义的泛化,旨在避免直接依赖。请记住,界面一旦定义和发布就应该被刻在石头上。现在,这并不是我所说的松耦合。利用 JIT 和方法重载等技术的 .NET 类可以成为更好的松耦合工具。因此,这些接口和工厂无处不在的问题是,它将导致类型、程序集、测试用例等的增加……并且只会导致更多的工作和复杂性。您将不得不构建多个系统,而不是简化事情,而不是构建一个系统。 “N 层系统的工作量是 N 倍”:-)

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

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

On the paper, there are many advantages of loose coupling, but in practise, it's hard to make it right IMHO. Here are some advantages:

  • Systems can evolve independently in terms of lifecycle.

  • Systems can be written in different languages, and ultimately run on different OSes.

  • Systems can (and should) be built by different teams. You can outsource the development of systems. This is in fact almost the only way to scale a software development organization.

Here are some disadvantages though:

  • It's more work at the beginning, and if you don't do it well, you may never see the benefits of it.

  • Defining APIs/Contracts is quite difficult and requires very experienced developers. It's easy to do initially, but its hard on the long run.

  • Generalization of loose coupling can in fact lead to loose typing everywhere. Instead of using clearly defined meaningful objects, you may observe an increase in the usage of 'object' parameters or return type, of generic types added to every class or interface. The bad effect of this is the average developer will probably add wild cast operations everywhere, assuming types on both sides of the so-called loosely coupled systems.

  • Some loose coupling techniques are based on the generalization of interfaces definition, with an intent to avoid direct dependency. Remember an interface is supposed to be carved in stone once defined and published. Now, that's not really what I call loose coupling. A .NET class, leveraging the JIT and techniques such as method overload can be a better loose coupling instrument. So, the problem with these interfaces and factories everywhere is it will lead to a multiplication of types, assemblies, test cases, etc... and simply more work and complexity down the road. Instead of simplifying things, instead of building one system, you'll have to build many. "an N-tier system is N-times the work" :-)

  • Loose coupling somehow bypasses one of the most powerful tool ever created: the compiler (C# or others). And that's the whole purpose of it actually, but it definitely has some drawbacks because all the ground work the compiler was doing (type checking, etc...) will need to be done elsewhere (tests), and that will have a cost.

  • Many out-of-the-box tools will probably not work any more. You will not be able to use things such as Visual Studio "Go To Definition" or "Find All References".

写下不归期 2024-09-09 01:18:55

当您的应用程序需要更改或增长时,松散耦合的架构将为您提供帮助。任何重要的应用程序最终都需要更改或扩展。

如果您使用松散耦合的架构进行设计,那么当需求发生变化时,只有应用程序的少数部分会受到影响。如果架构耦合过于紧密,许多部分都需要更改,并且很难准确识别哪些部分会受到影响。

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

A loosely coupled architecture will help you when your application needs to change or grow. And any non-trivial application will eventually need to change or grow.

If you design with a loosely coupled architecture, only a few parts of the application should be affected when requirements change. With a too tight coupled architecture, many parts will need to change, and it will be difficult to identify exactly which parts will be affected.

One of the main benefits of TDD, in my opinion, is that at helps promote a loosely coupled architecture.

国际总奸 2024-09-09 01:18:55

我认为其他答案中已经解释了“正确”的方式。但我现在要根据自己的经历来写。

在决定架构时,您必须考虑一些事项。

一个。 客户

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

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

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

b. 项目

项目的规模是多少?有些项目非常小,以至于不需要任何复杂的架构。

软件未来有没有机会快速成长(更多功能)?这是最大的挑战之一。但如果软件增长了,就意味着它是成功的。您可能会有更多资源可以使用。重构代码并使其“正确”相对容易。

该项目是否可能存在可扩展性问题?有些项目在用户和数据方面永远不会增长。我见过一些项目试图通过使用 Oracle RAC 数据库设置来显得严肃,而实际上一个简单的嵌入式数据库就可以正常工作!

该项目是您启动的还是从其他开发人员手中接手的?这是谁将支持该软件以及该软件是否会发展等问题的组合。您可能会从其他开发人员那里得到意大利面条般的代码。您有时间和资源来使其“正确”吗?

c. 开发团队

团队是否有足够的经验来实现正确的解耦?当我经验不足时,我尝试编写“正确”的代码。而我失败了。关键是要真正了解您的开发团队、他们的技能和知识。不要低估这个问题。当与经验不足的开发人员一起工作时,我通常会对架构做出一些牺牲。将会做出的牺牲是我最有根据的猜测。架构中的某些点您可以牺牲,而有些点则不能。通常,你之前做出的一项或多项牺牲会回来咬你一口。

开发人员是否有编写自动测试的经验?仅有自动测试是不够的。它们应该是完整的(尽可能)并且做得正确。如果你的测试很弱,那么你最好根本不进行它们。你不会想靠在满是洞的墙上。

结论

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

I think that the "right" way was explained in the other answers. But I'll write now from my own experience.

There are few things that you must take into account when deciding an architecture.

a. Client

Do you have enough time to make everything the "right" way (great architecture, tests, etc...)? Sometimes the client wants to see results quickly. We can complain that the time is short, and the product will not be at the highest standards, but in the end that is our problem. In this situations we explain to the client what he will get, and write the spaghetti code that we all know.

What are the clients requirements (in terms of reliability, scalability, expand-ability, speed)? I think this is self explanatory. Sometimes the client dictates the "right" way. We can offer the client the "right" way, but in the end the client will decide (depending of time and money of course).

Who will support the system after you have developed it? I would like to support a nice and decoupled code. So when I write the code I'm giving my best to make it "right". Sometime I might couple the view and the controller or couple some service and be happy with it. Knowing my own code it is easy to support it.

b. Project

What is the size of the project? Some projects are so small that any complicated architecture is not warranted.

Is there a chance for the software to rapidly grow in the future (more features)? This is one of the biggest challenges. But if the software grows it means that it is a success. You would probably have more resources to work with. It is relatively easy to refactor your code and make it "right".

Will the project potentially have scalability issues? There are projects which are never gonna grow, in terms of users and data. I've seen projects which are trying to look serious by using an Oracle RAC database setup, when a simple embedded database would work just fine!

Did you start the project or you are taking it over from other developers? This is a combination of the questions of who will support the software and will the software grow. You might get a spaghetti code from other developers. Will you have the time and resources to make it "right"?

c. Development team

Is the team experienced enough to make the decoupling right? When I was less experienced, I have tried to write the "right" code. And I have failed. The point is to really know your development team, their skills and knowledge. Don't underestimate this issue. When working with less experienced developers, I usually make some sacrifices to the architecture. The sacrifice that will be made is the best educated guess that I have. There are some points from the architecture that you can sacrifice and there are some that you cannot. Usually one or more sacrifices you have made earlier will came back and bite you.

Are the developers experienced writing automatic tests? It is not enough to have automatic tests. They should be complete (as much possible) and done right. If your tests are weak, than you better not have them at all. You wouldn't want to lean on a wall full of holes.

Conclusion:

I know that we all want to be professionals. And as professionals we must take all things into account. We cannot waste our time and energy on doing things the "right" way. Sometimes we must look at other factors (reality) and make our choice. And the most important thing is to live with it.

朱染 2024-09-09 01:18:55

优点:

  • 可扩展性 - 允许您扩展数据库访问层
  • 可互换性 - 例如电子邮件提供商代码
  • 可维护性 - 只需在一个地方更改代码
  • 易于设置单元测试 - 您可以模拟数据库等对象

缺点:

  • 可能需要多行代码
  • 一些额外的接口类

Advantages:

  • Scalability - allow you to expand out a database access layer
  • Swapability - eg email provider code
  • Maintainability - just change the code in one place
  • Ease of setting up Unit Testing - you can Mock objects like your databse

Disavantages:

  • Several extra lines of code perhaps
  • Some extra interface classes
涫野音 2024-09-09 01:18:55

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

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

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

First off, you should be writing unit tests ;)

Say you end up needing to change the underlying database. If your data access code is tightly coupled to your business logic, this could prove to be a huge effort. With loosely coupled code, your business logic will remain unaffected.

What if you decide you want to write some command line utilities that leverage your backend components? Providing multiple entry points to your system is much more easily accomplished with loosely coupled code.

尽揽少女心 2024-09-09 01:18:55

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

在这里您可以看到有趣的小文章: SOA - 松散耦合...什么?

很快它说:

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

It will give you scalability. For example if you have service layer behind you can separate it in several servers. Also you will have less dependencies and modifications will be easier. Also code support will be easier.

Here you can see interesting small article : SOA - Loosely Coupled...What?

Shortly it says :

Loosely coupled systems provide many advantages including support for late or dynamically binding to other components while running, and can mediate the difference in the component's structure, security model, protocols, and semantics, thus abstracting volatility...

无边思念无边月 2024-09-09 01:18:55

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

Because the stuff in the back might be useful even if it's not communicating with a browser-based, HTTP web UI. So you want to be able to disconnect it from that particular UI.

美人迟暮 2024-09-09 01:18:55

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

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

应用程序基于接口调用例程,并且接口无需实现。

尝试阅读有关 Unity 或 MEF 的内容,这些主题将为您提供良好的见解

The main reason to couple and decouple the classes is for extendability. The Change in one should not affect other.

if you build an application that is currently using MYSql database to store the data. Now we have new requirement to store the Data in MSSQL as his backend system. What Solution are you left if you build the system more integrated with MYSQL Libraries. To Rewrite the Whole application for MSSQL. Now how about this We build a new DAL based on MSSQL and plug the Dal into the system without making any changes to the system (UI).

The Application is calling the routine based on interfaces and interfaces are free from implementation.

Try reading about Unity or MEF these topics will provide you good insight

前事休说 2024-09-09 01:18:55

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

所以优点是:-

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

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

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

4) 集中的 QA :如果我们有分层架构,那么它总是有助于更好地集中 QA。

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

缺点是:-

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

2)如果你对技术过于狂热,最终可能会导致过度杀戮。

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

关于更改 DAL:-

当然,总会有一段时间,性能优先于功能,此时您将必须开始考虑导致 DAL 更改的数据提供商。

如果将 DAL 耦合到 UI,则每次更改 DAL(如果有的话,只要有),您总是需要重新发布生产中的整个二进制文件。它有它自己的一系列问题(我不好意思在这里解释它,如果你需要的话我总是可以包括它)

这就是原因,最初最好花时间并得出“自毁”何时会发生的结论该应用程序。我的意思是应用程序的生命周期是多少,如果回答得好,那么一切都会就位。

It all depends on the intent of making the Application along with the business interest. If business is keen to scale it and enough fuel (read corpus) is involved which gives enough thought to the architect to make the application reap long term benefits.

So the advantages are :-

1) If you are using a third party control/code : Always write a "wrapper/adapter layer" so that for any reason if that is not usable you can get something else and change the adapter layer without disturbing your application repository code.

2) Encapsulating specific complex functionalities in a "Service Layer" which may or may not require database requests : Its beneficial because as the request and response remains the same (it can surely change with time as well), you can always work on the performance of that specific code without changing the output. With unit cases in place we can also measure the performance of the code.

3) Making specific roles write specific code : If we create a lot of roles, it comes easier for people in the team to focus in their specific repository instead of getting lost in the pile of not related code.

4) Focussed QA : If we have layered architecture, it always helps to better the QA as its focussed.

5) Finding/Solving Bugs : Using layered architecture and assuming you have good logging in place, it always saves time to find the bugs and resolve it.

Disadvantages are :-

1) Setting up an application with this kind of framework will take extra time. So "go to market" will be delayed.

2) If you get too technology enthusiast it might end up in over kill.

3) Extra transaction latency: As the data travels through various layers there is extra latency which gets added in each transaction.

About changing the DAL :-

Of course there will be a time, when performance will take priority over features at that time you will have to start considering your data providers leading to the change in DAL.

If you couple your DAL to your UI, everytime you change your DAL (if at all, when at all) you always would require to re-release the entire binaries in production. Which has its own set of issues (am shying away to explain it here, if you require I can always include that)

That's the reason, initially its always better to spend time and conclude when will the "self destruct" happen for the application. I meant what's the life of the Application, if this is answered well, rest everything will fall in place.

迷迭香的记忆 2024-09-09 01:18:55

分工,相当于人类的关注点分离。你的 HTML 专家应该能够独立于你的 SQL 女神工作。

对前端的巨大改变应该能够在不破坏后端的情况下进行,反之亦然。换句话说,您应该只雇用一个人而不是两个。

Division of labor, which is the human equivalent of separation of concerns. Your HTML guru should be able to work independently of your SQL goddess.

A dramatic change to the front end should be able to proceed without tearing up the backend, and vice versa. In other words, you should only have to hire one person instead of two.

表情可笑 2024-09-09 01:18:55

以其他人没有讨论过的角度做出回应; 时间解耦。可以通过以下几种方式来完成:

当使用上述模式时(除了async monad),您经常显式处理消息而不是方法调用。这导致人们思考消息传递的工作原理(处理消息的幂等性、在传输过程中存储消息的队列、附加到信封上的安全数据、处理程序而不是请求程序中的重试逻辑,...)。

通过转向暂时解耦的面向消息的架构,您可以更轻松地扩展应用程序 - 特别是如果您主要进行发布-订阅(另请参阅事件驱动架构) - 任何事物都可以侦听事件并对它们做出反应,并且您不要将集成器的实现绑定到初始调用站点。

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

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

Responding with an angle noone else discussed; temporal decoupling. It can be done in a few ways:

When using the above (except the async monad), you often deal with messages explicitly rather than method invocations. This leads to thinking correlating with how message passing works (idempotence of handling them, queues for storing them in transit, security data attached to their envelopes, retry logic in handlers rather than requestors, ...).

By moving towards message-oriented architectures that are temporally decoupled you can make it easier to extend the application - especially if you have mostly doing publish-subscribe (see also, event driven architecture) - anything may listen to events and react on them and you don't bind the implementations of integrators to the initial call sites.

Web sites that push work onto queues are more responsive in general, because they don't let worker threads hang around waiting for IO to happen. They are also often cheaper to maintain in the long run.

For different types of compile-type coupling (and other metrics), browse http://www.ndepend.com/Metrics.aspx and read some about it yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文