web-dev-qa-db-fra.com

Pile étendant LinkedList. Une violation du principe de substitution de Liskov?

Une classe LinkedList existe avec des fonctions telles que add_first (), add_last (), add_after (), remove_first (), remove_last () et remove ()

Il existe maintenant une classe Stack qui fournit des fonctionnalités telles que Push (), pop (), peek () ou top (), et pour implémenter ces méthodes, elle étend les méthodes de la classe LinkedList. Est-ce une violation du principe de substitution de Liskov?

Par exemple, considérons le cas add_after () pour ajouter un nœud à la nième position d'une liste liée. Cela peut être fait dans la classe de base mais pas dans la classe Stack. Les postconditions sont-elles affaiblies ici ou modifiez-vous la méthode add_after () pour l'ajouter en haut de la pile?

En outre, si ce n'est pas une violation, est-ce une mauvaise conception? Et comment implémenteriez-vous la fonctionnalité Stack en utilisant la classe LinkedList?

13
jxvmiranda

Il existe maintenant une classe Stack qui fournit des fonctionnalités telles que Push (), pop (), peek () ou top (), et pour implémenter ces méthodes, elle étend les méthodes de la classe LinkedList. Est-ce une violation du principe de substitution de Liskov?

Non. Il est parfaitement possible d'ajouter des méthodes dans un sous-type.

Par exemple, considérons le cas add_after () pour ajouter un nœud à la nième position d'une liste liée. Cela peut être fait dans la classe de base mais pas dans la classe Stack.

Ceci est une violation du LSP. Le LSP dit que les instances d'un sous-type doivent être substituables aux instances d'un sur-type sans changer les propriétés souhaitables d'un programme. Si un sous-type supprime une méthode, tout code qui appelle cette méthode se bloquera (ou obtiendra une exception NoMethodError, ou quelque chose dans ce sens). De toute évidence, "ne pas planter" est une propriété souhaitable.

Les postconditions sont-elles affaiblies ici ou modifiez-vous la méthode add_after () pour l'ajouter en haut de la pile?

La modification de la méthode add_after() de cette manière est une violation de la règle d'historique (la plus importante des règles!) Et n'aide donc pas à corriger la violation du LSP.

Et comment implémenteriez-vous la fonctionnalité Stack à l'aide de la classe LinkedList?

En utilisant la composition.

REMARQUE: tout ce que j'ai écrit ci-dessus niquement s'applique aux langues qui confondent le sous-typage et le sous-classement! Le LSP concerne sous-typage, pas un sous-classement. Dans un langage qui ne confond pas les deux, il serait parfaitement acceptable de faire de Stack une sous-classe de LinkedList, tant que vous n'en faites pas un sous-type de LinkedList.

31
Jörg W Mittag

Puisque tout a déjà été abordé par Jörg W Mittag, je développe un peu la partie suivante:

Les postconditions sont-elles affaiblies ici ou modifiez-vous la méthode add_after () pour l'ajouter en haut de la pile?

Fondamentalement, lorsqu'il y a une question de savoir si une hiérarchie viole LSP, cela dépend du contrat que vous posez. Alors, quel contrat fait add_after avoir? Si cela vous semble fou, comme "Ajouter un nœud à la nième position ou en haut", alors vous êtes bien, la post-condition est remplie, LSP n'est pas violé. Sinon, c'est une violation LSP.

1
Zapadlo