Back to Basics: Usage of Static

The keyword static is somewhat awkward in a pure Oriented-Object world. I would like to expose here the usages of static I came up after 15 years of OO Programming.

The 2 rules of thumb are:

A: Static fields that are not pure value constants should be prohibited.
B: Static classes, that contain only pure functions, that compute outputs
from inputs parameters, are allowed. Personally, I am used to suffix
such class with XXXHelper.

You might not agree with these 2 simple rules so let me justify them.

What’s wrong with static fields that are not pure value constant? The underlying motivation for creating a static field comes from the need for an object that lives during all the program execution lifetime. Generally this is a central object, shared by many methods. So instead of passing the object as a parameter to all these methods, making it global makes it more convenient, easy or readable. I see 3 main problems in this reasoning:

First, everytime I stumbled on a need for an object that lives during all the program execution lifetime I found out sooner or later (generally later) that I was wrong. There is no such thing. For example imagine that your program become hosted as an addin (in VisualStudio for example). Addin can be unload and reloaded. Thus the program execution lifetime become session lifetime. And you certainly don’t want that the global object lives between sessions. The cornerstone here, to get my point, is the concept of session. It is virtually impossible to forecast up-front what will be sessions in which our code will live in the future. But there is a very common example of session: Automatic tests. An automatic test (or a set of automatic tests) is a mini session in itself. Having static mutable fields makes the code much less testable because all these mini-sessions must shared the same mutable state, with the need to initialize/clean up it.

Tests are generally ran sequentially. But what if several sessions are ran in parallel and they all share the same mutable objects. Then you need to synchronize access to the global object. And trust me, synchronizing accesses will be a major pain, not even taken account that this will slow down significantly your program. I wrote an article on Managing states in a multi-threaded environment without the synchronization pain. One of my preferred tip in the article is Thread / Resource affinity: The idea is as simple as it is efficient here also: making sure that an object is always accessed by the same thread. Basically each thread hold its own instance. If N threads holds N states then states must be attached to N objects and states cannot be static. To do so, using the ThreadStaticAttribute on your static field can do the job. But it is much more elegant to create a dedicated object for each thread that holds the complete thread-bounded context.

Finally, the third problem with static fields comes from the fact that this makes the program much less maintainable. Static fields represent global state. A global state can be accessed from anywhere in source code. Thus from anywhere in the source code, in any scope, you can potential create a dependency to the global state. The dependency is generally non-obvious because it is generally indirect (because the static field is generally encapsulated by a static static property). But the result is that accesses to the global state become anarchical. It is virtually impossible to enforce accesses to a global state and you will end up with some sort of side-effect nightmare. Sooner or later, the need to refactor the global state in order to control its usage will urge (this is another empirical fact I learnt the hard way).

A consequence of all this is that singleton class must be prohibited. From what we just saw, the single static field of singleton makes program harder to test, harder to maintain, and singletons foster concurrency problems. In my opinion, the problem with singleton is that it is the easiest OOP design pattern to learn. As a consequence, every OOP beginner knows the singleton and has a tendency to use it. Instead of using singleton, I use what I call Managers. A manager is a purely non-static class especially created in the spirit that only one instance will live at a particular point in time. A manager doesn’t have the dirty static instance field trick. Instead managers are generally referenced by other more high level managers. All this grape of managers represent the context in which the code is running. Manager can also be easily passed as a parameter to methods that needs locally to access the context. Also, manager are generally free to initialize and clean up, this make them convenient for testing.

Concerning the second rule B, yes I love purely static helper classes, that don’t have state. The simple CQL query

SELECT METHODS WHERE IsStatic

…just showed that 36% of my code resides in static methods. Object-Oriented is a great mean to model a problematic and creates proper abstraction. However, too often classes contain functions that computes well-defined output from well-defined input. These functions have a tendency to be potentially static and to be implemented with a lot of lines of code. Doing so result in fat classes hard to understand and maintain. This is why I prefer to nest this code inside dedicated helper classes. Not only this makes my instance classes smaller and clearer, but also automatic tests for helper classes are easy to write: tests just need to create input, call a static method, and check output done by computation. There is no hidden state to take care of initialize. Ironically, a helper class might encapsulate its own private mini-object model that models its own mini-concern.

