Why not Make Every Method Virtual?

In an effort to make my blog suck less, I figured I’d post my response to Ward Bells Do not Make Every Method Virtual. He carries on the discussion of whether or not .NET methods should be made virtual by default, as they are in Java. You should read his post before mine, as this will establish the context of everything that follows (and if you don’t already subscribe to his blog,  be sure to add it – you’ve been missing out on a lot of good stuff).

All done? Ok, I’ll continue.

Reviewing case against default virtual methods

Unwanted Extension Points

Wards "elevator" example demonstrates that we should not make all methods virtual, since it exposes extension points where we do not want them. Let’s have a look at the reason this particular extension point is not wanted.

The elevator.Up() method has responsibilities for moving the elevator up and  closing doors etc. These responsibilities need to be chained in the right order to function safely; we do not wish client code to break the desired behaviour by inadvertently calling Up() at the wrong time.

This seems to highlight a smell that the single responsibility principle is not being adhered to in the elevator class. Since this issue is cause by incorrect ordering of multiple responsibilities. By adhering to SRP, separating out the different behaviours from the responsibility of coordinating them, we can avoid this conflict. We can then keep this method as virtual, and benefit from an additional extension hook safely.

Explicit Contracts

Paraphrasing another point made (I hope Ward will correct me if this is a misrepresentation) is that we may want to be very explicit about the points in which an application can be extended. Marking a method as virtual is a way of explicitly showing your "approved" extension hook.

Arguably, I prefer to see my "extension hooks" more explicitly than a virtual method. As an application developer looking for a "seam" to extend, I would favour seeing an interface that I can implement, over inheriting from a class and overriding it’s virtual methods. This is mainly because to interfaces tend to be more discoverable than virtual methods.

Open/Closed Principle

Lastly, I have a different perspective on the OCP. I believe "closed for modification" to be in reference to the actual LOC contained in the class rather than "closing off" modifications to behaviour. I agree however, that making all methods virtual does open up a greater susceptibility to the violation of LSP.

Summary

The arguments made against methods being virtual as default mostly seem to fit under the umbrella of protecting yourself against unwitting developers. I think there are safer ways to do this whilst still obtaining the flexibility provided when all methods are virtual by default.

Advertisements

About craigcav

Craig Cavalier works as a Software Developer for Liquid Frameworks in Houston Tx, developing field ticketing and job management solutions for industrial field service companies.

Posted on August 16, 2009, in Uncategorized and tagged , . Bookmark the permalink. 3 Comments.

  1. “The arguments made against methods being virtual as default mostly seem to fit under the umbrella of protecting yourself against unwitting developers.”

    Not a very compelling argument as you could make similar case for having all class constituents public instead of encapsulating via private, protected or internal modifiers, or perhaps using goto’s over formal control flow constructs such as for loops and if statements. While you may gain flexibility you’ll likely feel more pain with added complexity you open up. After all if you’re not going to need those extra extensibility points why go to the effort of adding them?

    As the linked article says for anything more than a trivial standalone application you are really just giving yourself more rope for you (or others) to hang yourself with.

  2. Thanks for your input Lex.

    A few thoughts:

    “you could make similar case for having all class constituents public instead of encapsulating via private, protected or internal modifiers, or perhaps using goto’s over formal control flow constructs such as for loops and if statements”

    I agree the summary of the argument is not compelling in itself; it needs to be taken in the context of the rest of the post (Unwanted Extension Points, Explicit Contracts, Open/Closed Principle). In this context, I am failing to see the parallels with having all class constituents public etc.

  1. Pingback: DotNetBurner - C#

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: