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:
interface User {
const TYPE_ADMINISTRATOR = 1;
const TYPE_USER = 2;
const TYPE_GUEST = 3;
}
Gut genug:
interface HTTPRequest_1_1 {
const TYPE_CONNECT = 'connect';
const TYPE_DELETE = 'delete';
const TYPE_GET = 'get';
const TYPE_HEAD = 'head';
const TYPE_OPTIONS = 'options';
const TYPE_POST = 'post';
const TYPE_PUT = 'put';
public function getType();
}
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. Dies HTTPRequest_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 codiert MyClass
. 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ührt MyInterface::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 ...