Ich überarbeite eine PHP OOP-Legacy-Website.
Ich bin so versucht, 'final' für Klassen zu " make it explicit that the class is currently not extended by anything
" zu verwenden. Dies kann viel Zeit sparen, wenn ich zu einer Klasse komme und mich frage, ob ich eine protected
Eigenschaft oder Methode umbenennen, löschen oder ändern kann. Wenn ich eine Klasse wirklich erweitern möchte, kann ich einfach das letzte Schlüsselwort entfernen, um es für die Erweiterung freizuschalten .
Dh wenn ich zu einer Klasse komme, die keine Kinderklassen hat, kann ich dieses Wissen aufzeichnen, indem ich der Klasse ein Finale markiere. Wenn ich das nächste Mal darauf komme, muss ich die Codebasis nicht erneut durchsuchen, um festzustellen, ob sie Kinder hat. So sparen Sie Zeit bei Umbauten.
Es scheint alles eine sinnvolle zeitsparende Idee zu sein ... aber ich habe oft gelesen, dass der Unterricht nur zu seltenen / besonderen Anlässen "endgültig" sein sollte.
Vielleicht macht es die Erstellung von Mock-Objekten kaputt oder hat andere Nebenwirkungen, an die ich nicht denke.
Was vermisse ich?
quelle
Antworten:
Wer das geschrieben hat, ist falsch. Verwendung
final
großzügig, es gibt nichts falsch mit dem. Es wird dokumentiert, dass eine Klasse nicht unter Berücksichtigung der Vererbung entworfen wurde. Dies gilt normalerweise standardmäßig für alle Klassen: Das Entwerfen einer Klasse, die sinnvoll geerbt werden kann, erfordert mehr als nur das Entfernen einesfinal
Bezeichners. es braucht viel Sorgfalt.So verwenden
final
ist standardmäßig auf keinen Fall schlecht. Tatsächlich schlagen viele Leute vor, dass dies die Standardeinstellung sein sollte, z . B. Jon Skeet .Dies ist in der Tat eine Einschränkung, aber Sie können immer auf Schnittstellen zurückgreifen, wenn Sie Ihre Klassen verspotten müssen. Dies ist sicherlich überlegen, wenn alle Klassen nur zum Zwecke des Verspottens für die Vererbung freigegeben werden.
quelle
final
eine viel größere Rolle spielen würde.Wenn Sie sich selbst eine Notiz machen möchten, dass eine Klasse keine Unterklassen hat, dann tun Sie dies auf jeden Fall und verwenden Sie einen Kommentar, dafür sind sie da. Das "letzte" Schlüsselwort ist kein Kommentar, und die Verwendung von Sprachschlüsselwörtern, um Ihnen etwas zu signalisieren (und nur Sie würden jemals wissen, was es bedeutet), ist eine schlechte Idee.
quelle
final
wie erwartet verwendet. Daran ist nichts auszusetzen. Die Verwendung einer Sprachfunktion zum Erzwingen einer Einschränkung ist der Verwendung eines Kommentars immer überlegen.final
sollte "Keine Unterklasse dieser Klasse sollte jemals erstellt werden" (aus rechtlichen Gründen oder so), nicht "Diese Klasse hat derzeit keine Kinder, daher kann ich mich immer noch sicher mit ihren geschützten Mitgliedern anlegen". Die Absicht vonfinal
ist das Gegenteil von "frei editierbar", und einefinal
Klasse sollte nicht einmalprotected
Mitglieder haben!final
bedeutet: „Diese Klasse darf [vorerst] nicht erweitert werden.“ Nicht mehr und nicht weniger. Ob PHP unter Berücksichtigung dieser Philosophie entwickelt wurde, ist unerheblich: Es hat schließlich dasfinal
Schlüsselwort. Zweitens wird das Argumentieren von PHPs Design scheitern, wenn man bedenkt, wie patchworkig und insgesamt schlecht PHP gestaltet ist.Es gibt einen schönen Artikel über "Wann sind die Klassen für endgültig zu erklären?" . Ein paar Zitate daraus:
PS Danke an @ocramius für die großartige Lektüre!
quelle
"final" für eine Klasse bedeutet: Sie wollen eine Unterklasse? Gehen Sie weiter, löschen Sie die "letzte" Unterklasse so oft Sie möchten, aber beschweren Sie sich nicht bei mir, wenn es nicht funktioniert. Du bist auf dich allein gestellt.
Wenn eine Klasse in Unterklassen unterteilt werden kann, muss das Verhalten, auf das sich andere verlassen, in abstrakten Begriffen beschrieben werden, die Unterklassen gehorchen. Anrufer müssen geschrieben sein, um eine gewisse Variabilität zu erwarten. Dokumentation muss sorgfältig geschrieben werden; Sie können den Leuten nicht sagen, dass sie sich den Quellcode ansehen sollen, da der Quellcode noch nicht vorhanden ist. Das ist alles Anstrengung. Wenn ich nicht erwarte, dass eine Klasse einer Unterklasse angehört, ist das unnötiger Aufwand. "final" sagt deutlich, dass diese Anstrengung nicht unternommen wurde und gibt eine faire Warnung.
quelle
Eine Sache, an die Sie vielleicht nicht gedacht haben, ist die Tatsache, dass JEDER Klassenwechsel bedeutet, dass er neuen QS-Tests unterzogen werden muss.
Kennzeichnen Sie Dinge nur dann als endgültig, wenn Sie es wirklich ernst meinen.
quelle
final
(eine Änderung) markiere, muss ich sie nur erneut testen?final
. Ist das Erfahrung aus erster Hand?final
Klasse hat einen primären Anwendungsfall. Sie haben polymorphe Klassen, die Sie nicht erweitern möchten, da eine Unterklasse den Polymorphismus unterbrechen kann. Verwendenfinal
Sie diese Option nur, wenn Sie die Erstellung von Unterklassen verhindern müssen . Davon abgesehen ist es nutzlos.Die Verwendung von "final" nimmt anderen, die Ihren Code verwenden möchten, die Freiheit.
Wenn der von Ihnen geschriebene Code nur für Sie bestimmt ist und niemals für die Öffentlichkeit oder einen Kunden freigegeben wird, können Sie mit Ihrem Code natürlich tun, was Sie wollen. Andernfalls verhindern Sie, dass andere auf Ihrem Code aufbauen. Zu oft musste ich mit einer API arbeiten, die sich für meine Bedürfnisse leicht erweitern ließ, aber dann wurde ich durch "final" behindert.
Auch gibt es oft Code, der besser nicht gemacht werden sollte
private
, aberprotected
. Sicher,private
bedeutet "Kapselung" und versteckt Dinge, die als Implementierungsdetails angesehen werden. Als API-Programmierer kann ich jedoch auch die Tatsache dokumentieren, dass die Methodexyz
als Implementierungsdetail betrachtet wird und daher in zukünftigen Versionen möglicherweise geändert / gelöscht wird. Jeder, der sich trotz der Warnung auf solchen Code verlässt, tut dies auf eigenes Risiko. Aber er kann es tatsächlich tun und den (hoffentlich bereits getesteten) Code wiederverwenden und schneller eine Lösung finden.Wenn die API-Implementierung Open Source ist, kann man natürlich einfach die 'final' entfernen oder Methoden 'protected' machen, aber dann haben Sie den Code geändert und müssen Ihre Änderungen in Form von Patches nachverfolgen.
Wenn es sich bei der Implementierung jedoch um eine Closed-Source-Implementierung handelt, müssen Sie keine Problemumgehung finden oder im schlimmsten Fall auf eine andere API mit weniger Einschränkungen hinsichtlich der Anpassungs- / Erweiterungsmöglichkeiten wechseln.
Beachten Sie, dass ich nicht finde, dass 'final' oder 'private' böse sind, aber ich denke, sie werden einfach zu oft verwendet, weil der Programmierer nicht über seinen Code nachgedacht hat, was die Wiederverwendung und Erweiterung von Code betrifft.
quelle