When should we use static methods in class?
One rule-of-thumb: ask yourself “does it make sense to call this method, even if no Obj has been constructed yet?” If so, it should definitely be static.
So in a class
Car you might have a method
double convertMpgToKpl(double mpg) which would be static, because one might want to know what 35mpg converts to, even if nobody has ever built a Car. But
void setMileage(double mpg) (which sets the efficiency of one particular Car) can’t be static since it’s inconceivable to call the method before any Car has been constructed.
(Btw, the converse isn’t always true: you might sometimes have a method which involves two
Car objects, and still want it to be static. E.g.
Car theMoreEfficientOf( Car c1, Car c2 ). Although this could be converted to a non-static version, some would argue that since there isn’t a “privileged” choice of which Car is more important, you shouldn’t force a caller to choose one Car as the object you’ll invoke the method on. This situation accounts for a fairly small fraction of all static methods, though.)
Define static methods in the following scenarios only:
- If you are writing utility classes and they and they are not supposed to be changed.
- If the method is not using any instance variable.
- If any operation is not dependent on instance creation.
- If there is some code that can easily be shared by all the instance methods, extract that code into a static method.
- If you are sure that the definition of the method will never be changed or overridden. As static methods can not be overridden.
In general, if your situation requires encapsulation of state or an organizational structure, then you will be using classes.
On the other hand, if you have something that is a cross-cutting concern, and can be used broadly across your application, you might consider methods in a static utility class.
System.Math in the .NET framework (and Java) is an example of this.
I’m refactoring some code and I’m looking at a class called HFile. HFile has all private constructors so that you can actually create instances of it. Instead of creating instances of HFiles as follow:
var file = new HFile('filename') file.Save()
All HFile interaction is handled via static methods. So if I wanted to save a file I would call:
and then internally an instance of HFile would be created and then saved. Obviously without knowing the whole story any reader must reserve judgment, but it seems like using static methods has become very fashionable at my place of work. So I’m wondering if there are good principles/best practices for usage of static methods that can helpful for a group of guys sitting down and reviewing their usage of static methods.
In your example, HFile is probably an object with state, so I would not generally use a static method to save it. It’s simpler just to make a method call on the specific HFile object, rather than having to pass the entire object to a static method for saving. Whether that makes sense or not in your particular application depends on whether your application’s paradigm sees HFile objects as things to be passed around and acted on by outside methods, or as standalone objects capable of saving themselves.
how do I ensure that I only have one of something
only have one of something The problem of “how do I ensure that I only have one of something” is nicely sidestepped. You instantiate only a single ApplicationFactory in your main, and as a result, you only instantiate a single instance of all of your singletons.
The basic issue with static methods is they are procedural code
The basic issue with static methods is they are procedural code. I have no idea how to unit-test procedural code. Unit-testing assumes that I can instantiate a piece of my application in isolation. During the instantiation I wire the dependencies with mocks/friendlies which replace the real dependencies. With procedural programing there is nothing to “wire” since there are no objects, the code and data are separate.
An article worthy of reading: Static Methods are Death to Testability
Curiously recurring template pattern(CRTP)
how to use CRTP to achieve independent variables for static variables defined in a base class: