Интерфейсы PHP позволяют определять константы в интерфейсе, например
interface FooBar
{
const FOO = 1;
const BAR = 2;
}
echo FooBar::FOO; // 1
Любой реализующий класс будет автоматически иметь эти константы, например
class MyFooBar implement FooBar
{
}
echo MyFooBar::FOO; // 1
Я считаю, что все Глобальное - зло . Но мне интересно, применимо ли то же самое к константам интерфейса. Учитывая, что кодирование на основе интерфейса в целом считается хорошей практикой, является ли использование констант интерфейса единственными константами, которые можно использовать вне контекста класса?
Хотя мне любопытно услышать ваше личное мнение и используете ли вы константы интерфейса или нет, я в основном ищу в ваших ответах объективные причины. Я не хочу, чтобы это был вопрос типа опроса. Меня интересует, как использование констант интерфейса влияет на ремонтопригодность. Связь. Или модульное тестирование. Как это связано с SOLID PHP? Нарушает ли это какие-либо принципы кодирования, которые считаются хорошей практикой в PHP? Вы уловили идею ...
Примечание: есть аналогичный вопрос для Java, в котором перечислены некоторые довольно веские причины, почему они являются плохой практикой, но, поскольку Java не является PHP, я счел оправданным задать его снова в теге PHP.
Ответы:
Что ж, я думаю, что все сводится к разнице между хорошим и достаточно хорошим .
Хотя в большинстве случаев вы можете избежать использования констант, реализовав другие шаблоны (стратегию или, возможно, легковес), есть кое-что, что нужно сказать о том, что для представления концепции не требуется полдюжины других классов. Я думаю, что все сводится к тому, насколько вероятно, что нужны другие константы. Другими словами, есть ли необходимость в расширении ENUM, предоставляемого константами в интерфейсе. Если вы можете предвидеть необходимость его расширения, выберите более формальный образец. Если нет, то этого может быть достаточно (это будет достаточно хорошо, и, следовательно, будет меньше кода для написания и тестирования). Вот пример хорошего и плохого использования:
Плохой:
Достаточно хорошо:
Причина, по которой я выбрал эти примеры, проста.
User
Интерфейс является определяющим перечисление типов пользователей. Очень вероятно, что со временем он расширится, и ему лучше подходит другой шаблон. НоHTTPRequest_1_1
это достойный вариант использования, поскольку перечисление определено RFC2616 и не будет изменяться в течение всего времени существования класса.В общем, я не считаю проблему с константами и константами классов глобальной проблемой. Я вижу в этом проблему зависимости. Это узкое различие, но определенное. Я вижу глобальные проблемы, например, в глобальных переменных, которые не применяются принудительно, и как таковые создают мягкую глобальную зависимость. Но жестко запрограммированный класс создает принудительную зависимость и, таким образом, создает жесткую глобальную зависимость. Итак, оба являются зависимостями. Но я считаю, что глобальное намного хуже, поскольку оно не применяется ... Вот почему я не люблю объединять зависимости классов с глобальными зависимостями под одним и тем же баннером ...
Если вы пишете
MyClass::FOO
, вы жестко запрограммированы на детали реализацииMyClass
. Это создает жесткую связь, которая делает ваш код менее гибким, и поэтому его следует избегать. Однако существуют интерфейсы, позволяющие осуществлять именно такой тип связи. ПоэтомуMyInterface::FOO
не вводит никакой конкретной связи. С учетом сказанного, я бы не стал вводить интерфейс просто для добавления к нему константы.Так что, если вы используете интерфейс, и вы очень уверены , что вы (или кто -либо еще в этом отношении) не нужны дополнительные значения, то я не вижу большой проблемы с константами интерфейса ... Лучший конструкции не будут содержать никаких констант, условных операторов, магических чисел, магических строк или чего-либо жестко запрограммированного. Однако это добавляет дополнительное время для разработки, так как вы должны учитывать варианты использования. Я считаю, что в большинстве случаев абсолютно необходимо потратить дополнительное время на создание отличного надежного дизайна. Но бывают случаи, когда достаточно хорошее действительно приемлемо (и требуется опытный разработчик, чтобы понять разницу), и в таких случаях это нормально.
Опять же, это только мой взгляд на это ...
источник
Я думаю, что обычно лучше обрабатывать константы, специально перечисленные константы, как отдельный тип («класс») от вашего интерфейса:
или, если вы хотите использовать класс в качестве пространства имен:
Дело не в том, что вы используете только константы, вы используете концепцию перечисляемых значений или перечислений, которые представляют собой набор ограниченных значений, которые считаются определенным типом с определенным использованием («домен»?)
источник