PHP-Schnittstellen ermöglichen die Definition von Konstanten in einer Schnittstelle, z
interface FooBar
{
const FOO = 1;
const BAR = 2;
}
echo FooBar::FOO; // 1
Für jede implementierende Klasse stehen diese Konstanten automatisch zur Verfügung, z
class MyFooBar implement FooBar
{
}
echo MyFooBar::FOO; // 1
Ich gehe davon aus, dass alles, was global ist, böse ist . Aber ich frage mich, ob das auch für Schnittstellenkonstanten gilt. Ist die Verwendung von Schnittstellenkonstanten angesichts der Tatsache, dass das Codieren gegen eine Schnittstelle im Allgemeinen als bewährte Methode angesehen wird, die einzige Konstante, die außerhalb eines Klassenkontexts verwendet werden kann?
Ich bin zwar neugierig auf Ihre persönliche Meinung und darauf, ob Sie Schnittstellenkonstanten verwenden oder nicht, aber ich suche in Ihren Antworten hauptsächlich nach objektiven Gründen. Ich möchte nicht, dass dies eine Frage vom Typ Umfrage ist. Ich bin daran interessiert, welche Auswirkungen die Verwendung von Schnittstellenkonstanten auf die Wartbarkeit hat. Kupplung. Oder Unit Testing. Wie hängt es mit SOLID PHP zusammen? Verstößt es gegen Kodierungsprinzipien, die in PHP als bewährte Verfahren gelten? Du hast die Idee …
Hinweis: Es gibt eine ähnliche Frage für Java , in der einige gute Gründe aufgeführt sind, warum es sich um schlechte Praktiken handelt. Da Java jedoch kein PHP ist, hielt ich es für gerechtfertigt, sie erneut innerhalb des PHP-Tags zu stellen.
Antworten:
Nun, ich denke, dass es auf den Unterschied zwischen gut und gut genug hinausläuft .
Während Sie in den meisten Fällen die Verwendung von Konstanten vermeiden können, indem Sie andere Muster (Strategie oder möglicherweise Fliegengewicht) implementieren, gibt es etwas zu sagen, wenn Sie nicht ein halbes Dutzend anderer Klassen benötigen, um ein Konzept darzustellen. Ich denke, es läuft darauf hinaus, wie wahrscheinlich es ist, dass andere Konstanten benötigt werden. Mit anderen Worten, muss die durch die Konstanten auf der Schnittstelle bereitgestellte ENUM erweitert werden. Wenn Sie vorhersehen können, dass es erweitert werden muss, wählen Sie ein formelleres Muster. Wenn nicht, kann es ausreichen (es ist gut genug und daher weniger Code zum Schreiben und Testen). Hier ist ein Beispiel für eine gute und eine schlechte Verwendung:
Schlecht:
Gut genug:
Der Grund, warum ich diese Beispiele gewählt habe, ist einfach. Die
User
Schnittstelle definiert eine Aufzählung von Benutzertypen. Dies wird sich mit der Zeit sehr wahrscheinlich ausdehnen und wäre durch ein anderes Muster besser geeignet. DiesHTTPRequest_1_1
ist jedoch ein anständiger Anwendungsfall, da die Aufzählung durch RFC2616 definiert wird und sich während der Lebensdauer der Klasse nicht ändert.Im Allgemeinen sehe ich das Problem mit Konstanten und Klassenkonstanten nicht als globales Problem. Ich sehe es als Abhängigkeitsproblem. Es ist eine enge Unterscheidung, aber eine bestimmte. Ich sehe globale Probleme als globale Variablen, die nicht erzwungen werden und als solche eine weiche globale Abhängigkeit erzeugen. Eine fest codierte Klasse erzeugt jedoch eine erzwungene Abhängigkeit und als solche eine harte globale Abhängigkeit. Beides sind also Abhängigkeiten. Aber ich halte das Globale für weitaus schlimmer, da es nicht erzwungen wird ... Deshalb möchte ich Klassenabhängigkeiten nicht gerne mit globalen Abhängigkeiten unter demselben Banner zusammenfassen ...
Wenn Sie schreiben
MyClass::FOO
, sind Sie fest mit den Implementierungsdetails von codiertMyClass
. Dies führt zu einer harten Kopplung, die Ihren Code weniger flexibel macht und daher vermieden werden sollte. Es gibt jedoch Schnittstellen, um genau diese Art der Kopplung zu ermöglichen. FührtMyInterface::FOO
daher keine konkrete Kupplung ein. Vor diesem Hintergrund würde ich keine Schnittstelle einführen, nur um eine Konstante hinzuzufügen.Wenn Sie also Schnittstellen verwenden und sehr sicher sind, dass Sie (oder sonst jemand) keine zusätzlichen Werte benötigen, sehe ich kein großes Problem mit den Schnittstellenkonstanten ... Das Beste Entwürfe würden keine Konstanten oder Bedingungen oder magische Zahlen oder magische Zeichenketten oder fest codierte Elemente enthalten. Dies verlängert jedoch die Entwicklungszeit zusätzlich, da Sie die Verwendungszwecke berücksichtigen müssen. Meiner Ansicht nach lohnt es sich meistens, sich die zusätzliche Zeit zu nehmen, um ein großartiges, solides Design zu erstellen. Aber es gibt Zeiten, in denen gut genug wirklich akzeptabel ist (und es braucht einen erfahrenen Entwickler, um den Unterschied zu verstehen), und in diesen Fällen ist es in Ordnung.
Auch das ist nur meine Ansicht dazu ...
quelle
Ich denke, dass es normalerweise besser ist, Konstanten, speziell aufgezählte Konstanten, als separaten Typ ("Klasse") von Ihrer Schnittstelle zu behandeln:
oder, wenn Sie eine Klasse als Namespace verwenden möchten:
Es ist nicht so, dass Sie nur Konstanten verwenden, Sie verwenden das Konzept von Aufzählungswerten oder Aufzählungen, bei denen eine Reihe von eingeschränkten Werten als ein bestimmter Typ mit einer bestimmten Verwendung ("Domäne"?) Betrachtet wird.
quelle