Je suis en train de concevoir un framework OO et je suis confronté au problème suivant.Problème de conception orienté objet, Liskov Principe de substitution
Disons que dans le cadre que j'ai forme interface et les utilisateurs sont libres de mettre en œuvre et Prolonge (ajout de nouvelles fonctions) l'interface forme pour créer leurs propres chiffres, par exemple Carré et Cercle. Pour rendre ces nouveaux objets disponibles, les utilisateurs doivent les enregistrer dans un ShapeFactory en spécifiant le nom de la forme (chaîne) et l'objet.
En outre, le cadre fournit une interface appelée ShapeWorker qui définit la fonction suivante:
class ShapeWorker
{
public:
void processShape(Shape& shape) = 0;
};
Les utilisateurs sont libres de mettre en œuvre le ShapeWorker interface pour rendre travailleur de forme spécifique, par exemple SquareWorker et CircleWorker. Pour rendre ces nouveaux objets disponibles, les utilisateurs doivent les enregistrer dans un WorkerFactory, en spécifiant le nom de la forme (chaîne) et l'objet.
À un certain moment, le cadre, d'une chaîne représentant le nom de la forme, crée une nouvelle forme, en utilisant le ShapeFactory, et ensuite (ailleurs dans le code) crée une nouvelle ShapeWorker, en utilisant le WorkerFactory avec le même nom de forme. Le processShape est alors appelé fournissant l'instance Shape créée précédemment.
[ ... ]
Shape* myShape = shapeFactory.create(shapeName);
[ ... ]
ShapeWorker* myWorker = workerFactory.create(shapeName);
myWorker->processShape(*myShape);
[ ... ]
Le point est que, ce faisant, je force l'utilisateur la mise en œuvre, par exemple, le SquareWorker pour faire un bas-cast de forme-place dans la processShape fonction ainsi l'accès à l'interface de l » pleine carrés:
class SquareWorker
{
public:
void processShape(Shape& shape)
{
Square& square = dynamic_cast< Square& >(shape);
// using Square interface
}
};
Ceci est contre le principe de substitution Liskov.
Maintenant, cette approche est-elle incorrecte? Quelle serait la meilleure solution? Notez que je ne veux pas implémenter le processShape en tant que fonction membre de Shape.
J'espère que la description a été assez claire.
Merci d'avance pour votre aide.
Simo
Vous devriez ajouter une balise C++ je pense. –
Pouvez-vous fournir le raisonnement derrière l'instruction "Notez que je ne veux pas implémenter la processShape en tant que fonction membre de Shape"? – SCFrench
L'un des problèmes ici est que le code avec des références à Shape et ShapeWorker ne sait pas s'il est sûr de passer la Shape à ShapeWorker, sans une traçabilité au point de création pour vérifier que les deux objets ont été créés en utilisant le même shapeName. – SCFrench