And COM enforces lifecycle rules, transparent remoting, uniform activation (constructors basically), security primitives, marshalling, transparent async calls (yes, you can call any method asynchronously), and a ton of other things. It's actually very good and it's a shame most don't know about it and most of the rest sneer at it.
I agree!
(Though you cannot call just any method asynchronously; the interface's IDL needs specific annotations and the underlying object needs to implement ICallFactory.)
Well said.
COM was one of the best realizations of "Component-based Software Engineering" and Brad Cox's "Software-IC" model. It was a binary standard and so components could be written in any language and yet be assured of perfect interoperability provided you followed all the rules/conventions. There was a bunch of boiler-plate for the framework itself but once you understood it, everything was smooth sailing in your language of choice.
One of the things i always advise people is not to focus only on the current way of doing things but to study older well-known libraries/frameworks/architectures/kernels/etc. to really understand "Software Engineering" from many perspectives. That is where insight comes from and real understanding happens.
For people interested in understanding COM, see the classic Essential COM by Don Box.
Which shows how many devs never learnt about Windows development past Windows XP, given that COM is nowadays the main API delivery mechanism, as they redid Longhorn ideas in C++.