Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I submitted an application I wrote to some other architects for code review. One of them almost immediately wrote me back and said "Don't use "static". You can't write automated tests with static classes and methods. "Static" is to be avoided."

I checked and fully 1/4 of my classes are marked "static". I use static when I am not going to create an instance of a class because the class is a single global class used throughout the code.

He went on to mention something involving mocking, IOC/DI techniques that can't be used with static code. He says it is unfortunate when 3rd party libraries are static because of their un-testability.

Is this other architect correct?

update: here is an example:

APIManager - this class keeps dictionaries of 3rd party APIs I am calling along with the next allowed time. It enforces API usage limits that a lot of 3rd parties have in their terms of service. I use it anywhere I am calling a 3rd party service by calling Thread.Sleep(APIManager.GetWait("ProviderXYZ")); before making the call. Everything in here is thread safe and it works great with the TPL in C#.

share|improve this question

migrated from stackoverflow.com Aug 17 '12 at 2:24

This question came from our site for professional and enthusiast programmers.

18  
static is fine; static fields need to be treated very carefully –  Marc Gravell Aug 13 '12 at 22:00
1  
@Артём fields are class-level variables; static fields are class-level variables that are per-type rather than per-instance –  Marc Gravell Aug 13 '12 at 22:03
1  
That particular objection is bit too general for me. In most cases you wouldn't mocj the static class, you'd mock the arguments. Static field where it was an aggregate class which needed mocking, then yes. –  Tony Hopkinson Aug 13 '12 at 22:12
3  
Clearly your colleagues have a serious condition - an acute systemic OOPus erythematosus. They need a treatment ASAP! –  SK-logic Aug 17 '12 at 7:31
2  
There's an answers section for providing answers, I don't understand why people comment in an attempt to give someone an answer/suggestion... It defeats the purpose of the StackExchange, surely a comment would be to request more information. –  peteski22 Sep 11 '12 at 9:35
show 9 more comments

9 Answers

It depends on whether the static classes maintain state or not. Personally, I have no problem with stateless functions thrown together in a static class.

share|improve this answer
60  
Correct. Static functions which have no side effects are the most testable functions of all. –  Robert Harvey Aug 13 '12 at 21:58
4  
+1 to that, but with a safety clause: Almost every abstract algorithm is stateless, but that does not mean you should implement it as stateless static class or method. Implementing it in such way causes all the code using it to be hardly-linked to it. This means for example that if you implement sorting algorithm as a static method and thn use it through the project - that you cannot temporarily replace the sorting to another algorithm i.e. for testing purposes and for narrowing the problem area. This a huge hindrance in many cases. Aside of that, static is totally OK if used reasonably. –  quetzalcoatl Aug 14 '12 at 1:36
5  
In short: they are the most testable functions, but not necesarilly they make the other code more testable! This is what the architect meant probably. –  quetzalcoatl Aug 14 '12 at 1:37
2  
@tereško: The C# language requires static methods to be part of a static class, if you don't want to have to create an instance of the class to call the method. Perhaps you mean "instance," and not "class." –  Robert Harvey Aug 14 '12 at 15:06
3  
@quetzalcoatl: It's perfectly legal to pass a delegate (i.e. a different algorithm) to a static method; the extension methods in Linq are all static methods. Example: msdn.microsoft.com/en-us/library/… –  Robert Harvey Aug 14 '12 at 15:09
show 3 more comments

He is too general about it. He is correct, it hinders testing. However, static classes and methods have their place and it really depends on the context. Without code examples you can't really tell.

I use static when I am not going to create an instance of a class because the class is a single global class used throughout the code.

This can be severe code smell. What are you using the classes for? To hold data? To access a database? Then he is correct. You should look in to dependency injection in that case, as such a static class is effectively an implicit singleton.

If you are using them for extension methods or helpers that don't change the state and just operate on the parameters you provide, those usually are fine.

share|improve this answer
3  
+1 for mentioning that the statement was to general and mentioning extension methods, which also can be tested and dependencies can still be mocked as far as I know. –  François Wahl Aug 13 '12 at 22:02
2  
Aye static as single class instance as an implicit singleton, that's going to get messy.... –  Tony Hopkinson Aug 13 '12 at 22:16
add comment

I checked and fully 1/4 of my classes are marked "static". I use static when I am not going to create an instance of a class because the class is a single global class used throughout the code.

The best thing to do is to try and unit-test your code. Try designing tests that are repeatable, independent, simple and test only one method at a time. Try running your tests in different randomised order. Can you get stable "green" build?

If yes, that's a valid point to defend your code. If, however, you have difficulties, then maybe you should go for instance-based methods.

share|improve this answer
3  
This is the point that struck me too. A few static and stateless 'helper' style classes are fine, but if you've got a full 25% of all your classes as static, it's unlikely that your efforts are limited to that case. –  Matthew Scharley Aug 14 '12 at 0:57
add comment

