Feeds

Up with cohesion, down with coupling

We all love cohesion and hate coupling, don't we?

Combat fraud and increase customer satisfaction

The point about the header file is that it made a conceptual coupling that existed within the program explicit and, therefore, visible. Brushing it under the carpet did not reduce the coupling, it just made it harder to see and deal with. So, taken by itself, the header file was highlighting the problem rather than necessarily being the problem. That said, given some of the other design decisions the team took and the code I saw, perhaps the real problem was that they had access to keyboards. But I digress.

Now, armed with a reasonable and reasoned understanding of what's meant by maximise cohesion and minimise coupling, what is the relationship between coupling and cohesion?

The received wisdom is quite simple: when one goes up, the other goes down; tight coupling and weak cohesion go together, as do loose coupling and strong cohesion. Most of the time that correlation holds, but there are a number of well-known design examples that are not quite as straightforward.

Consider, first of all, the Composite design pattern. This design allows code to treat individual objects and groups of objects the same way through a common interface. Instead of having duplicate code where individuals and groups are handled in similar ways, code only has to be written once. Instead of explicit selection based on a runtime type check, such as instanceof in Java or dynamic cast in C++, polymorphic dispatch determines the right code to execute. So, instead of coupling to the specific types of individual objects and of groups of objects, usage code is coupled only to the interface.

From the perspective of usage code, lower coupling is typically a consequence of using a Composite. What about cohesion? Here the case is not so clear cut. Looking at the common interface implemented by classes for individual objects classes and for groups it appears that the common operations are not always, well, common.

In most Composite implementations the common interface provides a way to traverse groups of objects, whether using Iterator objects or via callbacks from Enumeration Methods, optionally expressed in terms of Visitor to separate callbacks on different object types.

This is all very well for groups of objects, but what does it mean to traverse an individual object? Not much. You have to invent a behaviour, such as doing nothing, returning null, returning a Null Object, throwing an exception, or whatever is appropriate for the language and iteration style of choice. In other words, to achieve lower coupling, some cohesion has also been traded in.

And speaking of iteration, the common-or-garden Iterator pattern offers another example of a trade-off between coupling and cohesion.

A collection that holds its elements but doesn't allow you to traverse them is unlikely to prove popular. There are many ways to offer traversal, but if the caller needs to be able to know the position of elements in some way there are essentially only three general designs that keep the collection's internal representation hidden from the caller.

First, it is possible to use an index into the collection. The advantage of this is that it appears simple and there is no coupling to the collection's data structure. The main disadvantage is that it is only practical if indexing is a constant-time operation, which it won't be for linked data structures.

The second approach is to internalise a cursor within the collection. This cursor can be moved efficiently to and fro by the caller without revealing the internal data structure. However, it can't support more than one pass at a time — which fails in interesting ways for nested traversals — and for collections that are supposed to be read-only you have the additional question of whether or not you consider the cursor to be part of the collection's state (it turns out that you have problems either way).

And the third option is to introduce an Iterator object.

An Iterator object represents a clean separation of concerns, resulting in two kinds of objects, each with clear responsibilities: objects whose responsibility is to iterate, with an interface to match, and objects whose responsibility is to collect, with an interface to match. The trade-off here is that although the collection's data structure is not revealed to the world, it is revealed to the Iterator, which is closely coupled to it. ®

Combat fraud and increase customer satisfaction

More from The Register

next story
Ubuntu 14.04 LTS: Great changes, but sssh don't mention the...
Why HELLO Amazon! You weren't here last time
This time it's 'Personal': new Office 365 sub covers just two devices
Redmond also brings Office into Google's back yard
Next Windows obsolescence panic is 450 days from … NOW!
The clock is ticking louder for Windows Server 2003 R2 users
Half of Twitter's 'active users' are SILENT STALKERS
Nearly 50% have NEVER tweeted a word
OpenBSD founder wants to bin buggy OpenSSL library, launches fork
One Heartbleed vuln was too many for Theo de Raadt
Got Windows 8.1 Update yet? Get ready for YET ANOTHER ONE – rumor
Leaker claims big release due this fall as Microsoft herds us into the CLOUD
Batten down the hatches, Ubuntu 14.04 LTS due in TWO DAYS
Admins dab straining server brows in advance of Trusty Tahr's long-term support landing
Red Hat to ship RHEL 7 release candidate with a taste of container tech
Grab 'near-final' version of next Enterprise Linux next week
Apple inaugurates free OS X beta program for world+dog
Prerelease software now open to anyone, not just developers – as long as you keep quiet
prev story

Whitepapers

Mobile application security study
Download this report to see the alarming realities regarding the sheer number of applications vulnerable to attack, as well as the most common and easily addressable vulnerability errors.
3 Big data security analytics techniques
Applying these Big Data security analytics techniques can help you make your business safer by detecting attacks early, before significant damage is done.
The benefits of software based PBX
Why you should break free from your proprietary PBX and how to leverage your existing server hardware.
Securing web applications made simple and scalable
In this whitepaper learn how automated security testing can provide a simple and scalable way to protect your web applications.
Combat fraud and increase customer satisfaction
Based on their experience using HP ArcSight Enterprise Security Manager for IT security operations, Finansbank moved to HP ArcSight ESM for fraud management.