Back to basics: Usage of static members

Using the static keyword should be considered as an unnatural design act in a OOP world. The problem is that developers get punished for using static fields and methods, months or years after having creating them. And indeed, reasons why static members are harmful are not obvious. But I won’t bash static members here since they can also be pretty useful in precise scenarios. Let’s develop a bit.

Static fields: use them only for constant and immutable states

In C#, the keywords const and readonly are used to mark a field as constant. de-facto const fields are static and immutable but it is not the case for readonly fields. Having a readonly static fields means that the object referenced by the static field will remain the same during the outer AppDomain lifetime. It doesn’t mean that the object is immutable. For example, one can have a readonly static field referencing a dictionary instance. And dictionaries in .NET are not immutable because one can still add/remove some key/value pairs at any time.

readonly static IDictionary<string, string> s_CountryCodeCorrespondance =
   new Dictionary<string, string> {
    {"+1" , "USA" }, {"+33" , "France" }, {"+44" , "UK" }, /*...*/
  };

In the example above, the dictionary instance is not by-design immutable, but its semantic makes it immutable (it is pretty rare that a new country code is created or changed). There are several ways to transform this semantical immutability to a by-design immutability. Maybe the easiest way would be to nest the static dictionary inside a dedicated class that would limit accesses to the dictionary:

static class CountryCodeCorrespondance {
   internal static bool TryGetCountryFromCode(string code, out string country) {
      return s_CountryCodeCorrespondance.TryGetValue(code, out country);
   }
      readonly static IDictionary<string, string> s_CountryCodeCorrespondance =
      new Dictionary<string, string> {
       {"+1" , "USA" }, {"+33" , "France" }, {"+44" , "UK" }, /*...*/
   };
}

Here, in my opinion, we have a static field that will never provoke any pain because it is both constant (in the sense the instance will remain unique) and immutable (there is no way to tweak the state of the object).

But why did I come to the conclusion that non-constant or non-immutable static fields, are harmful? Static fields are appealing for programmers because they represent an immediate way to maintain and provide a state across a program (the global state syndroma). But a code base will necessarily become more complex in the future. This means that no matter the static field is private or not, direct and indirect accesses to the static field at runtime will become chaotic. Several part of the code will read and mutate the field states and at a point, predicting the static field’s state at run-time will be close to impossible. Obviously it gets even worse in a multi-threaded environment.

Concerning relying on the popular singleton pattern, I attest that I always ended up removing all singletons I formerly created. Most of the time a singleton object maintains directly or indirectly one or several mutable states and this provokes a contention point. Singletons  makes things even more complex to debug, since by nature, a singleton encapsulates and then hides the mutable state(s) maintained, making potential debugging drama luring.

Another – less obvious – point against singletons and all kind of static mutable states is that they are out of scope of any future potential context. The context of a static field is by-design its parent AppDomain. They are some circumstances where developers wish a finer grained context. I learn it the hard way when NDepend became a Visual Studio addin. Addins can be enabled and disabled at whim by the VS user at VS run-time. But under-the-hood this takes place in the same AppDomain. So if a VS addin relies on some static mutable states, it is its responsibility to initialize and reset all static mutable states of the program at addin enabling and disabling time.

For sure, not every program will end up being a VS (or another host) addin. But most of program comes with a unit tests battery. Typically, tests are executed consecutively in the same AppDomain. And each test represent a mini context. At test run-time, static mutable fields are accessed and mutated again and again by tests executed in a random order (one should never rely on tests execution order). Hence it is the responsibility of each test, or at least each test suite, to set correctly all static mutable states. This makes unit-test activity more error-prone and harder to write.

Static methods

For all the reasons enumerated, having some non constant or mutable static states will provoke pain sooner or later. However, static methods are pretty harmless as long as they don’t mutate any static state (which is obviously impossible in a program that doesn’t have any mutable static state). Personally, I end up implementing a lot of complex algorithms in one or several static methods, often encapsulated in a dedicated stateless static class. Many algorithm are easier to read and maintain when they are written in a procedural fashion. It is not by chance that  algorithms are often exposed through a procedural pseudo-code sample.

But the killer reason for implementing algorithm with a stateless procedural style, through static methods, is that it lets the programmer formalize inputs and outputs through a single method call. As an immediate benefit, this makes corresponding unit-tests much easier to write.

A distinction can be made between algorithm that mutate inputs, and pure algorithms (or pure static functions) that keep all inputs constant. Obviously having pure static methods is preferable, but personally, I can’t remember a situation where I’ve been doomed by non-pure static methods.

