In response to my post, Strive for Functional Cohesion, VisualKnight wrote the following:
We noramally [sic] most functional methods to the domain object class in this case your Address class. However, if the method is more general in nature I would add it to an Utility class so other team developers can find it easier. We have an Utility class that is available in both the web and app side.
Let me start off by saying that I am guilty of using the utility class at least as far back as when I programmed in Delphi. The reason I did so was quite simple: I came from a Turbo Pascal background, and many of my development practices had evolved from procedural programming. As I learned object oriented patterns and practices, the utility class was lost from my tool belt as a relic from ages past. However, I am glad VisualKnight brings it up, because the utility class is an excellent example of coincidental cohesion!
Coincidental cohesion is the lowest form of cohesion found in object oriented software development. Methods within a class that has coincidental cohesion will appear to have been placed there randomly or without consideration of the proper concern of the method. This type of class necessarily leads to tight coupling as its varied functionality is used in a myriad of places.
A utility class is a perfect example of coincidental cohesion. Do not confuse this class with the so-called “utility pattern” (which is just a static class in c#). It is true that static classes are often called helper classes, and those are also often called utility classes, but this is just a creational pattern. Many static classes have higher orders of cohesion than coincidental.
For a quick example of coincidental cohesion, let’s take a look at the C# example of the Utility pattern on Wikipedia.
// The utility class
public static class Utils
{
/// <summary>
/// A utility method that helps out with error logging.
/// </summary>
public static void LogError(String msg)
{
MyLogger logger = new MyLogger(); // Create instance of logger class
logger.LogIt(msg);
}
/// <summary>
/// A utility method that displays a message to the user.
/// </summary>
public static void ShowMsg(String msg)
{
MessageBox.Show(msg);
}
}
This static class only contains two methods, but they have no relationship to each other. Now, any class that wants to log errors will need to use the Utils class, and any class that needs to show messages will need to use the Utils class. The Utils class does not have a clear concern defined within the system; it is a garbage heap on which to throw methods.
If you have a need to use static methods, you should at the very least group them logically. But I do stand by my principle of Strive for Function Cohesion. There should never be a Utility class which is used as a general bucket. Every method in your system means something, it belongs somewhere. If you’re having trouble deciding where it belongs, it may need to be broken down to operate on smaller components within the system. The one caveat to that is that orchestration may operate on multiple objects, but they generally belong in workflow anyway.
If you disagree and want to make a case for the Utility class, leave a comment. Be sure to back it up with a sample method and ask me how I would organize it.