This morning, I was reading the blog of J. Michael Palermo IV, and in his recent blog post, “utility methods – are they the devil”, he asks whether utility methods are evil, and he concludes with “no”. I don’t know about the evil part, but it caused me to reflect on my past. While Mike is talking about utility _methods_, I’d like to address utilty _classes_.
I remember a time when I created a “Util” class and put in methods that contained everything from reading the contents of a file to putting a log message in the event viewer. Essentially, anything I couldn’t jam into a screen went into a utility method since I wanted to share this code.
I paused and reflected because I haven’t written one of these classes in several years. I can trace it back to my adoption of the Domain Model pattern and domain-driven design in general. DDD stresses separation of concerns and giving each class a single responsibility. Domain classes represent a single concept in the domain, and domain services provide one service to the application.
When I look at a “Util” class and search for the concept it represents or its responsibility, I struggle. I see it might be writing to files, writing to the event log, transforming XML with a provided XSLT stylesheet, etc. When I see all these things going on, the only name that is general enough is “Util”, and that’s not an abstraction. It’s not meaningful. It doesn’t say anything about what’s going on inside or what the responsibility is.
I don’t even think about it these days, but I like to create abstractions for everything (ok, not EVERYTHING). I think it makes the application so much more maintainable, and the folks who have worked with me agree. These aren’t my ideas, by the way. I’m very good at stealing ideas from others: Martin Fowler, Robert C. Martin, Michael Feathers, Kent Beck, Eric Evans, Jimmy Nielson, and many others.
Consider the following needs that might be in a “Util” class:
- File reading/writing – I have an IFileSystem interface for when my application needs to know it is using a file. On the other hand, if I’m reading xml data from a file, and the xml is data for system logs, IFileSystem isn’t an appropriate abstraction. Here, I’d use ISystemLogRepository since my abstraction is a data store for SystemLog. My application doesn’t care that it’s in xml, just that it can be retrieved.
- Writing to event log – I’d have a ILogWriter interface with a WriteToEventLog method if my application really needed to know about the event log. More often, my application only needs to care about logging _something_, and I’d configure Log4Net to pipe the message into the event log as one of the appenders.
- Transform xml – I’d use an IXmlTransformer interface to front this concept for my application. This interface would be used on the extremities of the application since in the core, there is no need for xml, only domain objects.
When I think back to my use of Util classes, I have to say it was before I was unit testing my code, before I had heard of Inversion of Control containers, and when I wrote my code very tightly coupled. I’m not making the statement, “if you use Util classes, you are type XXXX”, that would be absurd, but since I adopted testing, loose coupling, and DDD, I haven’t written a single Util class.
Exception: I HAVE written a util class in my integration test project called TestData. It has static methods that populate common domain objects and save them to the database as a method to set up the context for an integration test that makes use of the the database. In production code, I can’t find a Util class by any name.