Cohesion Tutorial

Have you ever put a drop of oil into a glass of water? You will quickly notice that the two substances do not mix well; the oil wants to cling together floating on top of the water. That "clingy" bond each different substance has is termed as cohesion in the world of chemistry. In nature, cohesion can be observed in flocks of birds, schools of fish, and even those annoying gnat swarms. Cohesion can simply be described as the attraction that a group of similar objects share. In Java, cohesion is the relationship between members within a single class to perform a specific functionality, simply put - do the members of the class belong together and do they work well to accomplish a single well-defined task? The cohesiveness of a class can be measured from highly cohesive to low cohesion.

Low Cohesion

A class that contains numerous methods that have nothing in common is an example of low cohesion. Consider the following class:
class Utilities {
     public void displayMessage(String message) { ... }
     public boolean fileExists(String filename) { ... }
     public String captureInput() { ... }
     public String[] getClassMethods(Object o) { ... }
}
The class above contains a bunch of methods that have just been lazily thrown together. This class is the equivalent to the "junk drawer" that most people have in their kitchen - you know what I'm talking about, that drawer where you just throw everything that doesn't belong elsewhere. If you pull a spoon out of the dishwasher, do you put it in the silverware drawer or the junk drawer? You put it in the silverware drawer; the silverware drawer has high cohesion, whereas the junk drawer has low cohesion.

High Cohesion

The degree of cohesion increases as the functionality of the class becomes more specific. Consider the following class:
class ObjectInformation {
     public String getObjectClassName(Object o) { return ... }
     public String getObjectSuperclassName(Object o) { return ... }
     public ArrayList<String> getObjectFields(Object o) { return ... }
     public ArrayList<String> getObjectConstructors(Object o) { return ... }
     public ArrayList<String> getObjectmethods(Object o) { return ... }
}
The class above contains methods that serve a common purpose - they all perform tasks directly related to Object Information.

A highly cohesive class is easy to maintain and can evolve and grow in a controlled manner. A class with low cohesion is hard to maintain and will grow in a haphazard random manner. Think about the junk drawer analogy for a second ... which drawer is easier to maintain - the junk drawer, or the silverware drawer? You should always thrive to have a high level of cohesion, even if that means putting a single method inside of a single class. If nothing else, you will at least be able to locate the method much easier later on down the road if your project becomes a monster.
class Messages {
     public void displayMessage(String message) { ... }
}



Open the command prompt (CMD - see the Getting Started ) and type in the following commands.

C:\Windows\System32>cd \
C:\>md Java
C:\>cd Java
C:\Java>
C:\Java>md ObjectInformation
C:\Java>cd ObjectInformation
C:\Java\ObjectInformation>Notepad ObjectInformation.java

Copy and Paste, or type the following code into Notepad and be sure to save the file when you are done.


import java.lang.reflect.*;
import java.util.*;
class Tester {
    public static void main(String args[]) {
        Integer i = new Integer(41);	
        String s = "Hello World";

        ObjectInformation oi = new ObjectInformation();
        System.out.println("i information...");
        System.out.println(oi.getObjectClassName(i));
        System.out.println(oi.getObjectSuperclassName(i));
        oi.getObjectFields(i).forEach(x -> System.out.println("Field: " + x));
        oi.getObjectConstructors(i).forEach(x -> System.out.println("Constructor: " + x));
        oi.getObjectMethods(i).forEach(x -> System.out.println("Method: " + x));
        System.out.println();
		
        System.out.println("s information...");
        System.out.println(oi.getObjectClassName(s));
        System.out.println(oi.getObjectSuperclassName(s));	
        oi.getObjectFields(s).forEach(x -> System.out.println("Field: " + x));
        oi.getObjectConstructors(s).forEach(x -> System.out.println("Constructor: " + x));
        oi.getObjectMethods(s).forEach(x -> System.out.println("Method: " + x));
        System.out.println();	
    }
}
class ObjectInformation {
    public String getObjectClassName(Object o) { 		
        return o.getClass().getSimpleName();
    }
    public String getObjectSuperclassName(Object o) { 		
        return o.getClass().getGenericSuperclass().getTypeName();
    }
    public ArrayList<String> getObjectFields(Object o) { 
        Field fArray[] = o.getClass().getDeclaredFields();
        ArrayList<String> sArray = new ArrayList<>();
        for(Field f : fArray) { sArray.add(f.getName()); }
        return sArray;
    }
    public ArrayList<String> getObjectConstructors(Object o) { 
        Constructor cArray[] = o.getClass().getDeclaredConstructors();
        ArrayList<String> sArray = new ArrayList<>();
        for(Constructor c : cArray) { sArray.add(c.toString()); }
        return sArray;
    }
    public ArrayList<String> getObjectMethods(Object o) { 
        Method mArray[] = o.getClass().getDeclaredMethods();
        ArrayList<String> sArray = new ArrayList<>();
        for(Method m: mArray) { sArray.add(m.getName()); }
        return sArray;
    }
}

Now switch back to the command prompt (CMD) and type in javac ObjectInformation.java and press Enter.
Now type in java ObjectInformation and press Enter.


C:\Java\ObjectInformation>javac ObjectInformation.java
C:\Java\ObjectInformation>java ObjectInformation
See video for results


Final thoughts

Now that you know what cohesion is, you should always strive to name and design your classes with a focused purpose.


Tutorials