I know that some others might see these helper classes like trash code that result from lack of design. I agree, such helper classes could be avoided but for what? For more instance classes whose purpose is not clear and obvious. Indeed, if their underlying purpose was obvious in the first place, then the idea to put the code in a static helper wouldn’t’ have even come to the mind. Keep It Simple Stupid!

 

This entry was posted in CQL, Helper, Object oriented programming, OO, Static. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Remi BOURGAREL

    Sometimes create some static field for cache purpose. For instance in my db I have all my languages (code + name), I don’t want to query in the DB every time I need to display the name of a language , so I have a static dictionary and I query the DB only when the dictionary doesn’t contains the required code in its keys.
    What’s wrong with that ?

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    >What worries me more than seeing the abuse of statics are phrases like “Imagine in the future if …” or “what if …”.

    I agree with you Rogério, I don’t like such assertive sentences. If I used them and if I bother writing a post on this topic, it is because so far, all the static fields and singleton I met or I created, ended up being refactored. This took me many years and many refactoring to realize that, and I though it was worth being publicly explained.

  • Rogério Liesenfeld

    What worries me more than seeing the abuse of statics are phrases like “Imagine in the future if …” or “what if …”.

    This kind of thinking only leads to pain, in the form of over-engineering. It adds considerable cost (and code) in both the development and maintenance phases of a project.

    “Statics” have their place, as anything else.
    Even in a modern language like JavaFX Script, there are globally accessible functions and global variables (there is no “static” keyword, though).

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    Simon, immutable types are really my friends as well, NDepend has a lot of support for immutability and I wrote about that topic in the past:

    Immutable types: understand their benefits and use them
    http://codebetter.com/blogs/patricksmacchia/archive/2008/01/13/immutable-types-understand-them-and-use-them.aspx

  • http://www.800px.com Simon Farrow

    You were Talking about easily testable static methods with well defined input and output and no state.

    One of the things from the Evans DDD book that has really stuck with me.

    Makes me think of immutable value types, pushing as much logic towards them as possible really makes things much easier to understand and test.

  • suresh maharjan

    Back to Basics: Usage of Static.. the title should be Don’t USE STATIC…& More than the absolute rules, when only to use static with code examples would have been better..

  • fschwiet

    I agree with these rules as guidelines, but I don’t think its fair to throw out singletons altogether. Rather I think you just want to restrict singleton implementations use static only to reference the singleton instance. The mistake in singleton implementation is to use static fields for its state and member variables, which makes it hard to test or have multiple instances if needed later.

    This is really only useful though if you care about testability or certain reuse scenarios, and many people would rather not.

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    >What if it was hosted on the moon?

    And what about testing? Isn’t a test a mini host of your application? how do you deal with side-effects provoked by sharing a singleton instance through multiple tests?

  • http://www.markdavidrogers.com m4bwav

    “what if my program becomes an addin hosted in another application (VisualStudio for example).”

    What if it was hosted on the moon?

    Sometimes it makes sense to optimize for an application’s intended use, if performance is an issue. Reusablility is great, but if your application or library hogs tons of resources no one would want to use it. This solution seems simplier and easier than developing some kind of over-engineered session manager, unless it was specifically needed.

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    Dominic, ASP.NET environment is a big beast. Sure singleton might be the only technical way to achieve your need, but this just shows a limitation of ASP.NET (I already had btw). I know ASP.NET doesn’t work this way, but what if in he future for some reasons 2 instances of your application run in the same AppDomain?

    >Instantiating two of them will cause a BSOD.

    I meant instantiating 2 of them sequentially. But anyway, if you run into a technical limitation, as for ASP.NET application timer trick, sure, every mean is welcomed, even a static field.

  • Alun Harford

    ‘Instantiated just in one place in the code, sure, but maybe instantiated/opened/closed/released consecutively several times at runtime. During future program execution or testing, who know in how many sequential ‘sessions’ you’ll need to have an object that encapsulate COM1? This exactly reflect what I wrote:’

    I think you’ve missed my point. COM1 doesn’t represent a connection that can be opened/closed/released – it represents the physical port. Instantiating two of them will cause a BSOD. These are the circumstances under which a singleton is really supposed to be used. The problem comes when developers use a singleton because they think ‘there will only ever be one of these’ instead of ‘it is invalid for more than one of these to ever be instantiated’.

  • http://www.dominicpettifer.co.uk Dominic Pettifer

    How would you implement a constantly running background service/thread in the ASP.NET application that needs to do something at regular intervals (cleanup database/file etc. every 30 minutes), in a locked down environment that doesn’t permit using a Windows Service?

    In this situation, we used the Singleton pattern and it worked quite well.

    Also my understanding of the FlyWeight pattern is that it facilitates multiple static instance of objects that are shared by multiple threads for efficiency, correct me if I’m wrong. How would this fit in with your rules?

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    Awkard coder, thanks for the 2 links, very interesting. They both describe clearly the problematic that I underline at the end of the post.

    I know that some others might see these helper classes like trash code that result from lack of design. I agree, such helper classes could be avoided but for what? For more instance classes whose purpose is not clear and obvious. Indeed, if their underlying purpose was obvious in the first place, then the idea to put the code in a static helper wouldn’t’ have even come to the mind. Keep It Simple Stupid!

    My position is that I prefer this sort of Helper static classes and Manager state holder instance classes than a super refined and fine-grained model that makes my code complex and unmaintainable.

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    >If you have a field that is initialization heavy and it doesn’t need to be reinitialized every time a class is created, then static seems like a decent solution.

    Please think out of the box. Before posting another example just ask yourself this single question: what if my program becomes an addin hosted in another application (VisualStudio for example). Addin can be started and stopped at whim. Do you really want to have N singleton to init and reset? Wouldn’t you prefer a clean concept of session manager that can be started or stopped with a single method call?

    And what about testing? When starting a test how can you be sure that the global singleton object state hasn’t been corrupted by a previous test? Isn’t it more easy to create a new fresh contextual object for each test?

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    DaRage, using singleton to implement IoC container is an implementation detail. However it shows well the problem. Imagine in the future if 2 instances of your ‘program‘ live in the same AppDomain, and if each of these instances needs a different implementation of what’s hidden by the IoC. You are stuck because the singleton enforce only a single reference.

    This shows how a future concept of session that you don’t know about yet, will nest your current program context composed of an IoC container.

  • http://www.markdavidrogers.com m4bwav

    It seems like one of the benefits of using static fields is that you can reduce the cost of initializing objects. If you have a field that is initialization heavy and it doesn’t need to be reinitialized every time a class is created, then static seems like a decent solution. I usually don’t let static fields be publicly accessible if I have to use them.

  • DaRage

    I don’t understand. An IoC container is a good example for singleton use. Can you elaborate how you can use ‘Managers’ for IoC for example?

    Thanks

  • http://codebetter.com/members/Patrick-Smacchia/default.aspx Patrick Smacchia

    >So if you want a class that represents COM1, would you want that to be instantiated in more than one place

    Instantiated just in one place in the code, sure, but maybe instantiated/opened/closed/released consecutively several times at runtime. During future program execution or testing, who know in how many sequential ‘sessions’ you’ll need to have an object that encapsulate COM1? This exactly reflect what I wrote:

    Everytime I stumbled on a need for an object that lives during all the program execution lifetime I found out sooner or later (generally later) that I was wrong. There is no such thing


    >the important thing is whether or not you /have/ multiple instances, right?

    Wrong, the important thing is to be able to deal easily in the future with multiple sessions, that will live sequentially or even maybe concurrently (like testing on multi-thread).

     

    >Absolute rules are a bad idea.

    I don’t agree, every singleton I met or done have bitten my team in the butt the hardest (to reuse the words of Justin :o). But I am not surprised by your reaction, as written in post, singleton as the first design pattern we learnt, is cherished by most programmers.

  • Justin Karr

    Eh, I don’t think that Singleton necessitates static. If your Managers are only allowed one instance (like, say, a Factory), then they’re Singletons.

    Being practical here, the important thing is whether or not you /have/ multiple instances, right? That it’s designed to be shared, and be a central/authoritative resource? Not whether or not the class defines a (probably static-based) approach to protect against multiple instances?

    That aside, I have to agree. I’ve seen static use be argued for efficiency and convenience. But the cases where it’s most strongly argued also have been the cases where it’s bitten my team in the butt the hardest. Maybe because we too so great an advantage of that “convenience”.

  • Alun Harford

    “singleton class must be prohibited”

    So if you want a class that represents COM1, would you want that to be instantiated in more than one place in your code?

    Absolute rules are a bad idea. It happens that in my codebase at the moment no code lives in static members, but that doesn’t make them ‘always wrong’ or ‘prohibited’ – it depends on what you’re doing.