Re: Part 2; COM issues

From: H. S. Lahman (h.lahman_at_verizon.net)
Date: 08/10/04


Date: Tue, 10 Aug 2004 19:03:13 GMT

Responding to Nicholls...

Basically I think we should agree to disagree over this. We are clearly
speaking past one another and that isn't going to get resolved without a
more concrete example. But I don't know enough about COM details to
provide a credible one to make my case and I am far too lazy to research
one. However, I think there are a couple of points that are still of
peripheral interest...

>>>>What happens when one decides to change the network protocol? There is
>>>>no way to do that without also touching the object with clock semantics
>>>>(CGMTClockService) in the application itself. In addition, one may have
>>>>to touch other problem solution objects (e.g., factories) that talk to
>>>>it. Regardless of how elegant the composition techniques are, that
>>>>still means there is risk of breaking something in the application
>>>>solution. Therefore one must functionally test the problem solution
>>>>itself completely even though theoretically it has not been touched.
>>>>
>>>
>>>
>>>no you don't, you just change the network protocol of your machine
>>>and/or your COM object registration, you don't touch any code.
>>
>>How does COM know whether to create a network proxy or not for a
>>particular class? Something has to be parameterized at create time;
>>there are too many possible optimizations. More to the point, I would
>>argue that the COM object registration is part of the object
>>implementation. If you touch it you potentially touch any behavior of
>>the object.
>
>
> If the configuration data is part of the object implementation then so
> is the infrastructure the operating system, the hardware, who's using
> it, where it is, is it 240V or 120V.

Not the same things. The COM configuration defines how the object
itself behaves. When I invoke an OS service that service belongs to
someone else and I am accessing it through an interface with a DbC
contract. Its implementation and behavior is quite independent from my
object that invokes the service.

However, the COM object combines both hidden infrastructure services and
problem semantics (getTime). It is that composition of behavior that I
have a problem with precisely because the object is monolithic and there
is no separation of implementation concerns.

>
> Do you consider the configuration data of an application to be part of
> it's implementation?
>
> The answer is surely no. It is not even the configuration data for the
> specific application, because this concern has, as you want, been
> completely seperated - I don't think you can have it both ways, it
> either is a seperate concern, in a seperate subsystem and not part of
> the implemention or it isn't.

Actually, I do. Because we emphasize encoding invariants while
relegating detailed differences to external data, we use configuration
data to incorporate business rules and policies that would otherwise
have to be encoded. The application could not execute satisfactorily
without that data so that data is just as much a part of the problem
solution implementation as the code.

>>>Yep I am defininately talking about a surogate to the point where the
>>>client code hasn't a clue whether it's talking to the real thing or a
>>>proxy.
>>
>>That's fine so long as it is an interface and doesn't implement any part
>>of the service. Then it is not part of the client; it is just an
>>interface to an external service. The fact that a networking service is
>>inserted in the middle between client and clock service becomes
>>transparent because all the client talks to is the same end of the pipe.
>>
>>However, my understanding of the COM infrastructure is that the
>>surrogate is not a simple external data transfer interface. Instead it
>>is a first class object on the client side that is transparently
>>provided with an implementation that allows it to communicate on an
>>object-to-object basis across the layer or distributed boundary (e.g.,
>>things like remote execution).
>
>
> I don't see the difference in these two.

The difference lies in where the implementation lives. An interface can
be implemented in another DLL. (Outgoing subsystem interfaces almost
invariably are.) The COM component is defined, configured and
implemented /within/ the subsystem when it also has local semantics
(i.e., a GetTime knowledge responsibility).

>
>
>>That isn't so bad per se -- so long as the surrogate is narrowly
>>defined. The problem lies in the fact that the object can have any
>>number of developer-assigned properties (including those of other COM
>>objects merged in via composition) besides those that COM provides to
>>make it interoperable across distributed boundaries. When that happens,
>>it becomes more than a Facade interface; it becomes an active element of
>>the problem solution. And there is no magic indicator to say which is
>>which because exactly the same mechanisms are employed to suck in
>>networking capability as for, say, list capability (e.g., composition
>>via MI or embedding other COM components).
>
>
> nope not with this, I can't see how it is anything more that a
> proxy/facade.

The main reason they are different is the one immediately above.
However, another spin on this lies in the nature of interfaces. An
implicit assumption I make about subsystem interfaces is that they are
pure message interfaces. Such interfaces need not be implemented with
objects or OOPLs; any handy buffer will do.

However, insofar as interoperability in concerned, COM doesn't make that
assumption. Instead its model is direct object-to-object collaboration
regardless of the distributed environment. That collaboration involves
things like remote execution of behaviors and synchronous access of
remote state data. All that has to be somehow emulated in manner that
preserves data and referential integrity across the distributed boundary.

That is just not possible for simple interfaces. One has to have a
concrete object implementation in the applications on /both/ sides of
the boundary. One can all them proxies, surrogates, smart Facades, or
whatever, but they are still first class objects that combine problem
solution semantics with intimate knowledge of networking in their
implementations.

>>>The most significant difference between the COM implementation and the
>>>.net one is in this context is the existence of completely stateless
>>>objects as described above, where each method invocation invisibly
>>>creates uses and destroys an object.
>>
>>That's the normal implementation?!? Yech! Clearly the designers had a
>>lot of faith in Moore's Law.
>
>
> there are two, statefull and stateless, and its a configuraion issue.
>
> I don't understand the relavance of Moore's Law.

I was referring here to creating/deleting a new instance for each method
invocation. Instantiation and deletion of objects are usually the most
expensive single behaviors associated with the object. And doing that
for an OS process like a network proxy would be orders of magnitude
worse. IOW, you need faith that by the time you get it working the
machines will be a lot faster. (Or that DB physical I/O will be such a
big bottleneck that nobody will notice.)

