An Architect's View

CFML, Clojure, Software Design, Frameworks and more...

An Architect's View

Static is Evil

December 12, 2009 ·

This cropped up on the TDD mailing list and it made me smile so I wanted to share it along with some commentary. A fairly common request from folks in the CF community is for "static" methods (and data members) to be added to CFML. Folks look at Java, think it's a cool concept, and want it in CFML as well. I generally pop up and say it's a bad idea and that Java only has static because it doesn't have any concept of a global application scope (which CFML does, of course).Anyway, someone posted a code fragment on the TDD mailing list, asking how to test one class in isolation that has methods that explicitly depend on static methods of another class. When you have dependencies, the typical approach in testing is to mock the dependencies so that you test the "unit" in isolation. Dependencies on static methods (and static data members) are pretty much impossible to mock without resorting to some sort of "cheating" (preprocessing the source or manipulating the compiled binary). Folks on the list responded that this dependency was a design flaw that needed to be fixed to make the code testable. Arnauld Bailly of OQube went a little further:
Don't use static. Static is evil. Use objects. Refactor to use objects and DI. Then your problem disappears. Static is something that crept in Java probably because Sun wanted to market its language to C/C++ developers (just kidding, but who knows? I don't have time to search on the web for the "right" answer). Don't use static (and don't repeat yourself :-).
Nuno Filipe Marques also suggested refactoring to use objects rather than class statics and then rely on Dependency Injection (DI) to make the class easier to test. Charlie Poole agreed that this is a design flaw and also criticized statics:
If your goal is that class1 should be independently testable, then it's a design flaw. [snip] That's not to say that the statics are OK - IME, they bite you sooner or later. It's a question of how soon.
The reason for this negativity is much the same as why CFCs should not depend on shared scopes (such as application and session): it introduces a hard-to-test dependency. Most CFers seem to accept the argument that allowing CFCs to depend on application and session scope (except in very tightly controlled circumstances) is a problem for both testability and maintainability. Consider that issue when you find yourself thinking that "static" would be good to add to CFML! As an aside, Scala has an interesting approach to this problem: instead of statics, it allows you to define a singleton object (with the same name as the class with which it is associated) - with regular methods and data members - so that you can inject it just like other objects and therefore maintain isolation for testing (and thus improve maintainability and flexibility). There's nothing wrong with using a singleton object in place of static methods and data members on a class - don't assume the Java way is the only way!

Tags: architecture · coldfusion · tdd

3 responses

  • 1 Allen Graetz // Dec 14, 2009 at 8:01 AM

    "Most CFers seem to accept the argument that allowing CFCs to depend on application and session scope (except in very tightly controlled circumstances) is a problem for both testability and maintainability." - SC

    They really need to learn the beauty of loose coupling.
  • 2 Cellux // Nov 25, 2013 at 3:07 AM

    Imo static != "java way" != evil..

    Static is a useful language feature, and has nice uses in certain scenarios. They shouldn't be used for dependencies, and of course there are other ways to misuse it.

    I would also add that the Singleton pattern is almost as bad for testability as static - for the same reasons.
  • 3 Sean Corfield // Nov 25, 2013 at 9:11 AM

    @Cellux, there are certainly reasonable uses for class variables/functions (as opposed to instance variables/member functions) - and I think most people agree that Java's approach to OOP is, like C++'s approach to OOP, not what the creators of OOP had in mind :)

    And, yes, the Singleton pattern can be a problem for testability but that is also solved through DI. The real problem with most Singleton pattern implementations is the central "all-knowing" Locator which everything else then has to depend on, which makes stubbing and mocking much harder.

    This post was specifically about why adding some Java-like form of "static" to CFML would be a bad idea tho'...