Monday, April 10, 2006

Static or not static; that is the question...

Background: I have been involved in several projects where some developers have used the static keywords in very bad places and caused everything from bugs to memory leaks ...
(ok, not really leaks but really nasty memory hogs...)

Rule-of-thumb: Only use static for utility methods, singleton field and singleton get:ers.
(I consider the .NET "Empty"-pattern to be a specialized singleton)

The most common miss-use of static is to create small caches, these tend to be sprinkled around the codebase with the best of intentions.
(But you know what they say about the road to hell...)

These caches are normally implemented using a simple if( ... ) statement and an assignment of a static variable if the statement evaluates to true.
// declaration
static FooBar _foobar;
// ...somewhere in the code
if( _foobar == null )
{
_foobar = GetFooBar();
}
_foobar.DoFoo();

This kind of cache is nothing but a memoryleak and a GC-killer sincethis memory behavior isn't what the GC and .NET was designed for. (the worst case I have ever seen more or less killed all the GC since there where no "dead" objects for the GC to collect and the developers stated that .NETs GC was flawed...)

So now we got an idea what not to do, lets go through what to do.

Utility methods:
A utility method is a method that doesn't use any instance fields,you will find plenty of them on the System.String class; Concat( ... ),Compare( ... ) and Join( ... ). There is even a performance gain here, static methods execute faster then instance method since the runtime doesn't need to push the "this" reference onto the stack.

Singletons:
The second legitimate use is the singleton pattern. A singleton has a very common implementation pattern.

class FooBar
{
// the one and only instance
static FooBar _instance = new FooBar();
// get:er
public static FooBar Instance { get { return _instance; } }
// the most important part, without this the class
// is possible to create with a normal new call
private FooBar() { }
}

"Empty" - singleton specialization:
To avoid multiple instances of special objects like empty strings,the .NET base class library utilizes a specialization of the singleton pattern.

And finally, since there always shall be an exception to confirm the rule, here it is:

Constant data:
that needs to bind during run-time and not compile-time; const binds at compile-time since the compiler copies the value to every user. This makes const data much faster then static but much less flexible since it will require a recompile to change. The System.IO.Path holds some data that meets this requirement. (PathSeparator, VolumeSeparatorChar)

So to conclue: avoid statics unless you are developing:
- a utility method
- a singleton class (including Empty pattern)
- defining static data that needs to bind at run-time



Comments:
Kan du maila mig?
 
Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?