Pages

Friday, July 15, 2011

static should be deprecated

In a tweet I jokingly proposed to abolish the static keyword in all (garbage collected) languages. At the beginning it was just a joke, but then i wonder:

can I get rid of static?
First of all: why get rid of static? Because it's a source of troubles.

Factory

We have a class and a harmless static method to build it up:

public class DumbClass {

  private String foo;
  public String getFoo() { return foo; }
  public void setFoo(String foo) { this.foo = foo; }

  private String initializedStuff;
  public String getInitializedStuff() { return initializedStuff; }

  private DumbClass(String foo, String initializedStuff) {
    this.initializedStuff = initializedStuff;
    this.foo = foo;
  }

  public static DumbClass create(Context c) {
    return new DumbClass( c.doSomethingToGetFoo(), c.doSomethingToGetStuff() );
  }
}

Requirements always change, Alan Shalloway docet, so a customer wants foo in CamelCase rather than UPPERCASE. Case must not change for all other customers, so I would say:
Easy to do: I will create a new library for that customer and put a class extending.. OOps, I can't! It's a static method. What if I had an abstract factory, instead?

public class DumbClass {

  private String foo;
  public String getFoo() { return foo; }
  public void setFoo(String foo) { this.foo = foo; }

  private String initializedStuff;
  public String getInitializedStuff() { return initializedStuff; }

  DumbClass(String foo, String initializedStuff) {
    this.initializedStuff = initializedStuff;
    this.foo = foo;
  }
}

public interface IDumbClassFactory {
  DumbClass create(Context c);
}

public class DefaultDumbClassFactory {
  public DumbClass create(Context c) {
    return new DumbClass( c.doSomethingToGetFoo(), c.doSomethingToGetStuff() );
  }
}

Then I would make a wrapper of DefaultDumbClassFactory or I would make another implementation of IDumbClassFactory: it would work!
The moral of the story: don't use static methods, especially public ones!

Private fields

Sometimes you want keep a counter of instances of a certain class to know how many of them you have in memory. Ok, I would do it with a static field:

public class Foo {

  private static int howMany;

  public Foo(Something s) {
    howMany++;
  }
  ...
}

After a year you find out that nobody reads that counter anymore and, once deployed your library on a web server running continuously for two years, it could get negative (integer overflow) or cause an exception, unhandled, of course. Or you will need that it doesn't trace derived class or you will need the counter to be saved in a database and then? You find out that you need an abstract factory.
Now: when I'm going to write static, I stop, think it over and finally I nearly alwasy I write: interface

Wolfsburg VW-Werk

No comments:

Post a Comment