See the question and my original answer on StackOverflow

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".