I’m sure this is going to be a contentious one. I don’t have a good story about this one, so I’m just going to go right to the sin.
Sin #3 – Overuse of Virtual
There are two schools of thought when it comes to virtual. They are:
- Always use virtual
- Only use virtual when absolutely necessary
The first group’s argument is that original designer of a class is a poor judge of how the class might ultimately be used. Making all methods virtual allows the users of the class to easily extend/modify the behavior. Non-virtual methods make more work for the user.
(or that’s the argument I’ve heard – please comment if there’s something I missed…)
The argument is true. Virtual does make extensibility easier. The problem with virtual is robustness.
The original designer of a class has a good idea for what the class is about, and the implementation is designed (either explicitly through the tests written with TDD, or more implicitly through the mind of the designer) to support that idea (or contract, if you prefer).
In other words, the designer has an explicit idea about what extension points he wants to support in the class. If virtual is only on those points, then the designer has (or should have) done sufficient testing on those points, and it’s pretty likely that users who extend through those points get the behavior they want. And since only a few methods are virtual, the fact that a specific method is virtual is an important clue to the user that that method *is* an expected extension point.
If virtual is on every method, the user can extend in a lot of ways, but it’s very unlikely that the designer thought of all those ways – or all combinations of those ways – which means that such a user extension is going into uncharted territory. Maybe it doesn’t work when you try it. Maybe it works now, but breaks with the first update when the object behavior changes.
I prefer the “you can only do these 2 things, but I promise that they work” classes to the “you can do any of these 12 things, but they may or may not work” classes.