Last fall I wrote a new class library to handle Inmagic Webpublisher XML API calls with elegance and grace. That was the motivation anyway. One might well grasp the wind with chopsticks.
Each XML request type (query, insert, update, etc.) has some mandatory elements (e.g. textbase) and some optional elements (e.g. sort fields), so I used the Decorator Pattern to attach optional bits. The pattern provided the solution I was looking for, but threw me roughly into the world of OOP inheritance and polymorphism, where I felt at every turn like a man lost in a thorny thorn field without his pants.
I just found a way to remove a particularly sharp and prickly thorn.
The problem - Unable to access properties specific to a derived class
Consider this snippet of code:
It's classic Decorator. The query object is at all times an XmlInput (the base class) type. You can pass it in to multiple decorators, and because it was instantiated as an XmlQuery, a class that derives from XmlInput, it gets some special XmlQuery-specific behaviour too (e.g. commandQuery, page, mr).
Trouble is, because the query object must be passed to decorators as XmlInput, there is no way to access the XmlQuery-specific public members:
One consequence of this for me was that the derived classes such as XmlQuery had to jam every conceivable property into the constructor as a parameter, because they couldn't be set after the object was initialized. Not so bad with XmlQuery, as it happens, but a nightmare with XmlBatchModify which has many many properties:
Clearly something had to be done.
The fix? - Casting derived classes to base classes
I can go with the XmlQuery derived class from the get-go, set public properties after the constructor is called, and then cast the query object to the XmlInput base class before passing it to a decorator:
This works: properties specific to XmlQuery are not lost. I'm just not sure that it's entirely legal, or what consequences it may have in the long run.