Je suis en train de refactoriser un site Web hérité de PHP OOP.
Je suis tellement tenté de commencer à utiliser "final" sur les classes pour " make it explicit that the class is currently not extended by anything
". Cela pourrait économiser beaucoup de temps si j'arrive à une classe et je me demande si je peux renommer / supprimer / modifier une protected
propriété ou une méthode. Si je veux vraiment étendre une classe, je peux simplement supprimer le mot-clé final pour le déverrouiller .
C'est-à-dire que si j'arrive dans une classe qui n'a pas de classe enfantine, je peux enregistrer cette connaissance en marquant la classe comme finale. La prochaine fois que j'y viendrai, je n'aurais pas à chercher à nouveau dans la base de code pour voir s'il a des enfants. Gain de temps pour les refactorings
Tout cela semble être une idée de gain de temps raisonnable ... mais j'ai souvent lu que les cours ne devraient être rendus "finaux" que lors d'occasions rares / spéciales.
Peut-être que ça gâche la création d'objet Mock ou a d'autres effets secondaires que je ne pense pas.
Qu'est-ce que je rate?
la source
Réponses:
Celui qui a écrit cela est faux. Utilisez
final
généreusement, il n'y a rien de mal à cela. Il documente qu'une classe n'a pas été conçue avec l'héritage à l'esprit, ce qui est généralement vrai pour toutes les classes par défaut: la conception d'une classe pouvant être héritée de manière significative nécessite plus que la suppression d'unfinal
spécificateur; cela prend beaucoup de soin.Donc, utiliser
final
par défaut n’est en aucun cas mauvais. En fait, beaucoup de gens proposent que ce soit le cas par défaut, par exemple Jon Skeet .Ceci est certes une mise en garde, mais vous pouvez toujours recourir à des interfaces si vous devez vous moquer de vos classes. Ceci est certainement supérieur à rendre toutes les classes ouvertes à l'héritage dans le seul but de se moquer.
la source
final
joueraient un rôle beaucoup plus important.Si vous voulez vous rappeler qu'une classe n'a pas de sous-classes, alors n'hésitez pas et utilisez un commentaire, c'est ce à quoi elles servent. Le mot-clé "final" n'est pas un commentaire, et utiliser des mots-clés de langage simplement pour signaler quelque chose (et vous seul savez jamais ce que cela signifie) est une mauvaise idée.
la source
final
comme prévu. Il n'y a rien de mal à ça. Et utiliser une fonctionnalité de langage pour imposer une contrainte est toujours préférable à un commentaire.final
devrait indiquer "Aucune sous-classe de cette classe ne devrait jamais être créée" (pour des raisons juridiques ou quelque chose du genre ), pas "cette classe n'a actuellement aucun enfant, donc je suis toujours en sécurité de jouer avec ses membres protégés". L'intention definal
est l'antithèse même de "librement éditable", et unefinal
classe ne devrait même pas avoir deprotected
membre!final
signifie "cette classe ne doit pas être étendue [pour le moment]". Rien de plus, rien de moins. Que PHP ait été conçu avec cette philosophie en tête est sans importance: il contient lefinal
mot clé, après tout. Deuxièmement, discuter de la conception de PHP est voué à l'échec, compte tenu de la conception inégale et mal conçue de PHP.Il y a un bel article sur "Quand déclarer une classe finale" . Quelques citations:
PS Merci à @ocramius pour sa bonne lecture!
la source
"final" pour une classe signifie: vous voulez une sous-classe? Allez-y, supprimez la "finale", sous-classe autant que vous le souhaitez, mais ne vous plaignez pas si cela ne fonctionne pas. Tu es tout seul.
Lorsqu'une classe peut être sous-classe, c'est un comportement sur lequel les autres s'appuient, doit être décrit en termes abstraits auxquels les sous-classes obéissent. Les appelants doivent être écrits pour s'attendre à une certaine variabilité. La documentation doit être écrite avec soin. vous ne pouvez pas dire aux gens "regardez le code source" parce que le code source n'y est pas encore. C'est tout l'effort. Si je ne m'attends pas à ce qu'une classe soit sous-classée, c'est un effort inutile. "final" dit clairement que cet effort n'a pas été fait et donne un avertissement juste.
la source
Une chose à laquelle vous n’avez peut-être pas pensé est le fait que TOUT changement de classe signifie qu’elle doit subir de nouveaux tests d’AQ.
Ne marquez pas les choses comme définitives à moins que vous ne le pensiez vraiment.
la source
final
(un changement) alors je dois juste la tester à nouveau?final
. Est-ce une expérience de première main?final
classe a un cas d'utilisation principal. Vous avez des classes polymorphes que vous ne souhaitez pas étendre, car une sous-classe peut rompre le polymorphisme. Ne pas utiliserfinal
sauf si vous devez empêcher la création de sous-classes. Sinon, c'est inutile.Utiliser 'final' enlève la liberté à ceux qui veulent utiliser votre code.
Si le code que vous écrivez est uniquement pour vous et ne sera jamais divulgué au public ou à un client, vous pouvez faire avec votre code ce que vous voulez, bien sûr. Sinon, vous empêchez les autres de tirer parti de votre code. Trop souvent, j'ai dû travailler avec une API qu'il aurait été facile d'étendre à mes besoins, mais j'ai été gênée par la «finale».
En outre, il y a souvent du code qui devrait mieux ne pas être fait
private
, maisprotected
. Bien sûr,private
signifie "encapsulation" et masque les éléments considérés comme des détails de mise en oeuvre. Mais en tant que programmeur d'API, je pourrais aussi bien documenter le fait que la méthodexyz
est considérée comme un détail d'implémentation et qu'elle peut donc être modifiée / supprimée dans une version ultérieure. Ainsi, toute personne qui compte sur ce code malgré l'avertissement le fait à ses risques et périls. Mais il peut réellement le faire et réutiliser du code (espérons-le déjà testé) et trouver plus rapidement une solution.Bien sûr, si l'implémentation de l'API est open source, vous pouvez simplement supprimer la 'finale' ou rendre les méthodes 'protégées', mais vous avez changé le code et devez suivre vos modifications sous forme de correctifs.
Cependant, si l'implémentation est une source fermée, il vous est difficile de trouver une solution de contournement ou, dans le pire des cas, de passer à une autre API avec moins de restrictions quant aux possibilités de personnalisation / extension.
Notez que je ne trouve pas que "final" ou "private" soient diaboliques, mais je pense qu'ils sont juste utilisés trop souvent parce que le programmeur n'a pas pensé à son code en termes de réutilisation et d'extension de code.
la source