Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Loose coupling is, to some developers, the holy grail of well-engineered software. It's certainly a good thing when it makes code more flexible in the face of changes that are likely to occur in the foreseeable future, or avoids code duplication.

On the other hand, efforts to loosely couple components increase the amount of indirection in a program, thus increasing its complexity, often making it more difficult to understand and often making it less efficient.

Do you consider a focus on loose coupling without any use cases for the loose coupling (such as avoiding code duplication or planning for changes that are likely to occur in the foreseeable future) to be an anti-pattern? Can loose coupling fall under the umbrella of YAGNI?

share|improve this question
1  
Most benefits come with a cost. Use if the benefit outweighs the cost. –  LennyProgrammers Dec 3 '10 at 10:58
1  
you forgot the flip side of the loose coupling coin, and that is high cohesion one without the other is a waste of effort and illustrations fundamental lack of comprehension of either. –  Jarrod Roberson Dec 24 '11 at 17:51
add comment

5 Answers

up vote 11 down vote accepted

Somewhat.

Sometimes loose coupling that comes without too much effort is fine, even if you don't have specific requirements demanding that some module be decoupled. The low-hanging fruit, as it were.

On the other hand, overengineering for ridiculous amounts of change will be a lot of unnecessary complexity and effort. YAGNI, as you say, hits it on the head.

share|improve this answer
add comment

The simple answer is loose coupling is good when done correctly.

If the principle of one-function, one purpose is followed then it should be easy enough to follow what is going on. Also, loose couple code follows as a matter of course without any effort.

Simple design rules: 1. don't build knowledge of multiple items into a single point (as pointed out everywhere, depends) unless you are building a facade interface. 2. one function - one purpose (that purpose may be multi-faceted such as in a facade) 3. one module - one clear set of interrelated functions - one clear purpose 4. if you cannot simply unit test it then it does not have a simple purpose

All these comments about easier to refactor later are a load of cods. Once the knowledge gets built into many places, particularly in distributed systems, the cost of refactoring, the rollout synchronisation, and just about every other cost blows it so far out of consideration that in most cases the system ends up being trashed because of it.

The sad thing about software development these days is 90% of people develop new systems and have no ability to comprehend old systems, and are never around when the system has got to such a poor state of health due to continual refactoring of bits and pieces.

share|improve this answer
add comment

I think what you're getting at here is the concept of cohesion. Does this code have a good purpose? Can I internalize that purpose and understand the "big picture" of what's going on?

It could lead to hard-to-follow code, not just because there are many more source files (assuming these are separate classes), but because no single class seems to have a purpose.

From an agile perspective, I might suggest that such loose coupling would be an anti-pattern. Without the cohesion, or even use cases for it, you cannot write sensible unit tests, and cannot verify the code's purpose. Now, agile code can lead to loose coupling, for example when test-driven development is used. But if the right tests were created, in the right order, then it's likely there is both good cohesion and loose coupling. And you're talking about only the cases for when clearly no cohesion is there.

Again from the agile perspective, you don't want this artificial level of indirection because it is wasted effort on something that probably won't be needed anyway. It's much easier to refactor when the need is real.

Overall, you want high-coupling within your modules, and loose coupling between them. Without the high-coupling, you probably do not have cohesion.

share|improve this answer
add comment

Is programming practice X good or bad? Clearly, the answer is always "it depends."

If you're looking at your code, wondering what "patterns" you can inject, then you're doing it wrong.

If you are building your software so that unrelated objects don't fiddle around with each other, then you're doing it right.

If you're "engineering" your solution so that it can be infinitely extended and changed, then you're actually making it more complicated.

I think at the end of the day, you're left with the single truth: is it more or less complicated to have the objects decoupled? If it is less complicated to couple them, then that is the correct solution. If it is less complicated to decouple them, then that is the right solution.

(I am presently working in a fairly small codebase that does a simple job in a very complicated way, and part of what makes it so complicated is the lack of understanding of the terms "coupling" and "cohesion" on the part of the original developers.)

share|improve this answer
4  
I did this just the other day: I thought I would need some indirection between two classes "just in case". Then I hurt my head trying to debug something, ripped out the indirection, and was much happier. –  Frank Shearar Oct 16 '10 at 5:54
add comment

For the majority of questions like this, the answer is "it depends." On the whole if I can make a design logically loosely coupled in ways that make sense, without a major overhead to doing so, I will. Avoiding unnecessary coupling in code is, to my mind, an entirely worthwhile design goal.

Once it comes to a situation where it seems like components should logically be tightly coupled, I'll be looking for a compelling argument before I start breaking them up.

I guess the principle I work to with most of these types of practice is one of inertia. I have an idea of how I would like my code to work and if I can do it that way without making life any harder then I will. If doing it will make development harder but maintenance and future work easier I will try and figure out a guess at whether it will be more work across the lifetime of the code and use that as my guide. Otherwise it would need to be a deliberate design point to be worth going with.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.