Como saber se o código criado é facilmente legível, compreensível e sustentável? Obviamente, do ponto de vista do autor, o código é legível e sustentável, porque o autor o escreveu e o editou, para começar. No entanto, deve haver um padrão objetivo e quantificável pelo qual nossa profissão possa medir o código.
Esses objetivos são alcançados quando se pode fazer o seguinte com o código sem o aconselhamento especializado do autor original:
É possível ler o código e entender em um nível básico o fluxo da lógica.
É possível entender em um nível mais profundo o que o código está fazendo para incluir entradas, saídas e algoritmos.
Outros desenvolvedores podem fazer alterações significativas no código original, como correções de erros ou refatoração.
Pode-se escrever um novo código, como uma classe ou módulo que aproveite o código original.
Como quantificamos ou medimos a qualidade do código para que possamos conhecê-lo como legível, compreensível e sustentável?
Respostas:
Seu colega avisa depois de revisar o código.
Você não pode determinar isso sozinho porque, como autor, você sabe mais do que o código diz por si só. Um computador não pode lhe dizer, pelas mesmas razões que não pode dizer se uma pintura é arte ou não. Portanto, você precisa de outro ser humano - capaz de manter o software - para examinar o que escreveu e dar sua opinião. O nome formal desse processo é revisão por pares .
fonte
Às vezes, a melhor maneira de saber é voltar ao código que você escreveu há seis meses e tentar entender o que foi escrito para fazer.
Se você entender rapidamente - é legível.
fonte
Isto é:
O verdadeiro teste para 1. é (como Alex em Paris e quant_dev dizem) que você pode recuperá -lo depois de alguns meses fazendo outra coisa.
O teste para 2. e 3. é que alguém pode buscá-lo e descobrir como estender ou corrigir seu código enquanto segue o design do seu projeto. Se eles não conseguirem entender o design, como ele se relaciona com o espaço do problema ou como o seu código se destina a ser usado, eles invadirão uma solução em toda a parte.
Existem regras práticas, princípios (ou seja, regras básicas que alguém escreveu bem e deu um nome) e todo tipo de sugestão que pode levá-lo na direção certa ou afastar-se de armadilhas comuns. Nenhum deles garantirá as qualidades que você está pedindo.
fonte
Se o seu código seguir os princípios do SOLID e DRY e tiver um bom conjunto de testes de unidade, provavelmente será possível mantê-lo.
É legível? Leia-o. Os nomes de métodos e variáveis fazem sentido? Você pode seguir a lógica do programa sem problemas? Se a resposta for sim, então o código é legível.
fonte
Lendo como escrever código não sustentável - Garanta um emprego vitalício por Roedy Green, rindo e aprendendo.
O ensaio fornece vários exemplos de como escrever código incorreto, usando muitos exemplos engraçados. Ele continua explicando como utilizar a grafia criativa de Miss Miss , Reutilização de Nomes , a técnica altamente apreciada de Reutilização de Nomes Globais como Privada .
De uma maneira bem-humorada, o ensaio ensina como evitar todos os exemplos de código ilegível e não-sustentável.
Na verdade, achei difícil acreditar que alguém escrevesse código com semelhanças com os exemplos no texto. Foi quando eu estava na escola. Mas, depois de trabalhar por alguns anos, vejo código do texto todos os dias ...
fonte
Apesar de como parece, existem algumas medidas bastante objetivas que você pode considerar. Livros como C ++ Coding Standards , Refactoring e Clean Code têm longas listas de critérios para julgar seu código, analisando coisas como nomes significativos, tamanhos de função, princípios como acoplamento e coesão, design de objetos, teste de unidade, refinamento sucessivo etc.
A lista é muito grande para ser acessível a uma lista de verificação, mas você lê o livro e escolhe algumas coisas importantes para trabalhar; depois de vários meses, leia-o novamente para melhorar ainda mais.
fonte
A prova está no pudim. Observe o que acontece depois de entregá-lo a uma pessoa razoavelmente competente. Se eles não precisarem fazer muitas perguntas relacionadas à dificuldade do código, você fez um bom trabalho.
Essa foi uma lição inicial da minha carreira. Um mentor disse: "Documente tudo, para que você possa escapar mais tarde do programa. Se você não antecipar perguntas quando as respostas estiverem frescas em sua mente, terá que descobri-las quando não estiverem".
fonte
Eu li todas as respostas e notei que ninguém mencionou a complexidade do código.
Existe uma forte correlação entre a complexidade do código e a legibilidade / manutenção. Existem numerosos algoritmos de pontuação de complexidade de código, mas vou falar sobre como a pontuação de complexidade de McCabe funciona.
Basicamente, a pontuação de McCabe lê seu código e calcula o número de "caminhos" únicos existentes nele. Se você usa McCabe como numerador e as linhas de código como denominador, também obtém uma boa aproximação da "legibilidade".
Se você possui 10 linhas de código e há 300 caminhos nesse código, esse é um código bastante insustentável (difícil de alterar com segurança e facilidade), e provavelmente não é muito legível. Por outro lado, se você possui 300 linhas de código, mas existe apenas um caminho (não possui condições), é legível e fácil de manter.
Onde McCabe cai, no entanto, é nesse último exemplo. Se eu tenho 300 linhas de código sem condições, há uma chance muito boa de ter feito "copiar / colar reutilizar", e obviamente isso também não é uma coisa boa. Portanto, existem métricas para todo o sistema que você aplica além do McCabe - como detecção de código duplicado ou quase duplicado.
fonte
Um ponto que eu gostaria de compartilhar é que se o código for construído em "módulos", e quando digo isso, quero dizer que você pode alterar uma coisa em um módulo e fazer com que ele funcione facilmente com o todo. Elimina efeitos entre coisas não relacionadas. Além disso:
Eu recomendo a leitura, O Programador Pragmático.
fonte
Alguns testes / indicadores:
Desligue o IDE. Você ainda pode ler seu próprio código? Quando há um erro, é bastante fácil rastreá-lo manualmente e descobrir em que classe você precisará de um ponto de interrupção para descobrir que é onde está o problema. Ou quando você usa o IDE, você nem se incomoda e avança desde o início?
O debug geralmente se torna um jogo de maluco, em que a correção de um bug cria mais de 2 vezes.
Do acionamento do gatilho até algo útil realmente acontecendo, quantas chamadas de método são necessárias? Quantos métodos passam exatamente os mesmos parâmetros ou a maioria dos mesmos parâmetros exatos para outra chamada de método?
Quantos arquivos você precisa abrir para adicionar um novo método simples a uma classe?
Pense nos padrões e práticas que você adotou. Você fez isso porque eles faziam todo o sentido ou porque alguém o convenceu de que "é a única maneira de fazer isso?" ou porque você queria no seu currículo ou porque algum desenvolvedor de rockstar disse isso.
fonte
Você pode identificar códigos fáceis de manter e legíveis, procurando estas propriedades:
fonte
Em uma única palavra, Experiência .
Para começar, você precisa ter trabalhado no terreno, por isso não posso recomendar mais que os programadores dediquem um tempo para ler livros como Refatoração , que fornecerá algumas das ferramentas mais essenciais em um arsenal de programadores que melhorarão sua capacidade de manter o código e o Clean Code, que foi escrito por alguns dos talentos mais reconhecidos em nosso campo, e que descreve quase tudo o que você precisa entender para garantir que seu código seja limpo e legível.
Nenhuma quantidade de leitura, no entanto, substitui a experiência adquirida com muito esforço. Você realmente precisa ter trabalhado com o código por um tempo para apreciar completamente a diferença que a atenção à qualidade do código pode fazer. Ao experimentar o prazer de trabalhar com código limpo e bem fatorado, bem como a dor de trabalhar com espaguete de código, você aprende a entender melhor o que os autores desses livros realmente estavam tentando ensinar a você, mas o faz em um contexto mais amplo do código real de produção ao vivo, onde a qualidade do que você faz realmente importa e afeta sua capacidade de trabalhar facilmente com seu código diariamente.
Também ajuda ter um bom mentor ou um colega com a experiência para confirmar que você está se esforçando para escrever código com um alto padrão. Essa é apenas uma das razões pelas quais as revisões de código podem ser tão úteis. O uso de ferramentas de verificação e formatação de código também pode ser uma ajuda muito útil para garantir que você esteja mantendo as coisas limpas. No entanto, nada se compara à experiência obtida com anos de software de escrita, de modo que você se encontra automaticamente escrevendo código limpo, legível e estruturado simplesmente para facilitar a manutenção, e tudo porque você criou o hábito de aplicar as melhores práticas para isso. longo.
fonte
Sem ser puritano: prefira o estilo funcional. Atualmente, a maioria dos idiomas (.NET, Ruby, Python, Javascript, etc.) o suporta e promove (por exemplo, LINQ, underscorejs).
É extremamente fácil de ler.
Força cada nó a ter uma intenção única e focada, emprestando à clareza de propósito. E como cada tarefa discreta é isolada, sair, conectar e reorganizar nós (operações) para diferentes fins é trivial. Isso facilita a manutenção.
fonte
Código legível e de manutenção: código que, à primeira vista, um programador pode entender bem o suficiente para poder:
Isso se resume a 'clareza'. ou seja, quantas perguntas o programador precisa fazer sobre um segmento específico de código antes de ter certeza de que "entende o que faz bem o suficiente" para realizar a tarefa atual em questão sem causar efeitos colaterais inesperados.
O livro 'Code Complete, de Steve McConnell' aborda isso em detalhes.
Ele passa por várias métricas que você pode usar para determinar se o código é de boa qualidade.
Veja um exemplo aqui: http://books.google.co.uk/books?id=3JfE7TGUwvgC&lpg=PT376&pg=PT389#v=onepage&q&f=false
fonte
Minimize os efeitos colaterais (o ideal é não ter nenhum)
Uma função que causa três alterações nos estados fora de seu próprio escopo é muito mais difícil de raciocinar e manter do que aquela que apenas insere algo e gera outra coisa. Você não pode apenas saber o que a função faz, é preciso lembrar o que ela fez e como isso afeta todas as outras funções relevantes.
Para OOP, minimizar efeitos colaterais também significa classes com menos membros e, especialmente, menos membros que podem modificar o estado da classe, uma vez que as funções de membro podem modificar estados além dos seus e causar efeitos colaterais (eles podem manipular os elementos internos da classe, por exemplo). Isso também significa classes com menos membros de dados próprios, para que haja menos estado para esses métodos adulterarem e menos efeitos colaterais que eles podem causar.
Como um exemplo simples, imagine tentar projetar uma estrutura de dados sofisticada que possa manter um
sorted
estado usado para determinar se é necessário executar pesquisas binárias ou lineares. Nesse caso, pode ser útil separar o design em duas classes. Chamarsorted
a classe não classificada pode retornar uma estrutura de dados de outra classe que sempre mantém seu conteúdo classificado. Agora você tem menos efeitos colaterais (portanto, menos propenso a erros e mais fácil de entender o código), bem como um código mais amplamente aplicável (o design anterior seria um desperdício tanto no processamento quanto na eficiência intelectual humana para pequenas matrizes que nunca precisam ser classificadas).Evitar dependências externas supérfluas
Você pode implementar o código mais conciso que se possa imaginar com a reutilização máxima de código usando 13 bibliotecas diferentes para realizar uma tarefa relativamente simples. No entanto, isso transfere sobrecarga intelectual para os seus leitores, fazendo com que eles entendam pelo menos partes de 13 bibliotecas diferentes. Essa complexidade inerente deve ser imediatamente apreciada por qualquer pessoa que tente criar e compreender uma biblioteca de terceiros que exija a instalação e a construção de uma dúzia de outras bibliotecas para funcionar.
Esta é provavelmente uma visão muito controversa, mas eu preferiria uma duplicação modesta de código ao extremo oposto, desde que o resultado final seja bem testado (nada pior do que um código defeituoso não testado duplicado várias vezes). Se a opção for entre três linhas de código duplicado para calcular um produto cruzado de vetor ou puxar uma biblioteca de matemática épica apenas para cortar três linhas de código, eu sugeriria o primeiro, a menos que toda a sua equipe esteja presente nessa biblioteca de matemática , nesse ponto, você ainda pode escrever apenas 3 linhas de código em vez de 1, se isso for trivial o suficiente em troca dos benefícios da dissociação.
A reutilização de código é um ato de equilíbrio. Reutilize demais e você transfere a complexidade intelectual de um modo para muitos, pois nessas três linhas de código simples que você salvou acima têm o custo de exigir que os leitores e mantenedores compreendam muito mais informações do que três linhas de código . Isso também torna seu código menos estável, pois, se a biblioteca de matemática mudar, o código também pode mudar. Reutilize muito pouco e você também multiplica a sobrecarga intelectual e seu código deixa de se beneficiar de melhorias centrais; portanto, é um ato de equilíbrio, mas vale a pena mencionar a idéia de que é um ato de equilíbrio, já que tentar eliminar todas as formas pequenas de duplicação modesta pode levar para um resultado que é tão difícil de manter, se não mais, do que o extremo oposto.
Teste sua porcaria
Isso é óbvio, mas se o seu código não trata de todos os casos de entrada e perde alguns casos extremos, como você pode esperar que outros mantenham o código que você escreveu e que nem acertou antes de ser transferido para os olhos e as mãos deles? Já é bastante difícil fazer alterações no código que funcione perfeitamente e muito menos em um código que nunca foi totalmente correto.
Além disso, o código que passa em testes completos geralmente encontra menos razões para mudar. Isso se refere à estabilidade, que é ainda mais um Santo Graal a ser alcançada do que a capacidade de manutenção, uma vez que o código estável que nunca precisa ser alterado não incorre em nenhum custo de manutenção.
Documentação da interface
Priorize "o que as coisas fazem" em vez de "como as coisas as fazem" se você não puder dedicar tempo igual à documentação de ambas. Uma interface clara que seja óbvia em suas intenções sobre o que fará (ou, pelo menos, o que deveria fazer) em todos os possíveis casos de entrada, trará uma clareza de contexto à sua própria implementação, o que guiará o entendimento não apenas de como para usar o código, mas também como ele funciona.
Enquanto isso, o código que não possui essas qualidades em que as pessoas nem sabem o que deve fazer é o SOL, independentemente de quão bem documentados sejam seus detalhes de implementação. Um manual de 20 páginas sobre como o código-fonte é implementado é inútil para as pessoas que nem conseguem descobrir exatamente como ele deve ser usado em primeiro lugar e o que ele deve fazer em todos os cenários possíveis.
Para o lado da implementação, priorize a documentação do que você faz de maneira diferente de todos os outros. Como exemplo, a Intel tem uma hierarquia de volume delimitadora para seus kernels de rastreamento de raios. Como trabalho neste campo, posso reconhecer rapidamente a maior parte do que o código está fazendo sem examinar a documentação. No entanto, eles fazem algo único, que é a idéia de atravessar o BVH e realizar interseções em paralelo usando pacotes de raios . É aí que eu quero que eles priorizem sua documentação, porque essas partes do código são exóticas e incomuns da maioria das implementações históricas do BVH.
Legibilidade
Esta parte é muito subjetiva. Eu realmente não me importo muito com a legibilidade de um tipo que se aproxime dos processos de pensamento humano. O código mais bem documentado que descreve as coisas no nível mais alto ainda é difícil de ser seguido se o autor usar processos de pensamento bizarros e complicados para resolver um problema. Enquanto isso, código conciso usando nomes de 2 ou 3 caracteres geralmente pode ser mais fácil para mim entender se a lógica é muito direta. Eu acho que você pode revisar e ver o que as outras pessoas preferem.
Estou interessado principalmente em manutenção e, mais importante ainda, estabilidade. O código que não encontra motivos para alterar é aquele que tem zero custo de manutenção.
fonte
Eu diria que uma maneira de saber seria se os novos membros da equipe podem pegar o código, entendê-lo e modificá-lo para corrigir defeitos / atender novos requisitos com relativa facilidade.
fonte
Aqui está uma técnica que eu gosto de usar:
Mostre o código a um de seus programadores e peça que eles expliquem o que ele faz. Cuidado com essas coisas.
1) Se eles não puderem explicar facilmente o objetivo de um bloco de código, refatore-o.
2) Se eles tiverem que pular para outra seção do código para entender a seção atual, refatore-a.
4) Sempre que você sentir vontade de falar durante o processo, essa seção do código precisará ser refatorada. (O código não está falando por si).
fonte
O código mais sustentável é aquele que não existe. Portanto, em vez de adicionar à contagem de LOC, o novo código que 'reduz' a contagem de LOC (mesmo que ligeiramente menos sustentável quando visualizado isoladamente) poderia tornar a base de código total mais sustentável simplesmente reduzindo seu tamanho. Portanto, a regra principal para código sustentável:
Em segundo lugar, não há nada pior em termos de manutenção do que dependências ocultas. Então, para a regra número 2:
Em terceiro lugar, nem todos os programadores são igualmente hábeis em manter ou escrever usando recursos ou expressões específicas da linguagem de técnicas mais avançadas. Ao diminuir toda a base de código, você terá uma grande base de código que, devido ao seu tamanho, é difícil de manter. Permitir recursos e expressões de técnicas avançadas em todo o código fará com que todo o código possa ser mantido apenas por desenvolvedores seniores, o que também é ruim. A chave para a manutenção é a estratificação baseada no nível de habilidade. Por exemplo:
Bibliotecas entre projetos: desenvolvedores seniores, código / idioma / técnicas completas dos truques Bibliotecas específicas do projeto e back-end do sistema: desenvolvedores intermediários, evitam coisas mais avançadas e difíceis de explicar. Os idosos passarão por esse código procurando oportunidades de melhoria DRY.
Front-end: desenvolvedores juniores, use um guia de estilo rigoroso e um conjunto de técnicas que a linguagem constrói e os idiomas a serem evitados. Os desenvolvedores médios percorrerão esse código procurando oportunidades DRY e lógica comercial oculta.
Então, para a regra número 3:
Eu
fonte
Nunca é fácil tentar escrever um código legível e de fácil manutenção, mas não é difícil escrever um código fácil e de manutenção.
OOAD é uma palavra de quatro letras, mas difícil de entender de uma só vez - siga Análise e Design orientado a objeto
Sempre comece com uma boa coleta de requisitos e a declaração exata do problema
Você precisa manter seus objetos fracamente acoplados e garantir que seu código não se repita - siga DRY [Não se repita]
fonte