Cohesion is a measure of the degree to which the elements of a module belong together.
Yourdon & Constantine in Structured Design, 1979
In essence, cohesion is a measure of ensuring that one element (one class) has a single responsibility. Measuring cohesion is tricky (as pretty much everything else in SE). The metrics tend to indicate the extent to which the elements are used together and therefore there is no guarantee that they should belong together.
One of the most popular metrics for measuring cohesion is "Lack of Cohesion of Method" commonly known as LCOM.
For each attribute in a given class, calculate the percentage of the methods in the class using that attributes. Next, compute the average of all those percentages, subtract the average from 100%
Tripathy & Naik in Software Evolution and Maintenance
Here are some code smells to watch out for
- Divergent change - violation of the single responsibility principle is likely to result in future changes being more difficult and harder to make with confidence.
- Data Clumps - several pieces of data are often used together over and over again. It is, therefore (often) a duplicate. Extract the common behaviour and shift the responsibility to a new class.
- Primitive Obsession - Using a built-in type to represent domain concepts (such as a string, int) to represent some concept important in the domain. This is very popular particularly with arrays e.g. Start and End date is placed in an array of length 2. Then methods are implemented to deal with that length.
- Feature Envy - The object is more concerned with another object's attributes of methods than its own. This is often associated with violation of "Tell don't ask" principle. If that is the case, there is pretty good chance that the behaviour probably belongs on the envied object.