Recentemente, tive uma discussão com um colega sobre o estilo do código. Ele estava argumentando que o uso de APIs e os padrões gerais que você está usando devem ser o mais semelhante possível com o código circundante, se não com a base de código como um todo, da mesma forma que faria com a aparência do código (posicionamento da chave, letras maiúsculas etc.) . Por exemplo, se eu estivesse adicionando um método a uma classe DAO em C #, tentaria usar o LINQ, quando apropriado, para ajudar a tornar meu código limpo e fácil de manter, mesmo que nenhum dos outros métodos dessa classe o estivesse usando. No entanto, meu colega argumentaria que eu não deveria usá-lo nesse caso, porque seria contra o estilo existente dessa classe e, portanto, mais difícil de entender.
A princípio, achei sua posição bastante extrema, mas, depois de pensar um pouco, estou começando a entender seu ponto de vista. Com o exemplo hipotético do LINQ, talvez essa classe não a contenha porque meus colegas não estão familiarizados com o LINQ? Nesse caso, meu código não seria mais sustentável para meus colegas desenvolvedores se eu não o usasse? Por outro lado, se eu realmente acredito que o uso de uma técnica desse tipo resultaria em um código mais limpo, não deveria usá-lo, mesmo que diferisse drasticamente do código ao redor?
Eu acho que o ponto crucial do argumento do meu colega é que, se todos nós implementamos funcionalidades semelhantes em uma base de código de maneiras diferentes, e cada um de nós acha que o nosso caminho é "melhor", no final, o código como um todo fica mais difícil para entender. No entanto, no momento, ainda acho que, se seguirmos cegamente o código existente, a qualidade irá apodrecer lentamente ao longo do tempo.
Então, até que ponto os padrões fazem parte do estilo do código e onde devemos traçar a linha entre permanecer consistente e fazer melhorias?
fonte
IEnumerable
s em vez de com um DAO.Respostas:
Para dar uma resposta mais geral:
Em um caso como esse, você tem duas "práticas recomendadas" de programação que se opõem: a consistência do código é importante, mas a escolha do melhor método possível para realizar sua tarefa. Não há uma resposta correta para esse dilema; depende de alguns fatores:
Quão benéfico é o caminho "correto"?
Qual o tamanho de um problema que a inconsistência criaria?
Com base no equilíbrio desses problemas, você deve fazer a escolha certa sobre qual caminho seguir. Pessoalmente, vejo pouco valor em consistência por causa da consistência e preferiria usar os melhores e mais recentes métodos, a menos que haja um custo significativo para isso.
Obviamente, existe uma terceira opção: reescrever o código existente para que ele use os melhores métodos e seja consistente. Há momentos em que isso é necessário, mas vem com um custo alto.
fonte
Permanecer consistente tem pouco valor na minha perspectiva; fazer melhorias continuamente é uma obrigação.
A posição do seu colega realmente impede a inovação. O argumento de consistência leva você a uma situação em que você pode usar, por exemplo, o LINQ apenas se você migrar todo o código para usar o LINQ. E bem, não temos tempo para isso, temos?
Eu prefiro ter inconsistência em que algum código ainda está sendo
foreach
executado sobre ArrayLists e outras partes usam o LINQIEnumerable<T>
, em vez de seguir a maneira mais antiga de fazer as coisas até o final dos tempos.É responsabilidade dos seus colegas permanecer relevantes e aprender novas maneiras de fazer as coisas.
fonte
A consistência da API é muito importante, tanto para APIs públicas quanto internas.
A consistência da formatação do código é importante e, idealmente, deve ser aplicada pela ferramenta de formatação automática com as mesmas regras de formatação para todos. Facilita a convivência com a base de código compartilhada controlada por versão.
As convenções de nomenclatura devem ser consistentes, também para coisas como variáveis locais etc.
As ferramentas de análise estática devem ser usadas para impor certas outras convenções e boas práticas (mas não seguem cegamente os padrões de tal ferramenta, às vezes os padrões podem parecer insanos), embora se algo exigir, não tenha medo de desativar alguns verifique (normalmente com uma diretiva dentro de um comentário) temporariamente, se você pode justificá-lo.
O que acontece nas funções / métodos , além do listado acima, não precisa ser consistente de forma alguma, desde que seja um bom código por si só . Um código bom, compreensível e bem comentado é muito importante, mas depois disso, se as ferramentas de análise estática e de compilador acharem que é um código consistente, isso é consistente o suficiente.
Sobre os novos recursos de idioma, como o LINQ (bem, isso não é exatamente novo), a única coisa que precisa ser considerada é: será que uma nova versão suficiente da linguagem / bibliotecas será usada em qualquer lugar onde o código será usado? Em caso de dúvida, atenha-se aos recursos que são conhecidos por serem compatíveis. Obviamente, isso não impede que você faça uma atualização de versão em todo o sistema, para poder começar a usar as novas coisas legais.
E todo desenvolvedor que trabalha com código deve se manter atualizado, para que qualquer desenvolvedor .NET conheça o LINQ e, caso contrário, seja forçado a aprender, para seu próprio bem (você nunca sabe quando procurará um novo emprego neste negócio, por um motivo ou outro).
fonte
A resposta pra isso é simples.
A consistência é de suma importância.
mas vem com uma ressalva ...
Você e seu colega de trabalho provavelmente estão obcecados com o tipo errado de consistência
As implementações são descartáveis. Eles podem ser completamente revisados com vários graus de facilidade, dependendo da qualidade e abrangência do conjunto de testes. Preocupar-se com coisas como "Isso deve ser uma propriedade?", "Esse código não deve usar LINQ em vez de uma construção de nível inferior?" é de valor duvidoso. É muito difícil vincular quaisquer medidas ao valor da consistência no nível da implementação. Uma pergunta muito melhor a ser feita nesse nível é "Esse código funciona como anunciado?". A consistência da implementação de TL; DR é onde as "mentes pequenas" entram em ação.
Por que a consistência não é tão importante aqui? As implementações geralmente têm um pequeno número de colaboradores. A maioria dos métodos é escrita e nunca é tocada novamente. Do código restante, o número de métodos que têm dois colaboradores quase certamente com maioria. Esse padrão continua ad infinitum . Nesse contexto, a consistência simplesmente não é tão importante. Se o prazo de validade do código for bem pequeno ( alguns anos ), os ganhos com consistência agressiva provavelmente não serão um fator.
Isso não quer dizer que você deva enlouquecer em suas implementações. Em vez disso, é preciso dizer que um design simples, limpo e agradável será uma ordem de magnitude mais valiosa para o seu hipotético mantenedor futuro do que o método de consistência de placas de caldeiras bobo por método. Isso nos leva ao ponto real ...
APIs não são descartáveis.
Esse é todo o nível de código das APIs, serviços da web, SDKs etc. Esses devem, devem, DEVEM ser consistentes. Os ganhos de produtividade com essa variedade de consistência são enormes por vários motivos:
Testes de integração:
Se você mantiver a API consistente, poderá criar conjuntos de testes de integração. Isso permite que os desenvolvedores troquem livremente os detalhes da implementação e obtenham validação imediata. Quer trocar sua porcaria de colegas de trabalho pelo LINQ? Os testes de integração são executados? Ele também fornece validação ao se preparar para ir para a produção. Como os computadores são rápidos, um único laptop pode realizar o trabalho de mil testadores executando tarefas comuns. É o equivalente a aumentar consideravelmente o número de funcionários da sua organização.
Produtividade
Quando as APIs são consistentes, você pode adivinhar sobre como usar uma API apenas seguindo o que aprendeu sobre o uso de outras partes da API. Isso ocorre porque a API oferece uma aparência e sensação natural e consistente. Isso significa que seu cliente gasta menos tempo vasculhando a documentação. A integração é mais fácil e mais barata. Menos perguntas são feitas às pessoas que desenvolveram a API. Consistência faz de todos um vencedor
Por que a consistência é importante nesse cenário? Porque as APIs têm o problema exatamente oposto das implementações. O número de pessoas que os utiliza normalmente é muito maior que o número de pessoas que contribuem para suas implementações. Pequenos ganhos com um pouco de consistência são multiplicados e os custos de manutenção dessa consistência são amortizados.
Conclusão
Consistência é cara. Em face disso, diminui a produtividade. Ele restringe os desenvolvedores e dificulta suas vidas. Ele impõe limitações às maneiras pelas quais eles podem resolver um problema, às vezes forçando-os a resolvê-lo de maneira não ideal. Isso geralmente ocorre por razões que eles não entendem, são mal concebidos ou não têm acesso a (contratos, políticas organizacionais ou interorganizacionais maiores).
Raymond Hettinger fez alguns pontos excelentes em sua palestra no Pycon 2015 sobre o uso do guia de estilo PEP8 para equipes de programadores de python. Ele mostrou que a obsessão pela consistência estilística em um pedaço de código fazia com que os revisores de código perdessem sérias falhas de lógica e design. Sua hipótese pode ser resumida, pois é fácil encontrar inconsistências estilísticas; determinar a qualidade real de um pedaço de código é difícil
O ponto aqui é ser crítico. Identifique onde a consistência é importante e proteja-a agressivamente. Onde não é importante, não perca seu tempo. Se você não puder fornecer uma maneira objetiva de medir o valor da consistência (nos casos acima, "número efetivo de funcionários", custo em função da produtividade) e não puder demonstrar que os retornos são substanciais, é provável que esteja fazendo um desserviço para sua organização.
fonte
A linguagem C # ainda está evoluindo. Se as pessoas não aprendessem as alterações do C # 1, elas estariam perdendo:
Esta é apenas uma pequena seleção de recursos comuns encontrados no artigo da Wikipedia. O que quero dizer é que, se os desenvolvedores não aprenderem, a base de código permanecerá no vácuo. É de se esperar que seus desenvolvedores melhorem continuamente e que a base de código evolua, suportada por um conjunto de testes completo. Você se lembra de como era ruim no .NET 1 implementar propriedades manualmente.
O Linq facilita a vida. Use-o onde puder. Você pode motivar os membros da sua equipe.
As melhorias são graduais. Para mim, não faz sentido manter um código de estilo antigo que seja menos legível e potencialmente menos sustentável. Os membros da sua equipe devem ser capazes de descobrir o que está acontecendo, mesmo que não possam escrever.
fonte
Você deve ser consistente, mas não necessariamente com o código antigo. Ou seja, sua equipe deve concordar com a maneira correta de fazer algo e usá-la sempre que um novo código for escrito ou quando forem feitas alterações substanciais.
Dessa forma, você colhe a maioria dos benefícios da consistência (em particular, não importa quem escreve o código), mas ainda pode melhorar se a equipe obtiver um benefício claro fazendo as coisas de outra maneira.
Em um mundo ideal, reescreveríamos todo o código antigo para estar de acordo com o novo caminho certo. Embora isso não seja economicamente viável, deve fazer sentido técnico (ou então, o novo caminho não é o melhor), e seu plano de longo prazo deve ser atualizá-lo. Se isso não vale a pena, não se preocupe com o novo caminho. Em outras palavras, deve haver uma clara vantagem na nova maneira de considerá-la correta.
fonte
Eu acho que é importante seguir um estilo de código em um projeto, por exemplo. convenções de nomes, recuos etc.
Não concordo que você deva se limitar a usar novas construções de linguagem ou padrões de design simplesmente porque seus colegas não as entendem ou porque não foram usadas no projeto antes.
Claro que essas coisas devem ter boas razões para usá-las, por exemplo. desempenho ou brevidade, se apropriado.
fonte
Eu seria extremamente cuidadoso seguindo cegamente os padrões atuais de design. Obviamente, quando não há uma desvantagem significativa, deve-se sempre tentar seguir padrões semelhantes em toda a base de código.
No entanto, é muito fácil entrar em circunstâncias em que a maioria dos desenvolvedores sente que é uma "prática recomendada" seguir os padrões ruins existentes, levando a situações em que bons desenvolvedores escrevem códigos ruins e inatingíveis.
Por outro lado, a consistência é importante. Ao lidar com enormes bases de código, é extremamente útil tentar seguir padrões semelhantes para que, embora os desenvolvedores não tenham lido cada centímetro da base de código, eles saibam o que esperar.
Portanto, acredito que é melhor estabelecer e atualizar diretrizes sobre quais padrões os desenvolvedores devem seguir, se possível. Dessa forma, qualquer novo código é consistente com outro novo código.
fonte
Temos reuniões técnicas regulares, bastante informais, que qualquer um de nós pode realizar. Se encontrarmos uma nova técnica, apresentamos na reunião. Você geralmente tem uma boa noção de quão bem a idéia é aceita e compreendida por seus colegas. Isso ajuda você a decidir se é aconselhável incluí-lo em seu código, ajuda outras pessoas a decifrá-lo se você o fizer e também estabelece a pessoa 'ir para' se outros precisarem de ajuda com esse estilo. Se ninguém reinventasse a roda, ainda estaríamos arrastando coisas nos troncos.
fonte