This week's book giveaway is in the Mac OS forum. We're giving away four copies of a choice of "Take Control of Upgrading to Yosemite" or "Take Control of Automating Your Mac" and have Joe Kissell on-line! See this thread for details.
i have written a class that contains calculation routines only, and maintains no state (ie no member variables at all) in order to save the (small) overhead of creating and destroying an object i wrote all the methods as static. however during a recent code review this technique was questioned by a senior developer - he didnt exactly say why, but he called it 'unusual' and said that he tended to avoid static unless there was a really good reason to use it, and that i should rewrite the class making the methods non-static. i thought about what he said, but can't understand his point of view - i would have though the opposite was true - ie. only force people to instantiate a class if there is a good reason, otherwise keep things static. if it makes a difference the class is part of a web application, and so will run in a multi-threaded environment. what do you all reckon?
Your approach of making all methods static for like a calculation utility class is perfectly fine in my opinion.
1) Small memory footprint: One class object vs. users of your class possibly instantiating > 1 objects (object creation/GC takes CPUs). Though if all methods are static, make sure you have a private constructor to prevent others using it incorrectly.
2) Thread-safe: You don't have any state in the class, everything local.
The only argument is code maintainance. Down the road, people have already coded against your util class but you have a requirement to instantiate object off this class, you can't do it easily anymore. Making this util class a singleton is safer.
Classes with all static methods are often called "utility" classes. There are plenty of examples like Math in the library and in the real world. It's a handy shortcut and pretty well accepted with some warnings.
One potential problem is that it's hard to replace such a class with a subclass or different implementation. Classes that use it have very strong coupling with hard references to the exact utility class. With regular objects your clients can have references to interfaces or abstract classes, get concrete instances from a factory or by dependency injection (long enough for a separate note if interested) making them less tied to a single implementation.
For example in my little home projects I use a static Logger. Nearly every project references Logger all over the place. If I decided to use some other logger I'd be in trouble. Or not. Since I own the Logger class, I could make its methods call some Log4J class instead of what it does today. But it would be very tough to do that for half my projects and not the other half. Or not. Each project could have a LoggerConfigurator that sets up the hidden Log4J class or some other to do the real work.
All those workarounds exist only because I own Logger. If I had purchased Logger as a binary with no source code, I'd be married to it for life. Ouch!
So if you're fairly confident that people without the source code to your class will never need to replace it or extend it, you can decide to take the risk.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Joined: Apr 29, 2005
thanks for your comments, i'll stick to my guns on this one then
If you ever want to use this logic in a JSP page as a "helper bean", then you won't be able to using most "bean-based" frameworks. You can do what the Jakarta Commons BeanUtils folks have done and put the actual implementations into a bean class and just use the statics to call methods on a bean instance.
James Carman, President<br />Carman Consulting, Inc.
I agree with what the senior developer told you that static methods should be avoided unless you have a good reason. As many people have stated, it seems like you surely have a VERY good reason in this case!