[A famous quote from one of the designers of X-Windows was that it was
designed for computers that didn't exist yet. Some would argue that
they still don't. B-)]

>>>>>>My problem with COM is that it makes it easier to build a new widget
>>>>>>than diagnose and modify an existing widget.
>>>>>
>>>>>
>>>>>Why?
>>>>
>>>>For context: I have an existing WA widget that is composed of {W1, W2,
>>>>W3} widgets. I encounter a new context where I could use WA except that
>>>>I need a new behavior for W2. Rather than modifying WA to deal with
>>>>both the new and old contexts, I can more easily construct WB {W1, W2',
>>>>W3} and use it in the new context.
>>>>
>>>>One reason it is easier is because of the tools, "canned"
>>>>infrastructures, etc. that come with an environment like .NET. But
>>>>another reason is simply that WA is too complicated to fix. One
>>>>contributing factor is that it is monolithic. In OO W1, W2, and W3
>>>>exist independently as manifestations of the problem space and they
>>>>collaborate directly on a peer-to-peer basis. IOW, there is no WA glue
>>>>to worry about that "hard-wires" a particular context in a hierarchical
>>>>manner. It is that hierarchical structure that tends to get in the way
>>>>of repair once one is out of the realm of "canned" infrastructures.
>>>>
>>>
>>>
>>>Again, what is COM like about this, which does not apply to C++ or
>>>java.
>>>
>>>WA is too complicated to fix - what has that to do with COM? if it's
>>>too complicated in COM, what makes in any less complex in any other
>>>context, i.e. the implication is that COM adds complexity in some
>>>manner that java or C++ wouldn't....how?
>>
>>My problem with COM is that a dominant paradigm seems to be composition,
>>which strongly encourages creating WAs and WBs. I argue that the OO
>>approach says: Don't Do That. Just because the OOPLs provide lots of
>>opportunities for beating oneself up-side the head with a hammer doesn't
>>mean one should pick up the hammer.
>
>
> but example 2 can be implemented in java, C++ or COM.

I sense another disconnect. I'm not sure what the 'or' means here.
When one is creating COM objects one is still coding in a 3GL (C++, C#,
VB, etc.). The COM infrastructure comes in through the language IDE or
via library MI.

>
> What mechanism in there in COM that is not in these others?

Again, the issue is not what one /can/ do; it's about what one /should/ do.

>>>>So there is a kind of Catch-22 here. It is easier to make WB than to
>>>>fix WA, but in an OO approach there wouldn't have been a WA in the first
>>>>place.
>>>
>>>
>>>I'm currently looking at this page in Google, it has text, buttons a
>>>scroll bar, they are all composed together in a page, if I want to
>>>change the behaviour of the page e.g. have a new button I can
>>>either...
>>>
>>>a) create a new page as a copy and add it.
>>>b) add it to the original.
>>>
>>>I prefer a) because I can then explicitly identify that version from
>>>the previous one. so....
>>
>>The problem with this analogy is that the page is not abstracted as a
>>monolithic entity in an OO context.
>
>
> I don't understand the above sentence.

The page you are viewing is not a single composition object as you
describe -- if the application was developed in an OO manner. It is
actually constructed from multiple independent objects that abstract
quite different things and collaborate together by navigating
relationships between their classes.

>
>
>>In fact the page is an instance of
>>Page and the buttons are instances of Control that are /related/ to
>>Page. If one adds or removes a button one adds or removes an instance
>>of Control and instantiates or deinstantiates a relationship.
>>
>>
>>>do you believe in explicit versioning?
>>
>>Tell me what you mean by 'versioning' first; I think we have another
>>disconnect here.
>
>
> If I add a new button to the page and press compile, do I get
> something that is distinguishable from the previous compilation or
> not.
>
> If not then it is not a new version, if yes then it is.

OK, you are using it in the sense of source control or configuration
management. Yes, I think that is a fine thing.

However, I don't see the relevance to the present COM/composition
context. There will be a new version of the software whether the Page
is a monolithic composition with embedded buttons or the buttons are
separate objects. There will also be a new software version whether
Page and Button are COMable or not.

>
>
>>>what has this to do with COM? (this page is html).
>>
>>With COM one could compose a monolithic Page1 component with embedded ON
>>and OFF buttons. One could also compose a monolithic Page2 component
>>with embedded ON, OFF, and MAYBE buttons. But it would be a different
>>thing than the first even though it was composed of almost identical
>>components.
>
>
> Yes....what would you do? subclass and inherit?.....I wouldn't.

No, I would simply let Page and Button be separate objects:

        1 controls for *
[Page] --------------------- [Button]

>>But in OO development one doesn't do that because it tends to
>>proliferate complex and rigid abstractions. So one has separate,
>>simpler notions for Page and Control and a flexible way to link them
>>together to yield arbitrary configurations.
>
>
> ah ha, now I possibly understand.
>
> Well in actual fact that is what is sort of happening, when you create
> a 'page' you really are creating a page factory, it simply captures
> the specific configuration.
>
> I agree it is presented to the programmer as a 'page' or form but it
> isn't, it's a form factory.

I see that somewhat differently. The Factory just encapsulates the
rules and policies of instantiation:

               1
[PageFactory] -------------------------+
      | 1 |
      | |
      | |
      | creates | creates
      | * | *
   [Page] ------------------------- [Button]
          1 controls for *

> .net has absolutely nothing to do with COM.
>
> .net if anything is a java clone.

Aren't you thinking of C# rather than .NET?

*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl@pathfindermda.com
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
blog (under constr): http://pathfinderpeople.blogs.com/hslahman
(888)-OOA-PATH


Quantcast