One of the most charming aspects of COM is the way that the QueryInterface mechanism makes it a very simple matter to add support for new features to a COM object. All you have to do is implement the interface that describes the new behavior. For instance, let's imagine that we have a musician object that supports the interface ISopranoSaxophone (methods: DoTwiddlyKennyGStuff and DoImpenetrableEvanParkerStuff), and that we're putting together an ensemble of objects to play Anton Bruckner's Symphony No 0 in D minor (yes, it does exist – the man was clearly a C programmer in his spare time). Unfortunately, there isn't a soprano saxophone part to play, so we're going to have to make our object a multi-instrumentalist. This is nice and easy: all we have to do is make it implement a new interface – say, ITrombone (methods: DoComicalUpAndDownSlide , DoComicalWaaWaaEffect and PlayVeryLoudRaspingNoise ). So much for the Royal College of Music.
The trouble with ensembles, though, is that, generally speaking, you need some sort of control on where the music's going. Otherwise you end up with something like the spontaneous music ensemble that I used to play in at college. I played in that because no-one else would have me (as, I suspect, did most of the others in the group), and the results were uniformly terrible. So how can we add a degree of control to our musician objects?
I suggest that the neatest way to do this is to define a standard interface that everyone coming into the band has to implement. Let's call it IEnsemblePlayer , and give it some methods:
TurnUpForRehearsals (int nTimesAWeek)
WatchConductor ()
DontDrinkTooMuchInTheInterval (int nPints)
(Go on, add a few more if you want.)
If we like, we can make a rule that any musician objects turning up for the gig that don't implement the IEnsemblePlayer interface get thrown out of the band (like, uh, musical differences, man). Trouble is, we have a slight problem of discovery here. How do we find out if we haven't got any maverick musician objects in our ensemble that we don't know about? We have to offer some sort of incentive to our objects so that they declare themselves to us. I suggest that the best way to do this is to implement an interface ourselves, say IManagement . This would have the following methods:
Register (IEnsemblePlayer *pPlayer, int bankAccountNumber)
So, our aspiring musician comes along to us, and obtains a pointer to our IManagement interface, perhaps using some sort of helper function (let's call it CoGetSvengali ). Having done this, he or she invokes the Register method, which passes a pointer to the musician's IEnsemblePlayer , plus – more importantly from the musician's point of view – their bank account number. This means that the musician can only get paid if he or she gives us access to their IEnsemblePlayer interface – in other words, if we have control of them as an ensemble player. (In my first version of this, incidentally, the musician objects passed a pointer to their IUnknown interface, but seeing as the parameter was therefore called punk , I felt that this might lead to some confusion over musical direction.)
You could be forgiven for wondering what relevance this has to real life. It's like this. In a large distributed-object-based network, the last thing that the operations department wants is to have lots of unregulated objects running around, consuming resources. There are basically two ways around this. On the one hand, there's the police state approach, which says that no object will be allowed onto the network until it has been rigorously tested by the Quality Assurance Police. For some reason, this has tremendous appeal to QA departments, but it can frequently result in developments being held up, which in turn results in the procedures being bypassed for just one special case, followed by the whole system breaking down. Alternatively, you might want to consider defining a control interface, analogous to the IEnsemblePlayer one presented above, that enables a monitoring program to keep tabs on what's going on in the network. The precise nature of the interface depends on the nature of the applications running on the network, but it might range from a simple requirement to respond to a “Ping”, up to reporting information on outstanding reference counts. My book, “Professional DCOM Application Development” looks at how to integrate the use of a simple IPing interface into a management, monitoring and control framework, with Microsoft's Management and Monitoring Console (MMC) as a front-end.
The flipside of this is that, as in the musician example, you're going to have to offer some kind of incentives to make it worth the component developers' while bothering to implement your interface. Perhaps you could help them by gathering usage statistics, or billing information, or some other common function that is too tedious for them to implement themselves. In the example in my book, I offer centralized error logging and management.
In the end, COM might just be the tool that finally makes operations and development work as a team. Maybe we'll all end up making beautiful music together.
© Jonathan M. Pinnock, 1998
This article previously appeared on FatBrain.com, although it seems to have disappeared from there now ...