views:

582

answers:

7

Hello,

are static classes considered bad practice? I read an article about this a couple days ago (can't find it, sorry) which basically said that having static classes (especially those 'helper' classes) are typically a sign of bad code. Is this correct, and if so, for what reasons?

+3  A: 

Nah, it's not really correct.

There are plenty of functions that are not specific to an instance of an object, and that don't require state. For example consider 'Math' functions.

Almost all languages have something like:

y = Math.round(x);

So the 'round' function is static. You could, if you were crazy, argue for something like (C#):

class RoundFunction<T> : GeneralMathFunction<T>
{
    public override T Operate (params object[] variables) {
        ..
    }
}

But, IMHO, you'd be a little weird to do so.

Certainly there is a time when too many static functions are a sign of something gone wrong, but, within reason, it is not 'bad'.

Noon Silk
Silky, as Barry Brown pointed out, these are static methods. I merely meant entirely static *classes*. :)
Alex
In which language?
Noon Silk
In C# (..........< for 15 char requirement lol)
Alex
If it's c#, a static class just means that it contains only static methods. You're just declaring that there is no reason to make an instance of it. So the same rules apply, as in my post.
Noon Silk
shouldn't round() be a method on float, if we're actually trying to be object oriented?
Peter Recore
Peter: well, you can round doubles/decimals too.
Noon Silk
+1  A: 

There are needs where you have a Utility class where all the methods are static. In that case if you make the class static it clearly indicates your intention. And at least in C# you can not have non-static methods inside a static class.

Tanmoy
+2  A: 

I think the general argument is against keeping mutable state in static classes, and basically using them as global variables. There's nothing wrong with static helper methods in a static class.

And as to why global variables are bad, I'm sure between here and google you'll find half a millions pages and blog posts about it.

Davy8
yes, that is what he *claims* but it is not what he actually shows. Static classes (like Math) are NOT the equivalent of Global variables, they are the equivalent of Global *constants*. Even with parameters, this is still not logically different from Global constant arrays, lists, etc. I don't recall much problem with them.
RBarryYoung
I edited my answer to indicate that I meant mutable state in a static class, not constants.
Davy8
A: 

Here are some links to some google testing blog posts on why static methods can hurt the testability of your code, as well as why static methods (which are the bad part of static classes) introduce all kinds of potentially surprising coupling and interaction between components.

how to think about oo

singletons

static-methods-are-death-to-testability

Peter Recore
all of these articles are written by the same guy. Turns out he's just a Ruby bigot on a rant. His whole argument is summed up in his own words:"The basic issue with static methods is they are procedural code. I have no idea how to unit-test procedural code." Wow. 50 years of testing methodology preceeded this guy and he knows none of it. The only that I ca imagine would be more embarrassing than publicly admitting this would be if the rest of us based our desing and testing methodologies on the opinions of someone who apparently slept his way through college.
RBarryYoung
He's an idiot. He is claiming that after you write a static method like Abs() you will decide to add lots of extra business logic inside it that you won't be able to test.The point when testing a logical unit is not how much work is done inside it, but that it provides the appropriate outputs for all of its possible inputs.If you add more code (static or not), you just need to add more unit tests.
Jason Williams
Rbarry: I'd say he is more of an OO bigot than a Ruby bigot, and his post *was* labeled as a rant :)
Peter Recore
He's got a three-part series and people seem to be treating his off-hand uninformed opinions as cutting-edge insight into the future of testing and Design. (witness the multiple questions on SO about them). I say Ruby-bigot because he insists that [Math.]Abs(X) is wrong and that "Ruby got it right" with X.Abs(). (I think we should have both...)
RBarryYoung
+1  A: 

I use static utility classes all the time in my code for methods that are called quite often but would be a pain to instanciate. An example would be a simple logging class like:

public static class Logging
{
  public static UpdateAction(int id, object data)
  {
     SqlConnection connection = new SqlConnection("conn string from config file");
     // more logic here...
  }
}

Now, in no way do I ever have those classes and methods store any sort of global state since that can lead to huge concurrancy issues and in general is just bad design.

So don't avoid static classes, just avoid having those static classes keep some kind of global state.

Joshua
+1  A: 

Does it mean "Use of static classes is wrong" (in which case the article is incorrect) or "Static classes are often found in badly written code" (in which case it's not saying that static classes in themselves are bad, but that they are sometimes used incorrectly)

Static functions are more efficient than non-static because you don't need to create an instance of an object to use them or pass a 'this' pointer into method calls.

Use of static classes to hold global variables is a different matter - in which case the underlying rule is not that "statics are bad", but "globals are bad".

Jason Williams
+5  A: 

The abuse of static classes can be considered bad practice. But so can the abuse of any language feature.

I make no distinction between a non-static class with only static methods and a static class. They are effectively the same thing, except that static classes allow the compiler to enforce the developers intent (no instantiating this class, convenient syntax for accessing its functionality, etc).

As you say, a proliferation of "Helper" classes can get you into trouble (design, maintainability, readability, discoverability, other-abilities...). No argument here. But can you argue that a "Helper" class is never appropriate? I doubt it.

Indeed, responsible use of static classes can have great benefits to your code:

  • The Enumerable static class provides a set of extension methods most of us have come to love. They are a logical set of functionality / business logic that isn't related a instance of any particular type.
  • Services provided by the environment/context: eg Logging, Configuration (sometimes)
  • Others (that I can't think of at the moment :))

So no, in general its not bad practice. Just use them wisely...

Nader Shirazie