All great concepts in programming are fundamentally simple. However, in order to keep programmers like ourselves gainfully employed, we surround our subject with an air of mystery, magic and voodoo. Unfortunately, this more often than not results in us confusing ourselves as well. I've lost count of the number of programming disciplines that I've viewed with awe from afar, only to find out on close inspection that there wasn't that much to them really. Once you're past this nirvana moment, of course, you're into clear water and you can get on with applying your years of hard-learned expertise, notch up yet another buzzword on your CV and up that all-important daily rate. Ker-ching, ker-ching!
Of all the disciplines I've looked at, however, I have to confess that COM took me the longest to get to grips with, and I suspect that I'm not the only one. So is it any different? Is it really so elusive? Is there any short cut to that nirvana moment?
In this article, I'm going to try and find out.
The Point of COM
Before we look at any techie stuff, we need to think about why we might need COM. I'll start by proposing what I think is the most important thing about COM:
COM is about Teamwork
Why do I say this?
Whilst we would like to think that the only way to get things done is to do it all yourself, most software projects involve more than one programmer. This means that the success of most software projects depends on programmers communicating well with each other. Unfortunately, most of us are – as per stereotype – nerdy types with poor social skills and possibly one or two personal hygiene problems to boot. If you don't subscribe to this view, take a look at our pictures on the covers of Wrox books (bigger than ever these days), and ask yourself: are these people that you would like to spend time with? Of course you wouldn't. Actually, we wouldn't want to spend much time with you, either …
So how do we ensure that all the bits written by the different members of the team fit together, if they're not going to talk to each other in a meaningful way? We have to define formal interfaces between the different parts of the system, and we have to respect those interfaces. More than that, those interfaces must be language-independent, because the front-end people are using VBScript and ASP and the internals team are all hard-core C++ heads. Once those interfaces are defined, then the work on either side can go on completely independently, and no-one needs to talk to each other unless they really want to.
So we're talking about lots of little self-contained pieces of software – let's call them components – with rigidly defined interfaces that are their only means of interaction with the rest of the world. This looks like the beginnings of a definition of an object to me. And in that case, the particular property that we're looking for is encapsulation – the complete and absolute separation of interface and implementation.
But what does a COM object actually look like? In order to build up a mental picture of one, I think we need to take a step to one side.
All the World's a Stage …
So for the time being, let's leave software development and enter another world: one populated by tears, tantrums and prima donnas (so not too far away from software development, then – after all, actors are basically nerds with better looks). Let's imagine that, instead of developing a complex piece of software, we're putting on a production of a play. And, yes, even this web site has been touched by the influence of Shakespeare in Love …
At our disposal are a number of actors, who are required to interact with each other in a co-ordinated and meaningful manner. For instance, there's the male lead. He's playing a part called Romeo. In fact, as far as the play is concerned, he is Romeo. Because everything he does or says is defined by the part he is playing. Inside, of course, he's just Joe Schmoe, jobbing actor, coping with everyday problems like the rest of us, but he keeps that to himself – most of the time.
Now a play doesn't just come together like that. There's a whole development process involved. Actors need to rehearse their lines, both ensemble and individually. If our Juliet, for example, is having a particular problem with her balcony, our director might arrange for her to have some one-to-one coaching. In this case, the part of Romeo might be filled in by the coach himself (or herself). That way, we don't need to get Romeo involved (probably a good thing, as they don't get on too well, and it's best to keep them apart as far as possible).
Actually, shortly before the first night, our Romeo has a screaming tantrum and walks out, and we have to find a replacement. The obvious answer is to promote one of the minor players, but the question is who? Rather curiously, none of them has a proper CV with them, and it's quite by chance that when we ask the actor playing the part of Sampson (servant to Capulet), he replies that actually he's done it before, and knows the part off by heart. With a bit of juggling around and a few quick changes, he can just about get away with playing both parts. After frantic last-minute negotiations about payment details, the show is saved.
Well almost. The first night is a great success. Unfortunately, Sampson/Romeo lets his new-found fame go to his head, and ends up hospitalised after the first night party. No-one else from the cast knows the part of Romeo, so once again the production is headed for disaster. However, one of the stage hands has an idea. If we could fit one of the actors with an earpiece, someone sitting off stage could dictate the part to him over a radio link. It might just work …
What's This Got to do With COM?
I'll leave the production at that cliff-hanger point, because it's time we got back to COM. So, as Jennifer Aniston said, here comes the science bit …
In the above analogy, our actors represent COM objects. As far as the overall development is concerned, it doesn't matter what goes on inside them as long as they expose certain interfaces. For instance, as we saw above, the standard interface IRomeo (as defined by William Shakespeare himself) can be exposed by a number of different COM objects (including Juliet's coach). Note, however, that the interface is completely separate from the actual implementation: this is the principle of encapsulation.
As well as standard interfaces, our COM objects can expose other more specialised interfaces – such as the ITemperamentalJoeSchmoe interface implemented by our original Romeo. Our objects can also expose more than one standard interface – witness our object that exposes both ISampson and IRomeo. The interesting thing, however, is that we can't just ask our objects to publish their CV – or, rather, the list of interfaces that they expose. However, all COM interfaces ultimately derive from the fundamental IUnknown interface (as in “unknown actor” – no, not really). This interface includes the method QueryInterface, which is probably the most commonly-used method in the whole of COM. We can use this to get a reference to any other interface that the object exposes. When we asked our Sampson actor if he did Romeo as well, we did a QueryInterface on his ISampson interface, and got a reference to his IRomeo interface; of course, if he didn't do Romeo, we'd get an E_NOINTERFACE response for our pains. Now, having done that, we're now holding references to two of his interfaces, ISampson and IRomeo , so we must remember to release him from both of them at the end of the play's run.
Now what about the disaster facing our company after the first night? Well, here we see DCOM, or distributed COM, in action. Our on-stage Romeo is, of course, a complete imposter. In COM terms, we'd refer to him as a Proxy . He's merely the local representation of the IRomeo interface, but all he's really doing is spouting whatever he's told to do so over the radio link. The real work is being done at the other end, by the Stub holding a dog-eared copy of the script and a microphone. But the audience aren't any the wiser (it's not that good a production).
So how did it work out? Well, everything went fine, until Act 2, Scene 2 when the link started to break up, and Juliet's query of “Wherefore art thou , Romeo?”, alas, went unheeded. Romeo spent the rest of the scene shuffling around and looking embarrassed. In DCOM, you're always at the mercy of the network.
The Very Basics of COM – A Summary
What have we learnt?
- COM objects are small pieces of self-contained software that interact with the rest of the world by exposing one or more well-defined language-independent interfaces.
- These interfaces are completely separate from their implementations.
- The interfaces can be standard ones that other objects also expose, or they can be special ones that are particular to that object.
- All these interfaces are ultimately derived from IUnknown, and therefore include its methods.
- One of IUnknown's methods is QueryInterface, which is used for obtaining a reference to one of the other interfaces that the object exposes.
- With DCOM, you can access objects over a network without making any changes to the rest of the system.
So now you know more about COM than you can count on the fingers of one hand, which isn't bad for a start.
© Jonathan M. Pinnock, 1999
This article previously appeared on COMdeveloper.com, which has now sadly disappeared off the face of the planet.