tags:

views:

281

answers:

14

Our company keeps a MiscUtilities class that consists solely of public static methods that do often unrelated tasks like converting dates from String to Calendar and writing ArrayLists to files. We refer to it in other classes and find it pretty convenient. However, I've seen that sort of Utilities class derided on TheDailyWTF. I'm just wondering if there's any actual downside to this sort of class, and what the alternatives are.

A: 

Personally, I often find such a class handy - even if only in the short term. That said, I try not to share them between projects. I would not keep a global version, but write one specific to each project - otherwise you're incorporating dead-weight which may cause issues for security or architecture.

Rushyo
+1  A: 

Well, bad utility classes are derided on TheDailyWTF :)

There's really nothing wrong with having a generic utilities class for miscellaneous static business functions. I mean, you could try to put it all into a more object oriented approach, but at what cost in time and effort to the business and for what trade-off of maintainability? If the latter outweighs the former, go for it.

One approach you may be able to take, depending on the language, etc., is to perhaps move some of the logic into extensions on existing objects. For example, extending the String class (thinking in C# here) with a method that tries to parse the string into a DateTime. An in-house library of extensions just enhances the language with your business' own little DSL(s).

David
As in creating a subclass of String called EnhancedString or something? Unfortunately I only speak Java, and then only a little of it :)
Anita
I don't know if something similar can be done in Java, but in C# extension methods basically add functionality to existing types, in many cases alleviating the need for derived types: http://en.wikipedia.org/wiki/Extension_method
David
+4  A: 

Convenient, most likely.

Possible to grow into a scary, hard to maintain swiss-army-rocket-chainsaw-and-floor-polisher, also most likely.

I'd recommend separating the various tasks into separate classes, with some logical grouping besides "won't fit anywhere else".

The risk here is that the class becomes a tangled mess nobody fully comprehends and noone dares to touch - or replace. If you feel that is an acceptable risk and/or avoidable under your circumstances, nothing really prevents you from using it.

Piskvor
(True story:one of my prev.workplaces had a class named `Misc_Actions`.Legend said that it had been conceived in 2002 and had been useful until sometime in 2005;then it passed the tipping point and became a Lovecraftian monster.Yet noone dared touch it,or fix its known bugs for the fear of breaking other systems dependent on it.Some of the methods were useful,but the horror of bringing the whole monster in led developers to cut-and-paste parts of it into their own utility classes, repeating the cycle. Not sure if they're still using That, but I'd guess it'd be DailyWTF material by now.)
Piskvor
Oh, do tell! How exactly is it a monster? Our class has 150 methods and is still quite manageable :)
Anita
@Anita: The *number* of methods was not a concern; multiple functions that were almost but not entirely the same, were the biggest problem, not to mention "how to do X? Oh, it's in Misc_actions ... somewhere"
Piskvor
True that; I certainly have those moments sometimes. But consistent naming practices (getYFromX) and NetBeans' handy-dandy Ctrl-Space, which offers suggestions for what it thinks I want to type next, make those moments relatively rare :)
Anita
A: 

What I do for my personal projects is keep a misc library but rather than adding a reference in my projects, I paste the relevant bits of code in to the relevant places. It's technically duplicaintg it, but not within a single solution and thats the important thing. However I don't think this would work on a larger scale, too messy.

rmx
+3  A: 

I've never been a fan of the MiscUtilities class. My biggest issue is that I never know what is in it. Anything filed under miscellaneous is not discoverable. Instead I prefer to use a common dll that I can import into my projects that contains well named, separated classes for different purposes. The difference is subtle, but I find that it makes my life a little easier.

Matthew Vines
A: 

I generally don't have a problem with them, although, like all things, they can be abused:

  • They grow wildly large, so that most problems that use the class don't use 99% of the functions.
  • They grow wildly large, so that 90% of the functions aren't used by any program still in use.
  • Often they are a dumping ground for functions which are specific to one domain. They should be pared off to a similar class use just by program in that domain. Often, these function would be better off incorporated into proper classes.
James Curran
+1  A: 

The company I work for has a class like that in its repository. Personally I find it annoying because you have to be really intimate with the class in order to know what it's useful for. Consequently, I've found myself re-writing methods that this class already covers! Double annoying because I've now wasted my time.

I would prefer a more object oriented approach that would lead to expandability. Have a Utilities class for sure, but inside it put other classes that expand toward specific functionality. Like Utilities.XML, Utilities.DataFunctions, Utilities.WhateverYouWant. That way you can expand and eventually take your 20 function MiscUtilities class and turn it into a 500 function class library.

A Class Library like this could then be used by anyone, and added to by anyone (with privileges) in a logically organized way.

Brandon Boone
+1  A: 

I think the wrong defect of such a class is that it break Separation of concerns principle. I usually create multiple "Helpers" class to contains widely used, public static methods, for example ArrayHelpers to writing ArrayLists to files, and DatesHelper to converting dates from String to Calendar. Moreover, if the class does contain complicated methods, it's better to try to refactor them using more object-oriented tecnique. You can always switch from your "Helpers" class to the use of various OO pattern, leaving your old static methods to function as a Facade. Yuo'll find great benefits everytime you'll be able to do so.

Andrea Parodi
A: 

I used to have, in every project, a module called MiscStuffAndJunk. It was a place to hold everything that didn't have a clear place to go, either because the functionality was a one-off, or because I didn't want to change my focus, so as to do a proper design for a function that was needed by but extraneous away from what I was currently concentrating on.

