Nach dem Lesen diese Beschreibung der späten statischen Bindung (LSB) Ich sehe ziemlich deutlich was vor sich geht. Nun, unter welchen Umständen könnte das am nützlichsten oder nötig sein?
Ich brauchte LSB für das folgende Szenario:
Wenn Sie mehr über das Thema erfahren möchten:
Ein Hauptanliegen, das ich für die späte statische Bindung habe, ist eine Reihe von statischen Methoden zur Instanzerstellung.
Diese DateAndTime-Klasse ist Teil einer Chronologiebibliothek, in die ich portiert habe PHP von Smalltalk / Squeak. Die Verwendung von statischen Instanzenerstellungsmethoden ermöglicht das Erstellen von Instanzen mit einer Vielzahl von Argumenttypen, während die Parameterprüfung in der statischen Methode beibehalten wird, sodass der Benutzer der Bibliothek keine Instanz abrufen kann, die nicht vollständig gültig ist.
Eine späte statische Bindung ist in diesem Fall nützlich, damit die Implementierungen dieser statischen Instanzerstellungsmethoden bestimmen können, auf welche Klasse ursprünglich der Aufruf angewendet wurde. Hier ist ein Anwendungsbeispiel:
Mit LSB:
%Vor%Ohne späte statische Bindung [wie in meiner aktuellen Implementierung] muss jede Klasse jede Instanzerstellungsmethode wie in diesem Beispiel implementieren:
Ohne LSB:
%Vor%Da die Anzahl der Instanzen-Erstellungsmethoden und Klassenhierarchie zunimmt, wird die Duplizierung von Methoden zu einem echten Schmerz im Hintern. LSB reduziert diese Duplizierung und ermöglicht viel sauberere und einfachere Implementierungen.
Es ist nützlich, wenn:
Sie haben Funktionen, die über die Klassenhierarchie variieren,
Die Funktionalität hat die gleiche Signatur über die Hierarchie und
(wichtig) Sie haben keine Instanz, von der die Funktionalität abhängen kann.
Wenn nur # 1 und # 2 erhalten würden, würden Sie eine gewöhnliche Instanzmethode verwenden. Alex 'Problem (siehe seine Antwort auf diese Frage) erfordert kein LSB.
Ein typischer Fall ist die Objekterstellung, bei der Unterklassen sich selbst auf unterschiedliche Weise erstellen, aber dieselben Parameter verwenden. Offensichtlich haben Sie keine Instanz zum Aufrufen, daher muss die Erstellungsmethode (auch Factory-Methode genannt) statisch sein. Sie möchten jedoch, dass sich das Verhalten abhängig von der Unterklasse ändert, sodass eine gewöhnliche statische Methode nicht richtig ist. Siehe Adam Francos Antwort für ein Beispiel.
Wenn Sie auf eine überladene statische Eigenschaft / Methode innerhalb einer Methode zugreifen müssen, die in einer Unterklasse nicht überladen wurde, benötigen Sie eine späte statische Bindung. Ein kurzes Beispiel: paste2.org
Das klassische Beispiel ist die ActiveRecord-Klasse von Rails, wenn Sie versuchen, etwas Ähnliches in PHP zu implementieren, das wie folgt aussehen würde: class User extends ActiveRecord
und dann User::find(1)
aufrufen Die Methode, die aufgerufen wird, ist tatsächlich ActiveRecord::find()
weil du find()
in User
nicht überladen hast - aber ohne späte statische Bindung hat die find()
Methode in ActiveRecord
keine Möglichkeit zu wissen, aus welcher Klasse sie aufgerufen wurde ( self
darin zeigt immer auf ActiveRecord
) und kann daher Ihr User-Objekt nicht für Sie abrufen.
Angenommen, Sie haben Klassen, die Tabellen (Zeileninstanzen) in einem vereinfachten objektrelationalen Mapper darstellen. Sie hätten eine Klasse "Benutzer" und eine Klasse "Firma", deren Instanzen Zeilen der jeweiligen Tabellen darstellen. Benutzer und Firma würden von einer Basis-abstrakten Klasse erben, sagen wir "BaseObject", die einige gebräuchliche Methoden wie save (), delete (), validate () usw. haben wird ...
Wenn Sie Daten über die Validierung und die Tabellendefinition speichern möchten, wäre die beste Stelle in einer statischen Variablen in jeder abgeleiteten Klasse - da die Validierung und die Tabellendefinition für jede Instanz von User gleich ist.
Ohne LSB hätte die genannte validate () -Methode in BaseObject keinen Verweis auf die in User und Company definierten statischen Variablen, obwohl Sie sie über eine Instanz von User aufrufen. Es sucht nach der gleichen statischen Variable in der BaseObject-Klasse und es wird ein Fehler ausgelöst.
Das ist meine Erfahrung mit PHP 5.2.8 - LSB wird in 5.3 eingeführt.
Ich habe eine Klasse mit einer statischen Methode, die einige Formatierungen verarbeitet. Ich habe eine andere Klasse, die als die gesamte Funktionalität des Originals benötigt, außer für die Formatierung.