Say you have the FileReader
class with a read
method.
I understand that class-level attributes can justify having an instance. However, what is stopping making an equivalent ReaderUtils
class by pulling these same attributes inside the scope of a corresponding static
read
method ?
In short, what exactly justifies a "Doer" class with respect to static utility methods ?
A utility class MUST contain only static methods.
Pure utility classes should usually be static. When you have a class with well-defined input and output, no side effects and no state, then by definition it should be a static class.
Static methods are utility methods defined in a class that do not fit the tradition method- receiver pattern. Static methods are used where there is not a natural choice of a receiver object for the problem the method solves.
Utility classes are helper classes that consisits of reusable methods. From triggers we can call methods in such public classes. This helps to reduce code with in trigger and make it more structured.
The essence of OOP is encapsulating state/data along with associated behaviour. Static utility methods are akin to global functions in a procedural language -- you are separating behaviour (the static method) from state (the parameters to this method), thereby breaking encapsulation.
What does this mean in practice? Instead of being able to call reader.read()
, you have to call ReaderUtils.read(file)
, which means you are now tightly coupled to the implementation -- you have made an implicit assumption that you will always use ReaderUtils
and always pass in a file.
If you instead use the generic Reader
interface, you can use a FileReader
today but swap it out for a DatabaseReader
or a HttpReader
tomorrow without having to change any other code -- all the reader.read()
calls will continue to work the same.
Interfaces can't be implemented statically - the implemented methods of an interface must be instance methods. As such, this prohibits injection or JNDI lookup of a "utility class" as the runtime implementation to perform some service - it must be an instance of a class. This is one of the main reasons why "doer" classes exist.
Utility classes are fine if the implementation is known at compile time, and being static methods they are more likely to naturally be stateless (just make sure any static fields are immutable/stateless), which is required by typical servers that serve requests concurrently.
It's a matter of preference. In general, Java favors nouns (because people feel this is more OO) therefore FileReader.
As noted by Jeffrey, sometimes the noun obsession leads to unnecessary verbosity at which point calls get wrapped in static methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With