H
H. S. Lahman
Responding to queisser...
The OO paradigm manages access through relationship instantiation.
That's why relationships are instantiated at the object level rather
than at the class level. It is also why one is encouraged to have
multiple relationships between the same classes to support different
collaborations (e.g., different relationship roles in UML).
One reason for doing that is to separate the concerns of *who*
participates in collaboration from the concerns of *when* to
collaborate. That's because the business rules and policies of who
collaborates are usually quite different than those that govern when to
collaborate, so they need to be isolated and encapsulated in their own
methods that are logically "owned" by the right object abstraction.
Thus the client in an OO collaboration should normally only need to know
when to collaborate, not who to collaborate with. The client has faith
that whoever is on the other end of the relationship path is *always*
the right object. Even in the rare situations where the client object
also has the responsibility to determine who to collaborate with in the
solution context, that responsibility would be encapsulated in a
different method.
The name of the game in OO development is robustness in the face of
volatile requirements. The application will *always* be more robust if
one separates the concerns of who vs. when during collaboration, whether
that is convenient or not. If one limits dynamic_cast to subsystem
interface dispatch, then the subsystem implementation will be more
robust because whatever one did to avoid it will be tacitly separating
those concerns.
[FWIW, I agree with the no-op position. If the behavior is a no-op for
all members of a descendant leaf subclass in all solution contexts, then
the behavior is defined at the wrong level in the generalization.
Objects have responsibilities to know things and to do things. They do
not have responsibilities to not do things. By that logic every object
would have a no-op method for every behavior in every other object
because it is not supposed to do anything for those other object
responsibilities. IOW, if the object is not supposed to do something,
then it doesn't have a responsibility to do it. But let's not go there.]
Because if one gets to the point where one thinks one needs it, it is a
sure sign that one has somehow screwed up the problem space abstraction
in OOA/D. B-)
<aside>
Alas, this sort of argument is not persuasive to me in general. That's
because I grew up before Djikstra when people thought GoTos were a boon
and FORTRAN's assigned GoTo and COBOL's ALTER statements were even
better. I was there when the view shifted to "sometimes you need it" and
that seemed persuasive. But then I programmed in a language, BLISS, that
didn't even have a GoTo construct and I found I never missed it. Nor
have I needed it since using languages that did have the construct. And
about the same time programming managers were making using assigned GoTo
or ALTER grounds for summary dismissal, and nobody missed them either.
No offense intended but... IME, when developers agree that a practice is
something to be avoided but that there are exceptions, those exceptions
turn out to mean they just haven't looked hard enough for an
alternative. It is usually a very safe bet that OOA/D methodology
designers have considered the problem and have provided the means to
deal with it. That might means might not be compact and might require
some extra keystrokes, but compactness and keystrokes aren't an issue
for OO development; otherwise we would all be doing functional programming.
</aside>
--
There is nothing wrong with me that could
not be cured by a capful of Drano.
H. S. Lahman
(e-mail address removed)
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
(e-mail address removed) for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH
Redefine "external" and "subsystem interface" just a little bit and
everyone's happy. I think traversing a collection and only acting on certain
types is preferable to having the same object in two collections, just to
avoid dynamic_cast or, even worse, forcing functionality with do-nothing
defaults into the superclass (although I didn't hear anyone advocating
that.)
The OO paradigm manages access through relationship instantiation.
That's why relationships are instantiated at the object level rather
than at the class level. It is also why one is encouraged to have
multiple relationships between the same classes to support different
collaborations (e.g., different relationship roles in UML).
One reason for doing that is to separate the concerns of *who*
participates in collaboration from the concerns of *when* to
collaborate. That's because the business rules and policies of who
collaborates are usually quite different than those that govern when to
collaborate, so they need to be isolated and encapsulated in their own
methods that are logically "owned" by the right object abstraction.
Thus the client in an OO collaboration should normally only need to know
when to collaborate, not who to collaborate with. The client has faith
that whoever is on the other end of the relationship path is *always*
the right object. Even in the rare situations where the client object
also has the responsibility to determine who to collaborate with in the
solution context, that responsibility would be encapsulated in a
different method.
The name of the game in OO development is robustness in the face of
volatile requirements. The application will *always* be more robust if
one separates the concerns of who vs. when during collaboration, whether
that is convenient or not. If one limits dynamic_cast to subsystem
interface dispatch, then the subsystem implementation will be more
robust because whatever one did to avoid it will be tacitly separating
those concerns.
[FWIW, I agree with the no-op position. If the behavior is a no-op for
all members of a descendant leaf subclass in all solution contexts, then
the behavior is defined at the wrong level in the generalization.
Objects have responsibilities to know things and to do things. They do
not have responsibilities to not do things. By that logic every object
would have a no-op method for every behavior in every other object
because it is not supposed to do anything for those other object
responsibilities. IOW, if the object is not supposed to do something,
then it doesn't have a responsibility to do it. But let's not go there.]
I think most people will strive to avoid type-testing elements in
heterogenous collections but when the time comes where you need it most
design-arounds end up being dynamic_cast in disguise. Why not just embrace
it - you know you want to.
Because if one gets to the point where one thinks one needs it, it is a
sure sign that one has somehow screwed up the problem space abstraction
in OOA/D. B-)
<aside>
Alas, this sort of argument is not persuasive to me in general. That's
because I grew up before Djikstra when people thought GoTos were a boon
and FORTRAN's assigned GoTo and COBOL's ALTER statements were even
better. I was there when the view shifted to "sometimes you need it" and
that seemed persuasive. But then I programmed in a language, BLISS, that
didn't even have a GoTo construct and I found I never missed it. Nor
have I needed it since using languages that did have the construct. And
about the same time programming managers were making using assigned GoTo
or ALTER grounds for summary dismissal, and nobody missed them either.
No offense intended but... IME, when developers agree that a practice is
something to be avoided but that there are exceptions, those exceptions
turn out to mean they just haven't looked hard enough for an
alternative. It is usually a very safe bet that OOA/D methodology
designers have considered the problem and have provided the means to
deal with it. That might means might not be compact and might require
some extra keystrokes, but compactness and keystrokes aren't an issue
for OO development; otherwise we would all be doing functional programming.
</aside>
--
There is nothing wrong with me that could
not be cured by a capful of Drano.
H. S. Lahman
(e-mail address removed)
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
(e-mail address removed) for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH