Hi i made a post a while ago reguarding an alternitve to using Dynamic type checking, that post provided me with a lot of good insight on to the problem and I was recommended to use the Double Dispatching pattern. This pattern is a good solution where the set of classes is of a limited number.
class Number {
virtual Number add(Number * n)=0;
};
class Integer
{
Number add(Number * n) {
return n ->addFromInteger(this);
}
Number addFromFloat(Number* aFloat) {
//do Integer + Float
}
Number addFromInteger(Number* anInteger) {
//do Integer + Integer
}
};
class Float
{
Number add(Number * n) {
return n ->addFromFloat(this);
}
Number addFromFloat(Number* aFloat) {
//do Float + Float
}
Number addFromInteger(Number* anInteger) {
//do Float + Integer
}
};
But when we are dealing with many classes, the number of methods for each class gets quite bloated (one method for each type of class). For example:
class Integer
{
Number add(Number * n) {
return n ->addFromInteger(this);
}
Number addFromFloat(Number* aFloat) {
//do Integer + Float
}
Number addFromInteger(Number* anInteger) {
//do Integer + Integer
}
Number addFromDouble(Number* aDouble){
//do Integer + Double
}
Number addFromFraction(Fraction* aFraction){
//do Integer + Fraction
}
Number addFromSomething(Something* aSomething){
//do Integer + Something}
};
.....
...
..
};
Now here is my problem: what i have is a scene graph layer and GUI layer that is a representation of a scene graph . I can select a Scene Graph node and drag it onto another scene graph node. The code that does this checks the runtime type of the node begin dragged and the runtime class of the node that is being dropped onto. This is done in the GUI layer as follows:
class SceneGraphGUIRep
{
SceneGraphNode * sceneGraphNode;
void SceneGraphNode * getSceneGraphNode();
}
class DragAndDropController
{
void mouseRelease
{
if (dragStart->getSceneGraphNode->isKindOfClass(Transformation))
{
if (dragEnd->getSceneGraphNode->isKindOfClass(someType))
{
//do some action
}
else if(...)
{
}
}
else if(...)
{
}
else if (...)
{
}
}
}
I was thinking of replacing this with the Double Dispatch Pattern. But using the Double Dispatch Pattern would result in very bloated classes with the need for a specific method to handle each type of class. Additionally, this would move the drag and drop code to the Scene Graph layer (from the GUI layer, which would be bad since the drag and drop function should be a semantic of the GUI). Decentralization of code( we would loose cohersion as bits and pieces of the drag and drop code would be laced throughout the various scene graph classes).
Idealy i want to be able to:
- To Maintain that drag and drop code is restricted to the GUI layer.
- Eliminate the use of dynamic type checking
- Maintain Cohersion of the drag and drop code
would my existing solution be the best or is there something else that would fit? how about the Vistor Pattern? In his book Effective C++ Scott Myeres says that the "if-then-else" style of programming should be reserved for cases that have no alternitive. Any help or suggestions would be of great help. Thanks.
[edited by - _walrus on August 5, 2003 2:39:16 PM]