Of course OOP purists can blame me for advising some procedural code style (and indeed, I got blamed for using many static methods in NDepend.Helpers.FilePathDirectory). But for all reasons exposed, I consider they help me write more readable, more testable and more maintainable code as long as no static state gets mutated.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://thecafetechno.com/tutorials/interview-questions/most-frequently-asked-core-java-interview-questions-and-answers/ dharmendra@thecafetechno.com

    nice post thanks for sharing

  • http://tutiez.com/how-to-declare-constant-in-java.html pranav

    Very good and informative, I completely agree static should be used for constant and immutable types. 

  • http://javarevisited.blogspot.com/2011/01/how-classpath-work-in-java.html JP@ classpath in Java

    One more issue with static keyword is that they often result in breaking thread-safety of class. most of the time concurrency issue occur due to static variable if they were not synchronized properly.

    Javin
    How HashMap in Java perform get operation  <a

  • http://javarevisited.blogspot.com/ Javin Paul

    It’s not that static is bad , its correct usage of it. I have seen where logger instance we have at class level and always static to use it on both static and non static method but beware of any static field in multi-threaded environment can cause you serious race condition.

    Javin

    How Synchronization works in Java

  • Anonymous

    >The pain comes with code that *does* use mutable state.

    But if there is no static mutable state, a static method can only mutate the state of its inputs or create new states by creating new objects.

    On this point we disagree, since my stance is that:

    “A distinction can be made between algorithm that mutate inputs, and pure
    algorithms (or pure static functions) that keep all inputs constant.
    Obviously having pure static methods is preferable, but personally, I
    can’t remember a situation where I’ve been doomed by non-pure static
    methods.”

  • Steve Py

    Matt hit it on the head.

    @Patrick
    >There is no requirements to set for a static method that is not relying on any mutable state/outer context.

    That was entirely my point with: “Pure static methods that merely provide functional computation are innocent enough; However the smell of seeing static methods called in-line should be treated like smoke: Be on the lookout for nearby flames.”

    The pain comes with code that *does* use mutable state. Static methods that do are the fires, seeing static methods called in-line is a smoky smell. Someone can easily enough write unit tests for code that is calling a mutable static call and it may even work, for now. But it is a dependency not controlled by the test and you can easily be looking at fragile test scenarios.
    Personally I like to avoid static calls as much as possible.

  • http://adamschepis.com Adam Schepis

    I couldn’t agree more. In fact, i wrote about this very recently on my blog and generated quite a bit of discussion:.

    http://adamschepis.com/blog/2011/05/02/im-adam-and-im-a-recovering-singleton-addict/

  • Anonymous

    >I CANNOT unit test my DoStuff() method, without setting up all the requirements for the static method.

    There is no requirements to set for a static method that is not relying on any mutable state/outer context.

    >It is preferable to have some kind of inversion of control where I can mock your class, and test my method irrespective of the way the static method functions.

    Why would you wish to mock a static method that is note relying on any outer context?

  • http://profiles.google.com/mrsalmon Matt Salmon

    Unit testing of static methods is painful due to dependencies. For example, you have a static method on a class: MyClass.StaticMethod.

    Unit testing this is fine.

    Now, I implement a different class, with a method that internally uses the above static method:

    public class AnotherClass
    {
    public void DoStuff()
    {
    MyClass.StaticMethod();
    }
    }

    Herein is the problem – I CANNOT unit test my DoStuff() method, without setting up all the requirements for the static method. It is preferable to have some kind of inversion of control where I can mock your class, and test my method irrespective of the way the static method functions.

    Does that makes sense?

  • Anonymous

    Steve, I double-read your comment but I don’t understand the disadvantage you found in testing static method??

    >However, public static methods are significantly more risky from a unit testing perspective.
    ??
    >They’re no more difficult to test, but are more difficult to test around
    ??
    >newing a servicing instance like that should raise a few alarms from a testability viewpoint.
    ??

  • Steve Py

    A bit of a comment on Static methods. Private static methods are generally quite harmless so long as they don’t mutate or rely on mutable static state. Visual studio even goes so far as to pick this up as an optimization to make private methods that do not access state static. However, public static methods are significantly more risky from a unit testing perspective. They’re no more difficult to test, but are more difficult to test around (Unit testing code that is calling static methods) should their implementation not be pure.

    Unit testing a method that calls a static method:

    public void SomeMethodUnderTest()
    {
    var someResult = SomeStaticEnabledClass.StaticMethodThatDoesStuff(/*parameters */);
    // continue with it…
    }

    from a unit testing perspective is little different from encountering something like:

    public void SomeMethodUnderTest()
    {
    var someResult = new SomeUtilityClass().MethodThatDoesStuff(/*parameters*/);
    // continue with it…
    }

    The utility class is a dependency of the method under test, and newing a servicing instance like that should raise a few alarms from a testability viewpoint. Life is a lot simpler if dependencies can easily be substituted out under test. Pure static methods that merely provide functional computation are innocent enough; However the smell of seeing static methods called in-line should be treated like smoke: Be on the lookout for nearby flames.

  • http://profiles.google.com/mike.strobel Mike Strobel

    Nice writeup–I agree completely. Static data should, in most cases, be constant and immutable (though there are exceptions to every rule). Static methods are generally fine, and may even be preferred for algorithms with extremely hot code paths, as they are “cheaper” to invoke.

  • Terry Burns-Dyson

    Thank-you for the answer. I enjoyed reading the post, and find others opinions and arguments useful to learn myself. I just make sure to ask the question, because there are a lot of posts out there that are “This is bad, don’t do it” without “Here’s how I got around this.. ”

  • Anonymous

    >I’m ok with “you’re currently doing it wrong.. because.. ”

    I see this post more like ‘I got to learn the hard way that it is harmful because…, so I warn you’

    >What do you replace Singletons with?

    There are multiples possible designs solutions.
    Certainly the easier way would be to encapsulate the ‘session’ context (including things like cnx string) in a class with a single instance during the session lifetime. This instance would be created at the session initi, and discarded at the session end.
    This instance would be passed to all methods that need to access the context. This is acceptable if a few methods are relying on the context (but this is often the case isn’t it?). Doing so comes with the advantage of making obvious where the context is used. As a benefit avoiding anarchy in context access is easier.

  • Terry Burns-Dyson

    What do you replace Singletons with? In the case of a connection string required throughout the lifetime of a session or a need to get a handle on your IoC container?

    I’d like to learn more about why and my alternatives. I’m ok with “you’re currently doing it wrong.. because.. ” but I like to know why, how I can change and what I should change.