Is Inheritance Overrated?
Like many VB programmers, I'm only marginally familiar with implementation inheritance. Oh, sure, I understand it in theory -- I've read all the standard primers ("A dog and a cat are both animals, but they speak differently...") -- but I have yet to use it in a real application. So I was enthusiastic when it looked like my current application, a content management system written in ASP.NET, would provide an ideal opportunity to get my feet wet with implementation inheritance.
The app deals with content objects which are displayed within placeholders in page templates. When a page is requested, the system retrieves the relevant content from the database, binds the data to a user control, then inserts the user control into a placeholder on the page. There are several types of content: home page lead, home page non-lead, feature article, product review, etc. As I designed the various content objects, it occurred to me that they shared certain features in common: they all, for example, had a title, description and publication date; all home page items had a URL to which they linked; all article types had an author and one or more pages. They all needed to know how to load themselves from and save themselves to the database. So, I thought, why not create a base ContentItem class containing the shared properties and methods, and inherit the more specific types from this base class?
In my initial proof-of-concept, that's exactly what I did. Specific content types inherited from a base ContentItem class; when they were serialized to the database, they looked like this. Everything worked as expected; this inheritance stuff was a piece of cake!
As I started to flesh out the prototype, however, it became apparent that my design was pretty maintenance-intensive. Each new content type required me to create two user controls and associated code-behind classes: one of each to load/edit/save the content, and another to display it on a page. Although the new classes could inherit common functionality from my ContentItem and ContentDisplay base classes, I'd still have to create, test and debug them. In addition, the XML stored in the database was version-specific: If I later changed the design of a class, it wouldn't know how to deserialize data saved by an earlier version of the class.
One way to reduce the maintenance burden, I thought, would be to create a generic edit form: The form's code could read its layout from an XML file and dynamically create the necessary controls. That was simple enough (I'll write about it in a future article); the hard part was figuring out what to do when the user clicked the 'Save' button: I'd still have to create an instance of the correct content class and manually assign the form's field values to the associated class properties. Nor did this approach do anything to reduce my class development burden, or avoid the version-specific nature of the serialized XML.
Finally, I concluded that inheritance was not a good fit for this application; it was simply more trouble than it was worth. I refactored the design to use a generic content object, which consists of a simple collection of items. My generic edit form could save itself by simply looping through its controls and adding a name-value pair to the content object's Items collection. I'd no longer have to create new classes for each new content type, and the serialized XML would no longer be version-specific: the content object would neither know nor care what items it contained. To add a new content type, all I'd have to do is create a simple form definition file, and a user control to display the content.
Is it just me, or is this a well-known downside of implementation inheritance? Does inheritance work best in cases where the object model is relatively static? Or are there ways to efficiently handle situations like this one, and I just don't know them yet?
MiscTalk to Me