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 test
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.
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
Advantages:
Disavantages:
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".
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...
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.