ChrisAn's Blog Please read my disclaimer.

simplegeek

a.k.a. Chris Anderson

Sealed defended...

Chris: The attitude that you should open up classes for derivation "just in case" someone wants to derive from it is a great philosophy if the only cost you consider is the development. Once you allow for derivation you must test the derivation, document it, version it, etc. Basically you should only ship non-sealed classes if you have considered the ramifications of someone deriving from it.

The counter argument to this goes something like: "If you only have public and private members, then sealing or not has no impact on the class". Since there are no protected members (or virtuals) then it is perfectly safe to allow derivation. I have to agree with this logic. But, this also meets my requirement that you have considered the ramifications of somone deriving from it.

I had this debate around the Graphics class for WinForms. There was a customer request to derive from Graphics to customize it. Since the Graphics class is actually a thin wrapper on a GDI+ device context, we felt it didn't make sense. In fact it would lead to more confusion because you would try to derive from the class in hopes of customizing the behavior (for example, to do custom image rendering), however it wouldn't work. The only thing you could do would be to add methods that called other already existing methods on the graphics object. In addition, since we don't support factory methods to create the new Graphics object, you would always have to wrap the default graphics object with your custom one, leading to code like:

protected override void OnPaint(PaintEventArgs e) {
    MyGraphics g = new MyGraphics(e.Graphics);
    g.DrawSomethingCool(...);
    base.OnPaint(e);
}

instead of:

protected override void OnPaint(PaintEventArgs e) {
    MyGraphics.DrawSomethingCool(e.Graphics, ...);
    base.OnPaint(e);
}

Sure, the advantage to the first code is that you can pass your "MyGraphics" instace to other functions. However, since there are no virtuals or protected members, then you can't customize the behavior of any of these callers. Really all you are getting is being able to pass some extra context around. Oddly, only you (the provider of the extended class) will ever be able to down cast and access the new functionality - which you could always do without the derivation.

Basically, non-sealed classes that aren't well designed introduce a higher testing burden for negative developer benefit (confusion, complexity, etc.). In a perfect world we would have enough time to design all APIs for derivation, but sometimes we have to ship.

 

01/23/2003 10:07 PM | #Software

Content © 2003 Chris Anderson | Subscribe to my RSS feed.

Powered by BlogX