Eu estava olhando o framework Caliburn.Micro do WPF MVVM e li que muitas coisas padrão são baseadas em convenções de nomenclatura .
Por exemplo, ligação automática de propriedades no View para propriedades no ViewModel. Embora isso pareça conveniente (remove algum código padrão), minha primeira reação instintiva é que não é completamente óbvio para um novo programador que lerá esse código. Em outras palavras, a funcionalidade do aplicativo não é completamente explicada por seu próprio código, mas também pela documentação da estrutura.
EDITAR:
Portanto, essa abordagem é chamada de convenção sobre configuração. Como não consegui encontrar nenhuma pergunta sobre isso, alterei minha pergunta:
Minha pergunta é:
A convenção sobre configuração é uma maneira correta de simplificar as coisas ou está violando alguns princípios de programação (e, em caso afirmativo, quais)?
fonte
Respostas:
Não considero "um aplicativo deve ser totalmente explicado por seu próprio código" como um princípio fundamental de programação. Há muitas coisas que não são explicadas apenas olhando o código de um aplicativo. Além de conhecer as coisas básicas da própria linguagem de programação (sintaxe e semântica), você precisa conhecer as convenções. Se um identificador em Java começa com uma letra maiúscula, é um tipo. Existem muitas dessas convenções que você precisa conhecer.
A convenção sobre configuração consiste em reduzir a quantidade de decisões que o programador precisa tomar sobre as coisas. Para algumas coisas, isso é óbvio - ninguém consideraria ter um idioma em que a capitalização de tipos é algo que você precisa declarar no topo do seu programa - mas, para outras coisas, não é tão óbvio.
Equilibrar convenções e configurações é uma tarefa difícil. Muitas convenções podem tornar o código confuso (veja as variáveis implícitas do Perl, por exemplo). Muita liberdade do lado do programador pode dificultar a compreensão dos sistemas, pois o conhecimento adquirido em um sistema raramente é útil quando se estuda outro.
Um bom exemplo de onde a convenção ajuda o programador é ao escrever plugins do Eclipse. Ao olhar para um plugin que eu nunca vi, eu imediatamente sei muitas coisas sobre ele. A lista de dependências está em MANIFEST.MF, os pontos de extensão estão em plugin.xml, o código-fonte está em "src" e assim por diante. Se essas coisas dependessem do programador definir, cada plug-in Eclipse seria diferente e a navegação de código seria muito mais difícil.
fonte
Deu +1 ao @JesperE e gostaria de adicionar algo:
Sim, "convenção sobre configuração" viola o princípio "explícito é melhor que implícito" (veja, por exemplo, "Zen-Of-Python" ).
Por outro lado, a "configuração sobre convenção" oposta tende a violar "Simples é melhor que complexo" e, pior, viola o princípio DRY de maneira sutil, já que você precisa repetir nomes usados no seu código também na sua configuração .
fonte
Algumas das "convenções sobre configuração" se resumem a padrões sensíveis. Você só precisa configurar algo para usá-lo para fins não padronizados. Eu tenho que comparar Struts com Rails aqui. No Rails, você precisa colocar suas "ações / telas" em uma pasta e elas simplesmente funcionam. No Struts, você ainda precisa colocá-los em uma pasta, mas também precisa criar um nome de ação E um arquivo JSP E um nome de formulário E um bean de formulário E especificar como essas três coisas funcionam juntas no Struts-config. xml AND especifique que o formulário pertence à solicitação (RESTful). Se isso não for suficiente, o mapeamento form / form-bean possui sua própria seção no Struts-config, que é mapeada independentemente para a seção de ação no mesmo arquivo e tudo depende de cadeias de caracteres manuscritas no arquivo JSP para funcionar. devidamente. Para cada tela, são pelo menos seis coisas que você não precisa fazer e tantas oportunidades para cometer um erro. Eu acho que você pode definir a maioria ou todas essas coisas manualmente no Rails, se necessário, mas 2/3 do tempo de desenvolvimento do Struts é gasto na construção e manutenção de camadas desnecessárias de complexidade.
Com toda a justiça, o Struts 1 foi projetado quando as pessoas estavam transportando aplicativos entre a área de trabalho e a web. A flexibilidade que o Struts adotou o torna adequado para tudo o que o Rails faz, além de tudo o que um aplicativo de desktop precisaria. Infelizmente, a montanha de configurações que permite essa flexibilidade é uma grande força para quem precisa escrever um aplicativo da Web ou apenas um aplicativo de desktop.
Eu trabalhei em algum lugar em que eles deram o próximo passo e argumentaram: "Configuração sobre código ", mas tendo visto isso levado ao extremo lógico, o resultado é que a configuração se torna uma nova linguagem de codificação. Era um jogo de shell em que a complexidade era contornada sem ser domada de maneira significativa. E isso me agradeceu por todas as redes de verificação de tipo e outras redes de segurança que uma linguagem de programação bem projetada possui. Algum formato de arquivo de configuração incompleto que explode sem nenhuma mensagem de erro se você adicionar um espaço ou um apóstrofo NÃO é uma melhoria em relação a uma linguagem de programação de qualidade que possui conjuntos de ferramentas de edição e um compilador de qualidade criado para ele.
Não posso imaginar que ter padrões sensíveis viole quaisquer princípios teóricos sobre extensibilidade e modularidade. Um programador de Ruby / Rails mais cedo espetaria um pôquer quente nos olhos do que mudaria para um framework como o Struts 1, onde todas as configurações são feitas explicitamente em vários arquivos XML. Não estou discutindo Rails vs. Struts EM GERAL, mas essa convenção pode ser uma enorme vitória na produtividade. Essas duas tecnologias são a comparação mais extrema do mundo real que eu já vi.
Se você trabalha com Java, consulte Joshua Bloch, "Effective Java", Item 2: "Considere um construtor quando confrontado com muitos parâmetros de construtor", pp. 11-16. Para a maioria dos propósitos, alguns parâmetros (configuração) são necessários e outros são opcionais. A idéia básica é exigir apenas a configuração necessária e fazer com que o usuário (que poderia ser outro programa) especifique opções adicionais, conforme necessário. Limpei um monte de código com esse padrão há um mês e ele brilha positivamente.
fonte
A funcionalidade de um aplicativo que usa uma estrutura sempre depende da estrutura; a convenção sobre a configuração não faz diferença nesse sentido.
Na minha experiência, a convenção sobre configuração não apenas torna o código mais legível, mas também reduz a possibilidade de introduzir bugs sutis (especialmente copiar-colar-bugs).
Por exemplo, vamos assumir que, em alguma estrutura A, o evento
FooBar
dispara uma chamada parahandleFooBar
. Em outra estrutura B, essa correlação é configurada em algum lugar de um arquivo XML.Então, em A, é simplesmente
e, a menos que você tenha digitado incorretamente o FooBar, ele será chamado sempre que o FooBar acontecer.
Em B, é novamente
mas também
Com centenas de coisas para configurar dessa maneira, é muito fácil criar acidentalmente um bug sutil como
porque depois de copiar e colar, apenas mudamos,
<type>
mas esquecemos de mudar<handler>
.Como esses arquivos de configuração são grandes e monótonos, é menos provável que alguém encontre o bug revisando do que encontraria um bug semelhante no código real do programa.
fonte
Pode estar violando poucos princípios, mas ao mesmo tempo obedece a um dos princípios mais fundamentais de design, o SRP (princípio de responsabilidade única).
fonte