2016-08-03 1 views
2

La conception actuelle estViolation de Liskov principe de substitution dans SharedFolder

  1. SharedFolder est une sous-classe de Folder.
  2. SharedFile est une sous-classe de File avec une URL de ressource distante.
  3. Folder accepte la méthode add.
  4. SharedFolder accepte seulement SharedFile mais pas non partagé File
  5. File peut être déplacé vers un autre Folder avec add.
  6. L'interface utilisateur pour la recherche de fichiers dans SharedFolder et Folder est la plupart du temps identique.

Le add dans SharedFile enfreint LSP. Comment réorganiser la structure de l'objet tout en permettant une réutilisation du code de l'interface utilisateur?

+1

Vous pouvez définir la méthode add de ne pas garantir contractuellement que l'ajout est possible dans tous les cas. De cette façon, il n'y a pas d'échec de substitution. – usr

+0

@usr, dites-vous que la documentation seule peut satisfaire LSP? Dans ce cas, même la méthode notoire [Iterator.remove()] (https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#remove--) satisfait LSP. – jaco0646

+0

La saisie statique est juste un moyen d'ajouter * une * documentation * d'une manière lisible par une machine. Un contrat d'interface est arbitraire. C'est ce que vous définissez. Ne vous accrochez pas à des problèmes de syntaxe ou de langage. – usr

Répondre

3

Vous pouvez genericize Folder comme Folder<T extends File>, avec add(T), et ont SharedFolder extends Folder<SharedFile>.

De cette façon, SharedFolder est ne devrait se substituer une autre Folder<SharedFile>, mais pas tout autre type de Folder<File>

(Si votre langue permet. Ce serait possible en Java)

+0

Vraisemblablement, il doit pouvoir stocker n'importe quel type de dossier dans une variable. Ensuite, les informations de contrainte générique sont perdues et la violation LSP revient. – usr

+0

Si vous utilisez un type de dossier, vous ne pouvez pas stocker de type de fichier dans ce dossier. Vous ne pouvez pas vous débarrasser de la contrainte générique. – njzk2

3

Il existe de nombreuses réponses possibles à votre question. Voici deux:

  • Retirez la méthode add de la classe de base Folder, et ne laissez-le exposer une (lecture seule) collection de File éléments. Supprimer la relation 'est un' entre SharedFolder et Folder En d'autres termes, ne laissez pas SharedFolder hériter de Folder. Au lieu de cela, vous pouvez laisser SharedFolder devenir une sorte de classe de métadonnées contenant un Folder (composition sur héritage).
+0

Comment la première réponse satisfait-elle LSP? La collection doit-elle être immuable? Sinon, la méthode 'add()' incriminée a simplement été déplacée dans la collection. – jaco0646

+0

@ jaco0646 Cela résout le problème, car les utilisateurs de la classe de base seront incapables d'appeler 'add' et d'insérer des éléments incompatibles avec le contrat de classe dérivé. – Steven

+0

... mais le consommateur peut toujours appeler 'getCollection(). Add()' qui échouerait dans le même scénario que l'original 'add()'. – jaco0646