I think that the general consensus is that utility classes are not evil per se. You just need to use them judiciously:
Design the static utility methods to be general and reusable. Make sure that they are stateless; i.e. no static variables.
If you have lots of utility methods, partition them into classes in a way that will make it easy for developers to find them.
Don't use utility classes where static or instance methods in a domain class would be a better solution. For example, consider if methods in an abstract base class or an instantiable helper class would be a better solution.
The other way to look at this Question is to observe that in the quoted Question, "If utility classes are "evil"" is a strawman argument. Its like me asking:
"If pigs can fly, should I carry an umbrella?".
In the above question I am not actually saying that pigs can fly ... or that I agree with the proposition that they could fly1.
Typical "xyz is evil" statements are rhetorical devices that are intended to make you think by posing an extreme viewpoint. They are rarely (if ever) intended as statements of literal fact.
1 - And you should NOT interpret that strawman question as advice on whether you should always take an umbrella with you when you are outdoors.
Utility classes are problematic because they fail to group responsibilities with the data that supports them.
They are however extremely useful and I build them all the time as either permanent structures or as stepping stones during a more thorough refactor.
From a Clean Code perspective utility classes violate the Single Responsibility and the Open-Closed Principle. They have lots of reasons to change and are by design not extensible. They really should only exist during refactoring as intermediate cruft.
It's very easy to brand something a utility simply because the designer couldn't think of an appropriate place to put the code. There are often few true "utilities".
As a rule of thumb, I usually keep code in the package where it is first used, and then only refactor to a more generic place if I find that later it really is needed elsewhere. The only exception is if I already have a package that performs similar/related functionality, and the code best fits there.
Utility classes aren't exactly evil, but they can violate the principles that compose a good object-oriented design. In a good object-oriented design, most classes should represent a single thing and all of its attributes and operations. If you are operating on a thing, that method should probably be a member of that thing.
However, there are times when you can use utility classes to group a number of methods together — an example being the java.util.Collections class which provides a number of utilities that can be used on any Java Collection. These aren't specific to one particular type of Collection, but instead implement algorithms that can be used on any Collection.
Really, what you need to do is think about your design and determine where it makes the most sense to put the methods. Usually, it's as operations inside of a class. However, sometimes, it is indeed as a utility class. When you do use a utility class, however, don't just throw random methods into it, instead, organize the methods by purpose and functionality.
When I can't add a method to a class (say, Account is locked against changes by Jr. Developers), I just add a few static methods to my Utilities class like so:
public static int method01_Account(Object o, String... args) {
Account acc = (Account)o;
...
return acc.getInt();
}
They broaden the scope of methods. They make code public that would otherwise be private. If the util method is needed by multiple callers in separate classes and is stable (i.e. doesn't need updating) it's better in my opinion to copy and paste private helper methods into the calling class. Once you expose it as an API, you make it harder to understand what the public entry point to a jar component is (you maintain a tree structured called hierarchy with one parent per method. This is easier to mentally segregate into components which is harder when you have methods called from multiple parent methods).
They result in dead code. Util methods over time become unused as your app evolves and you end up with unused code polluting your code base. If it had remained private your compiler would tell you the method is unused and you could just remove it (the best code is no code at all). Once you make such a method non private your computer will be powerless to help you remove unused code. It may be called from a different jar file for all the computer knows.
There are some analogies to static vs dynamic libraries.
I don't entirely agree that utility classes are evil.
While a utility class may violate OO principles in some ways, they aren't always bad.
For example, imagine you want a function that will clean a string of all substrings matching the value x.
STL C++ (as of now) doesn't directly support this.
You could create a polymorphic extension of std::string.
But the problem is, do you really want EVERY string you use in your project to be your extended string class?
There are times when OO doesn't really make sense, and this is one of them. We want our program to be compatible with other programs, so we will stick with std::string and create a class StringUtil_ (or something).
I'd say it's best if you stick with one util per class. I'd say it's silly to have one util for all classes or many utils for one class.
You can look at this problem from two perspectives:
Overall *Util methods are often a suggestion of bad code design or lazy naming convention.
It is legitimate design solution for reusable cross-domain stateless functionalities. Please note that for almost all common problems there are existing solutions.
Example 1. Correct usage of util classes/modules. External library example
Let's assume you are writing application which manages loans and credit cards. Data from these modules is exposed through web services in json format.
In theory you can manually convert objects to strings which will be in json, but that would reinvent the wheel. Correct solution would be to include in both modules external library used to convert java objects to desired format. (in example image I have shown gson)
Example 2. Correct usage of util classes/modules. Writing your own util without excuses to other team members
As a use case assume that we need to perform some calculations in two modules of application, but both of them need to know when there are public holidays in Poland. In theory you can make these calculations inside modules, but it would be better to extract this functionality to separate module.
Here is small, but important detail. Class/module you have written is not called HolidayUtil, but PolishHolidayCalculator. Functionally it is a util class, but we have managed to avoid generic word.
Looking back at this question now, I'd say that C# extension methods completely destroy the need for utility classes. But not all languages have such an in-genius construct.
You also have JavaScript, where you can just add a new function right to the existing object.
But I'm not sure there really is an elegant way to solve this problem in an older language like C++...
Good OO code is kinda hard to write, and is hard to find since writing Good OO requires a lot more time/knowledge than writing decent functional code.
And when you're on a budget, your boss isn't always happy to see you've spent the whole day writing a bunch of classes...
Utility classes are not always evil. But they should only contain the methods that are common across a wide range of functionality. If there are methods that are only usable among a limited number of classes, consider creating a abstract class as a common parent and put the methods in it.