Hi everybody,
I'm making the design of a OO framework and I'm facing the following problem.
Let's say that in the framework I have a Shape interface and the users are free to implement and extends (adding new functions) the Shape interface to create their own figures, e.g. Square and Circle. To make these new objects available the users have to register them into a ShapeFactory specifying the name of the shape (string) and the object.
Furthermore, the framework provides an interface called ShapeWorker which defines the following function:
class ShapeWorker
{
public:
void processShape( Shape& shape ) = 0;
};
The users are free to implement the ShapeWorker interface to make specific shape worker, e.g. SquareWorker and CircleWorker. To make these new objects available the users have to register them into a WorkerFactory, specifying the name of shape (string) and the object.
At a certain point, the framework, given a string representing the shape's name, creates a new Shape, by using the ShapeFactory, and afterwards (somewhere else in the code) creates a new ShapeWorker, by using the WorkerFactory with the same shape's name. The processShape is then called providing the Shape instance created before.
[ ... ]
Shape* myShape = shapeFactory.create( shapeName );
[ ... ]
ShapeWorker* myWorker = workerFactory.create( shapeName );
myWorker->processShape( *myShape );
[ ... ]
The point is that, doing so, I force the user implementing, for example, the SquareWorker to make a down-cast from Shape to Square into the processShape function so to access to the full Square's interface:
class SquareWorker
{
public:
void processShape( Shape& shape )
{
Square& square = dynamic_cast< Square& >( shape );
// using Square interface
}
};
This is against the Liskov substitution principle.
Now, is this approach wrong? What would it be the better solution? Note that I don't want to implement the processShape as Shape's member function.
I hope the description has been clear enough.
Thanks in advance for your help.
Simo