As interfaces PHP permitem a definição de constantes em uma interface, por exemplo
interface FooBar
{
const FOO = 1;
const BAR = 2;
}
echo FooBar::FOO; // 1
Qualquer classe de implementação terá automaticamente essas constantes disponíveis, por exemplo
class MyFooBar implement FooBar
{
}
echo MyFooBar::FOO; // 1
Minha opinião sobre isso é que qualquer coisa global é maligna . Mas eu me pergunto se o mesmo se aplica às Constantes de Interface. Dado que a codificação em relação a uma interface é considerada uma boa prática em geral, o uso de Constantes de Interface é as únicas constantes aceitáveis para uso fora de um contexto de classe?
Embora eu esteja curioso para ouvir sua opinião pessoal e se você usa constantes de interface ou não, estou procurando principalmente por razões objetivas em suas respostas. Eu não quero que esta seja uma pergunta do tipo pesquisa. Estou interessado no efeito do uso de constantes de interface na capacidade de manutenção. Acoplamento. Ou teste de unidade. Como isso se relaciona com SOLID PHP? Isso viola algum princípio de codificação considerado uma boa prática em PHP? Você entendeu a ideia …
Observação: há uma pergunta semelhante para o Java que listou alguns bons motivos pelos quais eles são uma má prática, mas, como o Java não é PHP, achei justificável perguntar novamente na tag PHP.
Respostas:
Bem, acho que tudo se resume à diferença entre bom e bom o suficiente .
Embora na maioria dos casos você possa evitar o uso de constantes implementando outros padrões (estratégia ou talvez flyweight), há algo a ser dito para não precisar de meia dúzia de outras classes para representar um conceito. Acho que tudo se resume a quão provável é a necessidade de outras constantes. Em outras palavras, é necessário estender o ENUM fornecido pelas constantes na interface. Se você pode prever a necessidade de expandi-lo, use um padrão mais formal. Caso contrário, pode ser suficiente (será bom o suficiente e, portanto, haverá menos código para escrever e testar). Aqui está um exemplo de uso bom e ruim:
Ruim:
Bom o bastante:
Agora, a razão pela qual escolhi esses exemplos é simples. A
User
interface está definindo um enum de tipos de usuário. É muito provável que isso se expanda com o tempo e seria mais adequado por outro padrão. MasHTTPRequest_1_1
é um caso de uso decente, uma vez que o enum é definido pelo RFC2616 e não mudará durante o tempo de vida da classe.Em geral, não vejo o problema com constantes e constantes de classe como sendo um problema global . Eu vejo isso como um problema de dependência. É uma distinção estreita, mas definitiva. Vejo problemas globais como em variáveis globais que não são aplicadas e, como tal, criam uma dependência global flexível. Mas uma classe codificada cria uma dependência forçada e, como tal, cria uma dependência global rígida. Portanto, ambos são dependências. Mas considero o global muito pior, já que não é obrigatório ... É por isso que não gosto de agrupar dependências de classe com dependências globais sob o mesmo banner ...
Se você escrever
MyClass::FOO
, estará codificado com os detalhes de implementação deMyClass
. Isso cria um acoplamento rígido, o que torna seu código menos flexível e, como tal, deve ser evitado. No entanto, existem interfaces que permitem exatamente esse tipo de acoplamento. PortantoMyInterface::FOO
, não introduz nenhum acoplamento concreto. Dito isso, eu não apresentaria uma interface apenas para adicionar uma constante a ela.Então, se você estiver usando interfaces, e você está muito certo de que você (ou qualquer outra pessoa para essa matéria) não vai precisar de valores adicionais, então eu realmente não vejo um enorme problema com as constantes de interface ... O melhor os designs não incluiriam quaisquer constantes ou condicionais ou números mágicos ou strings mágicas ou qualquer coisa codificada. No entanto, isso adiciona mais tempo ao desenvolvimento, pois você deve considerar os usos. Minha opinião é que na maioria das vezes vale a pena dedicar um tempo adicional para construir um design sólido e excelente. Mas há momentos em que bom o suficiente é realmente aceitável (e é preciso um desenvolvedor experiente para entender a diferença) e, nesses casos, tudo bem.
Novamente, essa é apenas minha opinião sobre isso ...
fonte
Acho que geralmente é melhor lidar com constantes, especialmente constantes enumeradas, como um tipo separado ("classe") de sua interface:
ou, se você quiser usar uma classe como um namespace:
Não é que você esteja usando apenas constantes, você está usando o conceito de valores enumerados ou enumerações, que um conjunto de valores restritos são considerados um tipo específico, com um uso específico ("domínio"?)
fonte