|
From: H. S. Lahman on 21 Oct 2006 11:55 Responding to Squeamizh... > In C++, I need to pass a single object in the form of several > references to a function. Something like this: > > class Child : public InterfaceA, public InterfaceB, public InterfaceC { > }; > > void do_something(InterfaceA& same_object_a, InterfaceB& same_object_b, > InterfaceC& same_object_c); > > When I call do_something, I end up doing this: > > Child child; > do_something(child, child, child); I agree with the others. This is highly suspicious. What you are basically saying is the the Receiver of the message (who owns the do_something responsibility) has three different relationships with Child: +----------------- [Receiver] --------------------+ | | | | R1 | R2 | R3 | | | | | used in B context | +------------------ [Child] ----------------------+ used in A context used in C context and Caller (who is invoking Receiver::do_something) is temporarily instantiating all three relationships for Receiver. If your example is literally true and exactly the same [Child] instance is involved in all three relationships with a given Receiver, then there is something wrong. When the same objects participate in collaboration, they should all be using the same interface. IOW, typically one only needs multiple relationships when there are different /participants/ in different collaboration contexts. For example, [Registrar] ---------------+ | 1 | | | | R1 | R2 | | | registers | | * | [Student] -----------------+ 0..* expels The set of Students participating in the R2 collaborations is a subset of the Students participating in the R1 collaborations. But any member of the [Registrar] set "knows" all members of [Student] set in the same way for purposes of collaboration via either relationship. I am also extremely skeptical of the situation where each Child is a different member of the [Child] set and needs to have its access restricted. I cannot think of a plausible situation for the simpler case where different members of the [Receiver] set would need to have their access to members of the [Child] set restricted. I certainly can't think of one where the same Receiver would have its access to different [Child] members restricted. That is, the whole point of multiple interfaces is to restrict access for /different/ clients. If the same client can have access to all three interfaces, then there is no point in having different interfaces. Bottom line: I think you need to be more explicit about what the problem is that you are trying to solve. ************* There is nothing wrong with me that could not be cured by a capful of Drano. H. S. Lahman hsl(a)pathfindermda.com Pathfinder Solutions http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman "Model-Based Translation: The Next Step in Agile Development". Email info(a)pathfindermda.com for your copy. Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php. (888)OOA-PATH
From: H. S. Lahman on 22 Oct 2006 10:45 Responding to Squeamizh... >>Bottom line: I think you need to be more explicit about what the problem >>is that you are trying to solve. > > > Thanks for the responses. > > Let me try to add some clarity to my question. There are a lot of > "Child" classes which all, ultimately, inherit the three Parent > interfaces. The do_something function just needs to know that the > object being passed to it implements the three Parent interfaces, > because the only functions it calls on the object are declared by those > three interfaces. > > I neglected to mention that the root of this problem is that I am > trying to avoid gigantic interfaces that explicitly handle each type of > child object. For example, I was trying to avoid this: > > void do_something(ChildA child_a); > void do_something(ChildB child_b); > [...] > void do_something(ChildZ child_z); > > ...because, in each of these overloads, the exact same function is > performed. Perhaps the message I'm getting is that this is a hopeless > battle, and I should just fatten up the interface? Alas, this doesn't explain what the problem is that your are trying to solve in the real application you are developing. The issue here is why you think Receiver::do_something needs to access three different interfaces of [Child]. Methods are supposed to implement logically indivisible responsibilities. That, in turn, implies that Receiver::do_something has a rather limited collaboration context with [Child]. So why would it need to use multiple interfaces for that limited collaboration? I suspect your problem lies in how the caller of Receiver::do_something obtains the correct [Child] reference. For example, you might have three different objects that invoke Receiver::do_something in different solution contexts where the Child reference available to them is in the form of a different interface. If that is the case, you can simply generalize the interface: [IChild] A | +-----------+-----------+ | | | [IChildA] [IChildB] [IChildC] where IChild is the superset interface for {IChildA, IChildB, IChildC}. Now in each caller context one has a specific leaf interface reference but the method is defined as Receiver::do_something (IChild child) so one can pass any subclass reference to it. (Note that this is pretty much what both Kazakov and Daniel T. suggested in their original posts.) ************* There is nothing wrong with me that could not be cured by a capful of Drano. H. S. Lahman hsl(a)pathfindermda.com Pathfinder Solutions http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman "Model-Based Translation: The Next Step in Agile Development". Email info(a)pathfindermda.com for your copy. Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php. (888)OOA-PATH
|
Pages: 1 Prev: HOM: Higher Order Messaging Next: Advantages of object-oriented programming |