Still, it these modules are clearly in violation of OO design principles.

So nowadays, I name the module StuffIHaventRefactoredYet, and all is right with the world.

Jeff Dege
+10  A: 

Rather than giving personal opinion, I will quote from an authoritative source in the Java community, and examples from 2 very reputable third party libraries.

A quote from Effective Java 2nd Edition, Item 4: Enforce noninstantiability with a private constructor:

Occasionally you'll want to write a class that is just a grouping of static methods and static fields. Such classes have acquired a bad reputation because some people abuse them to avoid thinking in terms of objects, but they do have valid uses. They can be used to group related methods on primitive values or arrays, in the manner of java.lang.Math or java.util.Arrays. They can also be used to group static methods, including factory methods, for objects that implements a particular interface, in the manner of java.util.Collections. Lastly, they can be used to group methods on a final class, instead of extending the class.

Java libraries has many examples of such utility classes.


Short summary

  • Prefer good OOP design, always
  • static utility classes have valid uses to group related methods on:
    • Primitives (since they're not objects)
    • Interfaces (since they can't have anything concrete of their own)
    • final classes (since they're not extensible)
  • Prefer good organization, always
    • Group utility methods for SomeType to SomeTypeUtils or SomeTypes
    • Avoid a single big utility class that contains various unrelated tasks on different types/concepts
polygenelubricants
Incidentally, how has the hideous "utils" (as opposed to "utilities") persevered for so long? Because "utilities" is *unbearably* longer?
Jeff Sternal
@Jeff Sternal: If everyone knows what 'utils' means, in what way is 'utilities' superior? Frankly, I think long things are hideous. "Program Files", anyone? The <i>only</i> advantage I can think of for a long name is that when Windows 95 was installed for the first time Microsoft could guarantee nobody would already have a directory with that name. Still, "Applications" would have been a character shorter and not had the silly blank that causes no end of grief.
supercat
@supercat: And it was localized to boot (for reasons that elude me). In German, at least it's named "Programme", but that breaks all kinds of apps that can't be bothered to check and hardcode "Program Files".
Piskvor
@supercat: I noticed you didn't write "Frnk, I thin lng thngs are hid." ;)
Jeff Sternal
+1  A: 
supercat
A: 

Depending on what your static utility functions actually do and return, it may be cause problems unit testing. I have come across a method in a class that calls a static function on a static class that return things I do not want in my unit test, rendering the whole method untestable...

Peter Kelly
+2  A: 

For languages that support functions, this sort of class is undeniably bad form.

For languages that don't, this sort of class isn't, and is probably superior to extending other classes with random utility methods. The static utility methods, because they are in some other class, can only use the public interface of the objects they handle, which decreases the likelihood of certain kinds of bug. And this approach also avoids polluting public interfaces with a random grab bag of whatever people happened to find useful at the time.

There's a certain amount of personal style involved of course. I'm not a big believer in classes that provide everything under the sun (even C++'s std::string is a tad over-featured for my taste) and tend to prefer to have helper functionality as separate functions. Makes maintenance of the class easier, forces the public interface to be useful and efficient, and with duck-typing style mechanisms the external functions can be used across a wide range of types without having to duplicate source text or share base classes and so on. (The oft-derided algorithms in the C++ Standard Library are a good demonstration of this, imperfect and verbose as they are.)

That said, I've worked with many who complain about strings that don't know how to interpret themselves as filenames, or split themselves into words, or what have you, and so on. (I pick on strings because they seem to be the prime target for utility functions...) I happen to think there are unseen maintenance and reliability costs associated with having large classes like that, quite apart from the ugliness of having a nominally simple class that's actually a vast illogical mishmash of unrelated concerns whose grubby fingers end up poking themselves into every last corner -- because your self-tokenizing string needs some kind of container to put the tokens in, right?! -- but it's a balancing act, even if my wording suggests it's more clean-cut than that.

I'm not a big believer in the notion of "OO dogma", but perhaps the paranoid might see it at work here. There's no good reason that all functionality should be attached to a particular class, and many good reasons why it should not. But some languages still don't allow the creation of functions, which does nothing to remove the need for them and forces people to work around the restriction by creating classes that consist of nothing but static methods. This rather overloads the meaning of the class concept, to my mind, and not in any good way.

So that IS a good reason to rail against this practice, but it's pretty futile unless the language changes to accommodate what people need to do. And languages don't come without functions unless their designers have an axe to grind, or there are technical reasons for it, so I should think that change in either case is unlikely.

I suppose the executive summary is: no.

brone
+1  A: 

Utility classes aren't bad, in and of themselves. They can be (mis|ab|over)used at times, but they do have their place. If you have utility methods for types you own, consider moving the static methods to the appropriate types. Or creating extension methods.

Do try to avoid a monolithic utilities class - they may be static methods, but they will have poor cohesion. Break up a large set of unrelated functions into smaller groupings of related functionality, much like you would your "normal" classes. Name them *Helper or *Utils, or whatever your preference is. But be consistent, and group them together, perhaps in a folder within a project.

When utility classes are broken up as described, you can create methods for working with specific types - primitives or classes, such as arrays, strings, dates and times, and so on. Admittedly, these wouldn't belong anywhere else, so a utility class is the place to go.

Grant Palin