J
Juha Nieminen
H. S. Lahman said:(1) Use separate homogeneous collections rather than heterogeneous
collections. Then the client who needs specific types of objects can
navigate the appropriate relationship to the right collection.
In my particular case I am (usually) keeping objects of a certain type
in a container of that type, and I access this container directly when
it's possible to do so (eg. to perform an action on some or all the
objects of that type, as long as this action is independent of any other
objects in the system).
The problem is that not all actions I need to perform can be applied
to objects independently of other objects. In particular, sometimes some
actions need to be performed in a certain order. The two problems are
that the objects in the object-specific container might not be in this
order already, and secondly, even if they were, some actions have to be
performed to all existing objects (regardless of their type) in a strict
order, and cannot be performed on a per-type basis.
Currently I'm maintaining this order by putting base-class-type
pointers in a common container. The order of the pointers in this
container defines the order of all the objects. (Note that there are
also other reasons for doing this. Ordering is just one of them.)
One possibility would be to add a virtual function in the common base
class to perform this specific action. This way all the object types
could implement this action by implementing this virtual function, and
there would be no need for dynamic_cast.
The problem with this is that this base class and some of the objects
derived from it (which are often used here and there in the program) are
in a library. It would mean that I would have to add these new (often
program-specific) features to the library.
This would not only be cumbersome, but I also feel it goes against
proper OO design: You don't go and add application-specific features to
an abstract base class or existing objects in a library. If I did this
for every feature of every program I develop, it would make the library
and the base class less abstract and more bloated.
If dynamic_cast has to be avoided at all costs, some other solution is
needed. Maybe a complete re-design of the library. But even so, I really
haven't come up with a better solution. That's why I'm interested in
hearing new ideas.
(2) Provide the type information to the collection and provide an
interface to the collection that clients can access by providing a
desired type. Then the collection manages the {type, object} tuples in
its implementation.
I'm not exactly sure what this means, and how it is radically
different from using dynamic_cast. (It sounds to me like dynamic_cast
would simply have been replaced with some kind of checking of the 'type'
inside those tuples. If this is so, then it would simply make the whole
implementation more complicated with no real benefit.)