Principe de Liskov : cas concret ?

Principe de Liskov : cas concret ? - Algo - Programmation

Marsh Posté le 30-09-2008 à 10:38:11    

Bonjour j'ai un problème de modélisation objet a vous soumettre. Voici mon arborescence d'héritage :
 
http://movie.nexus.free.fr/images/schema.JPG
 
Cette arborescence doit respecter le principe de substitution de Liskov.  
 
Le problème c'est que les classes "Document chiffre" et "Courrier" utilisent des données faisant référence à un "Client" et à des fct d'insert et d'update BDD. MAIS l'objet "Graphique" (situé au même niveau de la hiérarchie) n'y fait absolument pas référence. Cependant "Graphique" doit hériter de "Document Membre" car il a besoin de certains autres element de cet objet.
 
C'est pourquoi j'ai décidé d'utiliser la composition pour "Document Membre" et de créer deux objets ; l'un gérant le client (oDatasClientDocument), l'autre les fct d'interfaçages avec la BDD (oBddDocument).
 
Mais avec cette nouvelle architecture certaines fct de "Document Membre" (entre autre getDatasClientDocument()) ne pourront pas être utilisé dans "Graphique" (cela n'aurait pas de sens). Donc cette architecture viole le principe de substitution.
 
Comment puis je faire pour que "Document Membre" gère les Clients et la Bdd tout en gardant la classe "Graphique" sans violer le principe de substitution.
 
Merci pour vos réponses
 

Reply

Marsh Posté le 30-09-2008 à 10:38:11   

Reply

Marsh Posté le 30-09-2008 à 11:49:13    

Qu'en document soit membre ou libre, chiffré ou clair, c'est une information annexe, ça ne change pas la nature de ton document. Donc enlève ces trucs de ton arbre (pour rajouter des propriétés, template, héritage multiple, tu vois)

Reply

Marsh Posté le 01-10-2008 à 09:03:12    

Apparemment vous me dites qu’ici la solution n’est pas l’héritage mais plutot la composition.  
 
Très bien, mais si je n’ai que « Document » avec à l’intérieur des propriétés, par exemple comme c’est le cas maintenant « $this->oMembre » qui gère les données du membre pour le document. Si le document est libre cette propriété n’a pas de raison d’être, donc elle sera égale à « null ». Je ne suis pas spécialiste mais je sais qu’il n’est pas bon d’avoir des propriétés à null dans ses objets.
 
C’est pour cela que j’avais utilisé le concept de « Document Membre » pour ne pas avoir de propriétés à « null ». Si dans ce cas de figure vous me conseillez la composition, comment dois-je gérer cette variable « null » ?

Reply

Marsh Posté le 01-10-2008 à 09:22:19    

Si je vous suis, je devrais faire quelque chose dans ce genre ?
 
http://movie.nexus.free.fr/images/schema2.JPG
 

Reply

Marsh Posté le 01-10-2008 à 09:36:40    

jamesbond2 a écrit :


Apparemment vous me dites qu’ici la solution n’est pas l’héritage mais plutot la composition.  


Oui
 

jamesbond2 a écrit :


Je ne suis pas spécialiste mais je sais qu’il n’est pas bon d’avoir des propriétés à null dans ses objets.


 
C'est la meilleure de l'année. Je vois pas en quoi unmemebre à null pose un problème.

Reply

Marsh Posté le 01-10-2008 à 09:39:13    

dans tous les livres de développement objets que j'ai peu lire ils disent clairement que si on a beaucoup de proriétés a "null" dans ses objets cela révele un défaut d'analyse.

Reply

Marsh Posté le 01-10-2008 à 09:39:43    

brules ces livres :o


---------------
Nos estans firs di nosse pitite patreye...
Reply

Marsh Posté le 01-10-2008 à 10:01:39    

d'accord, si dans mon diagramme précédent, je met une propriété "$this->oClient" à mon "Document", si ensuite je cré un objet "Graphique" qui descend de "Document" et qui n'a en fait pas de client. la prorpiété "oClient" sera donc "null". Si maintenant je cré la fct de "Document" , "getClient()" et que je l'utilise dans "Graphique", cela viole le principe de substitution de Liskov, qui veut que TOUTES les fct de la classe mère puissent être utilisées dans la classe fille. Techniquement je peux le faire mais sémantiquement cela n'a pas de sens.

Reply

Marsh Posté le 01-10-2008 à 10:12:54    

si je ne voulais pas avoir de variable "null",je ne mettrais pas "oClient" dans graphique ni dans "Document" je ne le mettrais uniquement dans des objets enfant de "Document" qui gère les clients. C'est pour cela que je dis que l'exemple de mon post précédent simulait une erreur volontaire d'analyse pour illistrer mon propos

Reply

Marsh Posté le 01-10-2008 à 10:13:04    

si je ne voulais pas avoir de variable "null",je ne mettrais pas "oClient" dans graphique ni dans "Document" je ne le mettrais uniquement dans des objets enfant de "Document" qui gère les clients. C'est pour cela que je dis que l'exemple de mon post précédent simulait une erreur volontaire d'analyse pour illistrer mon propos

Reply

Marsh Posté le 01-10-2008 à 10:13:04   

Reply

Marsh Posté le 01-10-2008 à 11:26:56    

jamesbond2 a écrit :

d'accord, si dans mon diagramme précédent, je met une propriété "$this->oClient" à mon "Document", si ensuite je cré un objet "Graphique" qui descend de "Document" et qui n'a en fait pas de client. la prorpiété "oClient" sera donc "null". Si maintenant je cré la fct de "Document" , "getClient()" et que je l'utilise dans "Graphique", cela viole le principe de substitution de Liskov, qui veut que TOUTES les fct de la classe mère puissent être utilisées dans la classe fille. Techniquement je peux le faire mais sémantiquement cela n'a pas de sens.


Euh j'ai décroché. Comment tu fais pour avoir une méthode dans la classe mère et ne pas pouvoir l'utiliser dans une sous-classe ?

Reply

Marsh Posté le 01-10-2008 à 11:31:15    

autre exemple :  
 
http://movie.nexus.free.fr/images/schema3.JPG
 
J'ai une propriété de Numero de document ($this->iNumero). Dans tous mes documents, seuls "Graphique" et "Document Libre" n'ont pas de numéros.
 
Si je respect le schéma ci-dessus, j'ai deux solutions :
 
- Soit je mets la propriété "Numero" et ses fct accesseur/mutateur dans "Document", mais je viole le principe de substitution.
- Soit je répète la propriété "Numero" et ses fct accesseur/mutateur dans chaque document l'utilisant (Facture, Bl, Bc, Devis, Avoir), mais cela fait beaucoup de redondance de code
- Soit je crée un objet à part pour gérer la numérotation, mais cela me fait créer un objet annexe juste pour une propriété, c’est un peu dommage
 
quelle solution est la plus appropriée selon vous ?

Reply

Marsh Posté le 01-10-2008 à 11:32:45    

Taz a écrit :


Euh j'ai décroché. Comment tu fais pour avoir une méthode dans la classe mère et ne pas pouvoir l'utiliser dans une sous-classe ?


 
je ne dis pas que je ne PEUX pas l'utiliser, je dis que si je l'utilise je viole le principe de substitution de Liskov, c'est TRES différent

Reply

Marsh Posté le 01-10-2008 à 11:47:03    

Le principe de substitution de Liskov est le suivante :  
 
"En clair, pour prétendre à l'héritage, une sous-classe doit être conçue de sorte que ses instances puissent se substituer à des instances de la classe de base partout où cette classe de base est utilisée."
 
c'est LA règle fondamentale de l'héritage

Reply

Marsh Posté le 01-10-2008 à 14:58:31    

Il te faut une sous-classe document numéroté alors.
a) nan tu le violes pas, c'est juste que ton modèle est faux puisque les graphiques n'ont pas de Numero
b) dans ce cas là Facture.Numero n'a AUCUN lien avec les autres AutresDocuments.Numero. C'est juste le meme nom, pas une interface commune.
c) pas à part, juste un arbre à 3 niveaux.

