28

SOLID includes the Liskov substitution princicple which has the notion that “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program”.

Since static classes with static methods (a bit like the Math class) does not have instances at all, is my system considered SOLID if I have static classes with static methods?

gnat
  • 21,442
  • 29
  • 112
  • 288
Pacerier
  • 4,973
  • 7
  • 39
  • 58
  • 1
    I think this question is great. Let's see what the community has to offer. – Saeed Neamati Aug 15 '11 at 05:54
  • 1
    A Math class does not include state. So you are never really passing objects of this type around. So I am not sure how this is even relevant. – Martin York Aug 15 '11 at 06:01
  • I don't think static classes really could be said to be pure SOLID (much for some of the same reasons as already mentioned) however I would consider them to be a great advocate and tool for the DRY principle. – dreza Aug 15 '11 at 10:00
  • 2
    How so? From my experience, overuse of static classes mostly results in people repeating themselves all the time with half the code permanently manipulating one global static god object. – back2dos Aug 15 '11 at 10:14
  • 1
    I guess I'm thinking more in terms of utility classes to provide common code. I agree they are easily and often are mis-used but still think that the can provide usefull means to group together common code where state is not an issue – dreza Aug 15 '11 at 10:25
  • @dreza I used to agree that utility methods were best created as static methods on a static class. However, I've seen this cause enough difficult-to-refactor coupling that I now prefer regular classes that implement an interface and coding only to the interface. – RationalGeek Aug 15 '11 at 12:14
  • In C#, a static class can't be inherited or instantiated. I don't believe this question actually applies to *static* classes in C#. – Toby Aug 15 '11 at 14:09

3 Answers3

28

LSP applies to passing an instance of a class into a method, having the method do some stuff with that instance, and often produce some sort of result. This doesn't matter for static classes since in C# you cannot create an instance of a static class.

Even more importantly, static classes are sealed and therefore cannot be inherited. This makes your question moot far as C# goes.

You could say that static classes are always LSP-compliant since you cannot ever produce a subclass that would violate that principle. You could also say that static classes are never LSP-compliant for the same reason.


In Java, static classes are slightly different. You cannot mark a top-level class as "static", so if you want to create a utility class similar to C#'s static classes you have to declare it as final and hide its constructor. Once you do that, though, they behave similarly to C# - you cannot instantiate them or subclass them. You can declare an inner class as static, but that does not mean the same thing as it does in C#: it simply denotes a nested top-level class.

VB.NET behaves exactly the same way as C# in this case, far as I know.


You didn't mention whether you're interested in the other principles, but I'm going to include them anyway for completeness.

Single responsibility principle: a static class easily follow this principle.
Open/closed principle: since static classes are sealed, they cannot ever follow this principle.
Liskov substitution principle: as above.
Interface segregation principle: doesn't apply to a single class, but splitting one large static class into smaller, more specialized ones could be a step towards following this principle.
Dependency inversion principle: static classes cannot implement interfaces, so any class using it will always depend on whatever implementation exists at the time. Static classes therefore violate this principle.

Since static classes do not satisfy all 5 criteria, they are not SOLID.

Adam Lear
  • 31,939
  • 8
  • 101
  • 125
  • since to be SOLID means we have to satisfy all 5 criterias, doesn't that mean that they aren't SOLID ? – Pacerier Aug 15 '11 at 07:16
  • 1
    @Pacerier Yes, but one shouldn't try to shoehorn a class into SOLID all the time if it's not needed; it depends on the context of the class. If it's a utility class or something, it's okay IMO to not be "SOLID", but if it's an actual domain class that has specific domain usage... – Wayne Molina Aug 15 '11 at 12:16
5

I would not classify such a class as object-orientated and therefore I would say that it cannot (and should not try to) meet the principals of object-orientated design.

These classes are merely a workaround to the inability to provide code outside of a class in languages like Java and C#. If they could be, they should be defined as standalone functions since they do not gain any benefits from object-orientation.

Gyan aka Gary Buyn
  • 2,775
  • 19
  • 17
  • I would disagree with putting stand alone functions outside of the class. The simple ability to group related functions (static or not) under a common name is useful for readability. Mathematical functions fit the bill perfectly. – jojo Aug 16 '11 at 02:30
  • 2
    @jojo Agreed. Languages that support functions defined outside of classes also support logical grouping of these functions e.g. namespaces in C++. – Gyan aka Gary Buyn Aug 16 '11 at 03:12
2

It's worth mentioning, since you specified no language, that in C++ you can pass classes around which have only static members and access those members via template, and therefore it is possible to substitute for a class with only static members, and arguably, the methods called form it's "interface".

DeadMG
  • 36,794
  • 8
  • 70
  • 139
  • vb.net / c# / java – Pacerier Aug 15 '11 at 10:28
  • You can have functions without classes on the global, known as free functions.. this is where C# had to implement static in C# 1 as VB had globals which resulted in lots of frustration. So C# focuses on OOP.. static classes are not OOP – Piotr Kula Nov 20 '20 at 13:24