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?
问题:
回答1:
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...
回答2:
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".
回答3:
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.
回答4:
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'.
回答5:
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
回答6:
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.
回答7:
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.