UtilityClasses are classes that have only static methods that perform some operation on the objects passed as parameters. Such classes typically have no state.
For some OoWeenies out there, UtilityClasses as such are seen as an AntiPattern. While certainly there's always the very real danger of AbuseOfUtilityClasses, not all designs that involve utility classes can be refactored to better designs that conform to a pure OO point of view.
...like java.lang.Math ;->
Ah yes, but then java.lang.Math is rather a special case. Having said that, how about putting those 'functions' on a generic Number class so that you can ask a Number object what its cosine, sine etc is ?
Ever asked the handwritten number 352 for its tangent? In my opinion that doesn't make much sense. That approach also doesn't scale well, parametrically speaking. Where do you locate binary operations, say greatest common factor, when the operands are of different type? Overloaded operators in C++ are often implemented as loose functions rather than instance operations for good reason. Placing all behavior in instance methods is unnatural.
I guess that when an object model for a system consists of a bunch of classes with a few static methods operating on other objects which only contain data then there is a problem.
Point taken though :-)
In the SmalltalkLanguage, numbers and strings are first-class objects: They have methods and inherit indirectly from 'Object' (the root class). You can even add methods to them; you can change any class in the system - and "the system" includes the entire development environment, windowing system, etc.
Java has classes for the primitive types, but they wrap the primitive types; the primitive types aren't "first class objects." -- JeffGrigg
Yes, I was looking around for the (default?) Smalltalk API because I am sure that 'functions' such as cosine etc live on Number. Is this true ? -- ChanningWalton
The Smalltalk system is a memory image; it includes a class hierarchy covering everything Smalltalk is and can do. (So, what you want is a listing of the classes in that portion of the hierarchy, with their methods.) -- JeffGrigg
I end up doing this a lot in Java to add missing functionality to java library classes. For example, I almost always have a string utilities class that adds the perl join and split methods as well as a test for null or empty.
Functions have their place. But this is generally in plumbing code as opposed to domain or solution objects. -- HowardFear
RubyLanguage is also good in the regard that it has first-class Numeric and String types. However, it also has function classes, and calls them MixIns like at the top of the page. I think one example is Comparable, which allows you to use comparison operators like < and ==.
Ruby mixins are not function classes. Function classes have static methods that act on parameters. Ruby mixins are intended to be mixed in with the "include" method, at which point their methods become instance methods of the class that mixed them in. Function classes are standalone classes whose class methods are called directly. Ruby mixins typically rely on methods defined by the classes that mix them in and are useless by themselves. -- JasonArhart
I recognize the use of static classes to fix java library "design choices". For example this class might help you if you have ever needed to listen for focus (or mouse events or anything like that) on a composite Swing component like JComboBox
class FocusFix { public static void addFocusListener(Container cont, FocusListener listener) { Component[] c = cont.getComponents(); for (int i = 0; i < c.length; i++) { if (c[i] instanceof Container) addFocusListener((Container)c[i], listener); c[i].addFocusListener(listener); } } }Inheritance, delegation etc. could do the trick, but I really can't see that improving the design. Also, FunctionClasses? can be used as the SimplestThingThatCouldPossiblyWork when implementing the SingletonPattern. Of course some people think that SingletonsAreEvil. -- JanLarsen
Another common reason to find FunctionClasses? is that it isn't always obvious where to put the behavior otherwise. Suppose that you have a class Foo that's got a bunch of reasonable state and behavior and makes a fairly coherent and usable unit. In the course of your project you find yourself doing more than once an operation on Foos. Now, you could put that operation in Foo, so you know where to find it, but it isn't really part of the contract of the class, and many people think you should NarrowTheInterface to help keep the class with LowSurfaceArea?. It certainly doesn't belong anywhere else in your code.
I think part of this is a static/dynamic thing - people in static languages with solidly defined interfaces will balk at expanding Foo for this common behavior, especially if they are used to sealed classes. Perhaps it's also that SmalltalkLanguage allows you to categorize methods, so you can put you useful method in some category that a first-time reader of the class won't look at. I dunno - I don't always think that the SmalltalkLanguage categories help with LowSurfaceArea?, because they don't really have a LookHereFirst? category.
In other words, FunctionClasses? can be a way of dealing with the MethodsShouldBePublic/NarrowTheInterface tension. -- RandyBrown?
As written above, they sound like just a kluge to get around the fact that some languages want to tie every function to a class. Maybe what is really desired here is a GenericFunction.
Is this whole issue perhaps related to the observation that operations one performs on numbers are separate from the numbers themselves? i.e., I could see myself writing a class 'Addition' which I would instantiate to add or subtract numbers together, is not java.lang.Math (for example) in this context just a composite singleton of operations? -- WilliamUnderwood
UtilityClasses are also used as NameSpaces, if real NameSpaces aren't available.
See also StatelessObject
I've also heard them called StaticClass?es -- DavidPlass
UtilityClasses will be created more frequently in the language that follows traditional close-class mechanism like C++/Java where, once a class is defined, it can not be modified. In languages like Ruby, which has open-class principal, you will define such method in the class itself.
For example, if you found that some of the operation is always done to File object. you probably want to make this operation a method of File class, standard class, or any third-party class. But in java/C++, You can't, so you will have to create a Utility class containing static methods of what to do with the File object. But in Ruby, you simply add the new method to File class, and all object of File class will have that new method available.
Closed-class way works against OOP in general. The good practice of OO is to TellDontAsk. But this principle will never work if you can't teach the object new trick that you can tell it.
About the problem of where to put the method for binary operation. The problem is that we have to realize that method doesn't relly belong to an object, but it depends on every object involved in the operation, think Lisp CLOS. Ruby open-class way reduces needs for CLOS (at least now you don't create utility class for one argument method). But the best is still CLOS.
SmuggedLispyRubyWeeny?