I'll be frank. I don't like static methods. They make me cringe. In the universe of OO static methods are anti-matter.
They don't have to be bad, but they are dangerous, because they are used incorrectly.
When static methods can be good
There are only two situations when static methods or variables are being used and it's not an abomination.
- Declaring a true global constant, not a global variable. A global constant. Example: Math.PI. This is a fair shorthand for really saying that there is one instance of the universe, and that universe singleton contains a mathematical concept singleton in which there is a property PI which does not change. This concept seems strange to us because we are used to not thinking about PI in the context of object oriented responsibility. It would become more obvious if we were designing some strange game where there were alternate universes with different mathematical concepts and constants.
- Object creation. Static methods are a valuable and valid method of object creation. Overloaded constructors that take different arguments are not very clear and are often made clearer by replacing them with a static constructor.
is made much more clear when written as
it becomes really clear in the usage
When static methods are bad
Aside from those two uses, in my opinion, any other use is an abomination. (I suppose I let C# extension methods slide here, because they are so useful under the right conditions, but I reserve the right to make judgement on a future date.)
Static methods usually indicate a method that doesn't know where it belongs. It is sitting out there trying to belong to the class it is on, but it doesn't really belong, because it doesn't use the internal state of the class. When we look at our classes from the Single Responsibility Principle (SRP) viewpoint, a static method is usually a violation because it tends to have a responsibility that is not the same of the class it is attached on.
One way to think about static methods is as global procedures. Essentially a static method can be called anywhere from anywhere. It just pretends to be part of a class, when really the class is only used as a “tag”, which organizes the method by some logical division. I look at static methods in these terms, because creating global procedures is the exact opposite of object oriented design.
Another major problem with static methods is the testability. Testability is a big deal when building software. Static methods are notoriously difficult to test, especially when they create new instances of concrete classes. If you have ever worked in legacy code and tried to write a unit test for a static method, you know my pain.
Static methods also are not polymorphic. If you create a static method on a class, there is no overriding that behavior. You are stuck with a hard coded reference to that implementation.
Finally, static methods increase the complexity of an application. The more static methods there are, the more a programmer working in the application has to know about. When instance methods are used in a class, having an instance of that object will allow a programmer to determine all the actions that can be taken. When static methods are used the programmer has to know about the secret methods that may not even be on the object he is working with, but manipulate that object. Let's look at one common example: Date and DateUtilities.
In more than one application I have worked on, Date and DateUtilities existed. Date existed to provide an implementation of date and time, and DateUtilities existed to manipulate the date and do things like figure out the first day of the month, or determine holidays, or see if two dates overlap. I don't know how many times I would try to write a method to do one of the things DateUtilities already did because I didn't know to look for a static class called DateUtilities with static methods that did what I wanted. As a programmer, I have to remember to always check all the methods in DateUtilities to see if there is one that does what I want. This can be a large amount of overhead when you are working in a large application, with many static methods hanging around in helper classes. Perhaps I am spilling over into another problem here, but the point is that it is much more difficult to remember what utility methods exist floating out there than it is to use a method on a class that the functionality really belongs to. (Side note here: C# extension methods kind of solve this problem, by allowing you to type “.” and see the static methods that can operate on that class).
Final words
So just remember when you create a static method to think about it carefully. I am not advocating never using them. I am advocating having a really good reason and checking first to see if the static method really belongs to another class where it can use state information.
If you have the skills but you just aren't seeing the success you deserve in your career, then do check out my course “How to Market Yourself as a Software Developer”.