2016-06-14 1 views
8

The open/closed principle indique qu'une classe doit être ouverte pour l'extension mais fermée pour modification.Est-ce que le dépassement viole le principe Open/Closed?

Je pensais que la partie modification se référait strictement à la modification du code source de la classe de base. Mais j'ai eu un argument avec quelqu'un disant que cela implique également des méthodes de remplacement de la classe de base.

Cette interprétation est-elle correcte?

+2

La substitution de méthode dans le polymorphisme de sous-type serait probablement plus typiquement associée aux violations de substitution Liskov (comme dans le problème Cercle/Ellipse) qu'autre chose. – TheInnerLight

Répondre

2

Un remplacement est un peu comme un rappel que n'importe qui peut enregistrer. C'est comme:

if (IsOverridden) CallCallback(); 
else DefaultImplementation(); //possibly empty 

En ce sens il n'y a aucune modification. Vous êtes juste en train de reconfigurer l'objet pour appeler le callback au lieu de faire le comportement par défaut.

C'est exactement comme l'événement click d'un bouton. Vous ne considéreriez pas l'abonnement à un événement comme une modification. C'est l'extension.

1

"Je pensais que la partie modification se référait strictement à la modification du code source de la classe de base."

Vous pensiez que oui.

Il y a une multitude de façons de rendre une classe extensible et en autoriser l'un à en hériter. Le mot-clé extend est même utilisé dans quelques langues pour permettre l'héritage ce qui rend évident que nous ne modifions pas, nous étendons ...

Que l'héritage soit la bonne solution à l'extensibilité ou non est une autre préoccupation, mais D'habitude, ce n'est pas le cas. La composition devrait être le moyen privilégié pour rendre les classes extensibles (par exemple Stratégie, Observateur, Décorateur, Pipes et Filtres, etc ...)

3

Les méthodes virtuelles permettent de remplacer le comportement d'une classe de base dans une classe dérivée, sans avoir à modifier le classe de base et cela signifie que vous adhérez au principe Open/Closed car vous pouvez étendre le système sans avoir à modifier le code existant.

Les classes de base (qui ne sont pas purement abstraites) ont cependant tendance à violer le Dependency Inversion Principle, puisque la classe dérivée dépend de la classe de base, qui est un composant concret au lieu d'être une abstraction. Rappelez-vous, le DIP states que:

Les modules de haut niveau [...] doivent dépendre des abstractions.

En outre, les classes de base ont tendance à violer la Interface Segregation Principle aussi bien dans le cas où ils définissent plusieurs méthodes publiques (ou protégées) qui ne sont pas tous utilisés par le type dérivé. Ceci est une violation du FSI parce que:

aucun client ne devrait être contraint à dépendre de méthodes ne pas utiliser

+0

Je ne suis pas d'accord avec le fait que des méthodes concrètes sur une classe de base violent le FAI, car le client n'est pas obligé de dépendre d'eux - ils n'ont pas besoin d'implémenter des méthodes qu'ils n'utiliseront pas, par exemple par rapport à l'implémentation d'une interface, puis en lançant un 'MethodNotSupportEdexception', ou similaire. Je dirais cependant que le nombre de méthodes inutilisées est corrélé à la cohésion entre sub et super classe: si beaucoup d'entre elles ne sont pas pertinentes, c'est probablement une odeur que vous avez prolongé la mauvaise classe, ou une autre classe doit être extrait pour les points communs. – anotherdave

+0

@anotherdave Avoir des méthodes concrètes sur une classe de base n'est pas une violation de l'ISP, mais avoir des méthodes concrètes sur une classe de base qui ne sont pas utilisées par un dérivé est en fait une violation d'ISP. La question de savoir si le client les utilise ou non est sans importance, puisque le fournisseur de services Internet déclare «qu'aucun client ne devrait être contraint de dépendre de méthodes qu'il n'utilise pas». La même chose vaut pour les interfaces larges, où le client utilise seulement 1 des 10 méthodes. Cela dépend encore des 9 autres méthodes, qui sont "déjà là". – Steven

+0

@anotherdave Mais oui, il existe une corrélation entre le nombre de méthodes inutilisées dans la classe de base et la cohésion de cette classe. Une faible cohésion est souvent une indication d'une violation de violation de responsabilité unique. Vous verrez souvent des classes de base abusées pour mettre en œuvre des préoccupations transversales. Avoir plusieurs préoccupations transversales dans une classe de base est une violation de la SRP. – Steven

0

Form « Code Adaptive via C# » livre, méthodes virtuelles est un instrument pour atteindre OCP.