One of the advantages that you get from IoC/DI is that most interactions between classes are negotiated between interfaces. This makes unit testing easy because the interfaces can be mocked automatically or semi-automatically, and therefore each of the parts can be tested for inputs and outputs. Furthermore, beyond testabilty, putting interfaces between everything allows you to have the most modular code possible -- you can easily replace one implementation without quite so much worry that you're screwing up dependencies.

Because C# doesn't have metaclasses, a class can't implement an interface using static features, so static features of classes end screw up any effort to implement a pure IoC/DI object model. That is to say, you can't create a mock to test them, and you have to create real dependencies.

If your company/project is invested heavily in doing IoC, this of course is a reasonable concern, and the pain you're going through is for the gain of all. From an architectural standpoint, however, I personally don't think that any model should be followed to the grave. There are some things that make sense to implement using static methods -- the singleton design strategy, for instance. I'm less inclined towards static classes myself because I think they tend to start to lose the advantages of OO, but there are times when a library class is probably a more natural expression of something than an engine.


Commenter reminds me of extension methods, which of course have to be in static classes in C#. That's legit, and is an example of how pure IoC doesn't work super well in C#, at least if you're trying to take advantage of the breadth of the language.

share|improve this answer
    
If a class is made static for the right reasons and correctly implemented such as for example extension methods they are still testable very much as they would have no external dependencies and are self-contained and as such should not require mocking. Should the need for an interface not be driven by the design requirement to best full-fill a business requirement not for the sake of keeping a pure IoC/DI project? –  François Wahl Aug 13 '12 at 22:12
1  
You and I agree on the general point that you should choose the right tool for the right job and not be handcuffed by philosophy. If, however, there is a well established culture in place in your project of pure IoC/DI, it'll hurt just as much as converting a traditionally top-down solution to IoC/DI. Engineering needs to consider the transitional costs. By the by, I don't think extension methods quite get you there. I think a better solution for IoCish behavior with static classes would be to have multiple classes chosen between at compile time with preprocessor directives, C style –  jwrush Aug 13 '12 at 23:43
1  
Er. I'm dumb. You meant a static class for HOLDING extension methods, which, of course, is how you have to do them. Yes, of course, you want a static class for that purpose. That slipped my mind: and this goes to show that C# was not intended for IoC. :) –  jwrush Aug 13 '12 at 23:46
    
Yes, you are right, if an existing culture in an existing project exists it would be more damaging than helping to change the way things are done. –  François Wahl Aug 13 '12 at 23:58
add comment

Static classes are sometimes misused and should be:

- a singleton
- a single time created object (same as singleton, but not accessable anywhere). 
  use a class variable or function argument for access/passing it.
- a method in another class

It also might be a so called 'utility' function, and part of a utility class. Utility classes are classes that contain only static methods and serve as helper functions without any context.

share|improve this answer
add comment

Static methods are fine to use and have a rightful place in programming. It sounds like your architect has a testing framework that does not fully support static methods. If your code is part of a bigger project, then it is important to meet the architects guidelines. However, don't let this project deter you from using static methods when it is appropriate to do so.

share|improve this answer
add comment

I have been using static properties for things that are common to all instances of a class. And I have been using static methods to get groups of class objects. I am by no means an expert but this has been working for me so far.

PHP example:

class vendorData {
  private static $data_table = 'vendor_data'; // static property
  private $id; // instance property
  private $name; // instance property

  public function __construct($vendor_id) {
    if(!self::validId($vendor_id) ) { // static method
      return false; // id doesn't exist
    }
    $this->id = $vendor_id; // id has been validated
    $this->getProperties(); // object method
  }

  private static function validId($vendor_id) {
    // send db query to find if the id exists
    // return true/false;
  }

  private function getProperties() { // object method
    $sql = "SELECT * FROM `{self::$data_table}` // using static property
        WHERE `id` = {$this->id}"; // using object instance property
    // get resultset
    foreach($result as $property => $value) {
      $this->$property = $value; // object instance properties all set
    }
  }

  // and here
  public static function getBy($property,$value) { // static method to return object array
    $sql = "SELECT `id` FROM `{self::$data_table}` // using static property
      WHERE `$property` = '$value'";
    // send query, get $ids array
    $obj_array = array();
    foreach($ids as $id) {
      // create array of current class objects using special static keyword
      // meaning of static here is different than in property/method declarations
      $obj_array[$id] = new static($id);
    }
    return $obj_array;
  }
}
share|improve this answer
add comment

I'll say the principles they have are ok but the statement (don't use statics) may be wrong. How much is your code coverage? if the number is high and you are comfortable with the unit testing of your app, then you are ok. If not, then I would suggest review the code. You may find static classes are the reason or not, it will depend on a lot of things.

share|improve this answer
add comment

The answers already posted cover a lot of really good points, but there is one that seems to be missing:

Static fields are never garbage collected.

This is really important if you have an app with a lot of memory constraints, and this pattern can be very common when people try to implement a cache.

Static functions are not nearly as bad, but everyone else has covered this in enough detail already.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.