Message cité 1 fois
Message édité par Taz le 01-10-2008 à 15:01:41
Reply

Marsh Posté le 01-10-2008 à 14:59:15    

jamesbond2 a écrit :

Le principe de substitution de Liskov est le suivante :  
 
"En clair, pour prétendre à l'héritage, une sous-classe doit être conçue de sorte que ses instances puissent se substituer à des instances de la classe de base partout où cette classe de base est utilisée."
 
c'est LA règle fondamentale de l'héritage


sans déconner ...

Reply

Marsh Posté le 01-10-2008 à 15:08:52    

c'est gentil de nous faire un cours  
 
masi ce n'est pas parceque tu dois pouvoir substituer un élément d'une classe fille a un élément d'une classe père que la fille et le père doivent avoir le même comportement, sinon, ca sert a rien de créer une autre classe si la fille ne peut pas redefinir les méthode du père  
 
au niveau de ton dernier exemple, si vraiment je voulais éviter un inumero a vide, je créerai une classe docAvecInumero , dont hérite tes 5 premières classes et une autre docSansInumero dont hérite les deux autres.


---------------

Reply

Marsh Posté le 01-10-2008 à 15:19:03    

Taz a écrit :

Il te faut une sous-classe document numéroté alors.
a) nan tu le violes pas, c'est juste que ton modèle est faux puisque les graphiques n'ont pas de Numero
b) dans ce cas là Facture.Numero n'a AUCUN lien avec les autres AutresDocuments.Numero. C'est juste le meme nom, pas une interface commune.
c) pas à part, juste un arbre à 3 niveaux.


 
Merci pour tes réponses
 
a) ce qui est vrai pour Numéro l'est aussi pour un certains nombre de propriété(4 ou 5) qui sont commune à Facture, Bl, Bc, devis, Avoir; mais pas à Document Libre ou Graphique. C'est pourquoi j'avais créé la classe "Document Membre" pour regrouper ces propriétés commune à ces 5 types de document. Donc créer une classe "Document numéroté" va bien dans le sens de mon 1er diagramme avec une classe "Document Membre" (le nom est peut être mal choisi) !
 
b) je saisi pas...
 
c) entièrement d'accord
 
par contre je trouve que les sarcasmes du genre « sans déconner ... » n’apportent rien au débat…

Reply

Marsh Posté le 01-10-2008 à 15:37:54    

en fait, dans ton premier diagramme, faut juste que ta classe "graphique" dérive de "document libre" (ou de "document" )


---------------
Nos estans firs di nosse pitite patreye...
Reply

Marsh Posté le 01-10-2008 à 15:40:30    

d'accord, je vais chercher dans cette voix...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed