Em que ponto / intervalo um arquivo de código é muito grande?

36

Estou encontrando muitos arquivos de linha de 2-3k, e não parece que eles devam ser tão grandes.

Qual é um bom critério para chamar objetivamente um arquivo de código-fonte "muito grande"?, Existe uma quantidade máxima de linhas que um arquivo de código-fonte deve ter?

dukeofgaming
fonte
Seu colega avisa depois de revisar o código. "Você não pode determinar isso sozinho, porque sabe mais como autor 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 de manutenção do software - para olhar o que você escreveu e dar a sua opinião ... "#
30612
Alguns compiladores costumavam ter limites estranhos no tamanho do código-fonte: comprimento máximo da linha ou número máximo de linhas. Quando o compilador reclama, esse é um indicador objetivo de que o código é muito grande (ou que é hora de atualizar).
Mouviciel 25/11/12
2
Divida o máximo possível, mas sem quebrar a integridade dos arquivos. Cada arquivo (ou par de arquivos de cabeçalho / fonte) deve sempre ser um todo arredondado, independente da implementação interna de outros arquivos. Se isso significa que alguns arquivos serão grandes porque implementam algo complexo, que seja.
Ambroz Bizjak
Observe que a complexidade não é apenas sobre números, mas também sobre estrutura. Por exemplo, eu gostaria de declarar o python zen "flat is better than anested": uma lista simples de 100 casos é mais simples que uma hierarquia (você não se lembrará de todos os 100 casos, mas facilmente se lembrará de que existem 100 alternativas) . E uma hierarquia "regular" em que os ramos têm a mesma estrutura que seus irmãos são mais simples que a hierarquia com subestrutura irregular.
Juh_
"Esse é o código fonte?" "Não, esse é o makefile, o código fonte está nos caminhões seguindo atrás".
mckenzm 30/04

Respostas:

26

Como modelo ideal, uso os seguintes critérios (com uma lógica semelhante à sugerida por Martin Beckett, isto é, pensar em termos de estrutura lógica e não em termos de linhas de código):

Regra 1

Uma classe por arquivo (em C ++: uma classe -> um cabeçalho e um arquivo de implementação).

Regra 2

Sete é considerado o número de itens que nosso cérebro pode observar ao mesmo tempo sem ficar confuso. Acima de 7, achamos difícil manter uma visão geral do que vemos. Portanto: cada classe não deve ter mais de 7 a 10 métodos. Uma classe que possui mais de 10 métodos é provavelmente muito complexa e você deve tentar dividi-la. A divisão é um método muito eficaz, pois toda vez que você divide uma classe, você reduz a complexidade de cada classe individual pelo menos por um fator de 2.

Regra 3

Um corpo de método que não cabe em uma ou duas telas é muito grande (suponho que uma janela de tela / editor tenha cerca de 50 linhas). Idealmente, você pode ver todo o método em uma janela. Se não for esse o caso, você precisará rolar um pouco para cima e para baixo, sem esquecer a parte do método que fica oculta. Portanto, se você precisar rolar mais de uma tela para cima ou para baixo para ler todo o corpo do método, é provável que seu método seja muito grande e você poderá perder facilmente a visão geral.

Novamente, a divisão de métodos usando métodos de ajuda privados pode reduzir a complexidade do método muito rapidamente (a cada divisão, a complexidade é pelo menos reduzida à metade). Se você introduzir muitos métodos de ajuda particulares, considere criar uma classe separada para coletá-los (se você tiver mais métodos particulares do que os públicos, talvez uma segunda classe esteja oculta dentro da classe principal).

Reunindo essas estimativas aproximadas:

  • No máximo uma classe por arquivo de origem.
  • No máximo 10 métodos públicos por classe.
  • No máximo 10 métodos particulares por classe.
  • No máximo 100 linhas por método.

Portanto, um arquivo de origem com mais de 2000 linhas provavelmente é muito grande e começa a ficar muito confuso.

Essa é realmente uma estimativa muito aproximada e eu não sigo esses critérios sistematicamente (especialmente porque nem sempre há tempo suficiente para fazer a refatoração adequada). Além disso, como Martin Beckett sugeriu, há situações em que uma classe é uma grande coleção de métodos e não faz sentido dividi-los de alguma maneira artificial apenas para diminuir a classe.

De qualquer forma, na minha experiência, um arquivo começa a ficar ilegível quando um dos parâmetros acima não é respeitado (por exemplo, um corpo de método de 300 linhas que abrange seis telas ou um arquivo de origem com 5000 linhas de código).

Giorgio
fonte
11
Também gostaria de lutar por métodos não mais de 10 linhas de ... ajuda com a leitura / compreensão do que o método está fazendo e reduz a complexidade que pode facilmente acontecer em grandes métodos ...
Zack Macomber
4
A regra 2 é absurda se você a seguir até a conclusão. Você não deve ter mais de 7 arquivos em um diretório, para manter seus arquivos grandes, para não ficar confuso entre as dezenas ou centenas de arquivos em seu projeto. Da mesma forma, uma estrutura de diretório profundamente aninhada é muito confusa, portanto, é melhor manter alguns arquivos grandes em um diretório do que dispersar tudo.
hasen
11
Lamento, esta resposta é baseada em métricas totalmente arbitrárias. Os "7 itens" são claramente besteiras, caso contrário você não seria capaz de usar o alfabeto. O tamanho do objeto deve basear-se na separação de preocupações, responsabilidade única, alta coesão-baixo acoplamento e princípios semelhantes, e não em números arbitrários.
JacquesB
11
@JacquesB Os 7 itens são geralmente indicativos de 7 informações não relacionadas. Se o seu cérebro pode associar ou agrupar informações, em um sentido real, são 1 informação que pode levar a mais se você tentar se lembrar (na verdade "alfabeto" é um símbolo, nem todas as 26 letras). Um exemplo melhor seria tentar lembrar um número de 7 dígitos informado por telefone, sem caneta e papel disponíveis. Os métodos claramente não são números arbitrários, mas se esses métodos forem relevantes para o que você está codificando, você poderá esperar após o 7, precisará procurar por ele antes de se lembrar corretamente.
Neil
3
@ Neil: Se os métodos de uma classe são informações aleatórias e não relacionadas, você tem problemas maiores no design da sua classe do que o número de métodos.
JacquesB
33

Não - não em termos de linhas de código. O driver deve ser um agrupamento lógico. Certamente não deve haver várias classes em um arquivo grande, por exemplo

Se você tivesse uma classe que tivesse legitimamente algumas centenas de métodos (não é impossível dizer, por exemplo, modelagem 3D), seria muito menos conveniente dividi-la em arquivos arbitrários. Costumávamos fazer isso quando a memória era mais escassa e os processadores mais lentos - e isso era um esforço, procurando constantemente a definição da função.

Martin Beckett
fonte
2
Uma classe com centenas de métodos não seria um sintoma de inveja, falta de coesão, design deficiente, violação do princípio de responsabilidade única, etc.?
Tulains Córdova
2
@ user1598390: geralmente, mas nem sempre.
Whatsisname
4
@ user1598390 - comum em, por exemplo, a modelagem gis / 3d ter muitas operações que você pode executar e sobrecarregá-las para sinal 2d, 3d, 4d, 3d +, depois flutuar / duplo / inteiro etc. - os modelos ajudam um pouco, mas são eficazes muitas operações são muitas vezes melhor do que uma hierarquia de classe bastante
Martin Beckett
2
@ tp1 - e você usa uma fonte pequena para que eles não ocupem tanto espaço?
Martin Beckett
2
@ tp1 Cara, me desculpe, eu realmente não quero dizer desrespeito, mas sinto muito por quem trabalha com você. Se você tiver 1200 classes, use uma convenção de diretório; se você tiver muitos diretórios, divida-os em módulos / bibliotecas independentes.
Dukeofgaming 3/12/12
8

Quando o código se torna inalterável. ou seja: você não pode dizer apenas observando o código se o método / classe / função que você está procurando (e precisa editar / depurar) está lá ou não, e se sim, onde está.

Porém, sua escolha e recursos de IDE / Editor influenciarão a quantificação real desse limite superior. Dobramento de código , função / método de listagem e pesquisa vai adiar o momento em que este desenvolvimento cenário apresenta.

Mas quando isso acontecer, é hora de dividir.

ZJR
fonte
2

Aqui está uma visão alternativa: você está perguntando sobre como limitar o tamanho do arquivo. Minha opinião é que existem muitos fatores que tornam os arquivos de código grandes muito problemáticos. Às vezes, o arquivo de código é enorme, mas seu conteúdo é bem agrupado e com um código extremamente limpo, para que o tamanho não cause problemas significativos. Eu já vi muitos arquivos que são muito legíveis, apesar do alto LOC.

Em vez de usar a métrica LOC, prefiro pensar em usar os dados do histórico para entender com que frequência o código é quebrado nesses arquivos grandes. Geralmente, a razão disso é que os desenvolvedores não têm tempo para paciência para verificar os outros locais relevantes no mesmo arquivo e fazer a alteração com a mentalidade de "solução rápida", sem entendimento suficiente.

O maior perigo é a presença de código de copiar e colar. A codificação de copiar e colar naturalmente também acelera o crescimento do LOC. Eu acho que eliminar copiar e colar é ainda mais importante do que manter o LOC abaixo de algum número mágico. Além de copiar e colar puro, também existe um segundo perigo nos arquivos grandes: funcionalidade sobreposta. Quanto maior o arquivo, maior a probabilidade de você reimplementar algum trecho que já está em outra seção do mesmo arquivo.

Assim, enquanto proporção bug fix (proporção de correção de bug commit todos os commits) é baixo para os arquivos maiores, a situação é tolerável. Por favor, tente git loge percorra quantas confirmações estão relacionadas a erros. Ou use uma ferramenta que possa analisá-lo e visualizá-lo automaticamente, por exemplo, Softagram .

Ville Laitila
fonte
-1

Considere isso Metaphor. No que diz respeito ao tamanho do código, acho que devemos considerar o seguinte:

The Cat in The Hat (50 pp.)

e

Lord of The Rings (1,178 pp.)

Não há nada errado com isso Lord of the Rings. É um livro fabuloso. The Cat in the Hattambém é um ótimo livro. Ambos podem ser entendidos por crianças de 5 anos, mas apenas um é mais adequado devido ao conteúdo.

Para o meu ponto, escrever código deve fazer sentido para uma criança de 5 anos sempre que possível. Cyclomatic Complexityé um conceito importante que os desenvolvedores devem considerar ao gerar código. Utilizando e criando bibliotecas para aprimorar a funcionalidade e a reutilização de código, tanto quanto possível. Dessa forma, nosso código pode falar mais volumes do que o que vemos escrito.

A maioria de nós não está escrevendo código de montagem . Mas a raiz do nosso código é assembly. Pesquisando através da montagem de 10000 linhas é mais difícil do que 10000 linhas de python, se isso for feito corretamente.

Mas algum trabalho requer a escrita de 500 a 1000 linhas. Nosso objetivo com o código deve ser escrever 300 linhas de código limpo.

Como desenvolvedores, queremos escrever "Senhor dos Anéis". Até conseguirmos um bug e desejarmos escrever "Cat in the Hat". Não faça da codificação uma medida do ego. Basta fazer as coisas funcionarem de maneira simples.

Os desenvolvedores não querem documentar o código (eu amo o código documentado pessoalmente, não sou tão egoísta). Portanto, não escreva código que somente você possa entender / ler. Escreva Cat in the Hatcódigo.

Todos sabemos que você é JRR Tolken (na sua cabeça). Lembre-se de que você não terá nada a provar com o código sem erros.

Outra razão para a metáfora.

Não exagere no leitor, espalhe a riqueza. Se você trabalha com um grupo de pessoas e todas elas precisam alterar o mesmo arquivo grande, provavelmente estará se metendo no gitinferno.

Todo mundo adora rebater.

-> Disse que ninguém nunca!

TL; DR Foco na legibilidade. Espalhe seu código e auxiliar por várias linhas e arquivos o máximo que puder. Não jogue 8 ou 9 classes em um único arquivo, isso torna o código difícil de ler e de manter. Se você tiver um código ou loop grande de condição, considere alterá-los para Lambdas se o idioma suportar. As funções de utilitários devem ser consideradas um ótimo caminho para aumentar a legibilidade do código. Evite aninhamento pesado.

GetBackerZ
fonte
Não sou um defensor negativo, mas sua analogia está um pouco perdida para mim. Você está dizendo que é melhor espalhar seu código por várias linhas e ter menos palavras em cada linha?
Fodder
Espalhe o código e o auxiliar por várias linhas e arquivos, tanto quanto possível. Concentre-se na legibilidade. Não jogue 8 ou 9 classes em um único arquivo. Isso torna o código difícil de ler e de manter. Se você tiver um código de condição grande ou loops. Transforme-os em utilitários. Evite aninhamento pesado. Informe-me se isso ajudar a explicá-lo.
GetBackerZ
Talvez você deva editar isso na sua resposta, pois isso tornará mais claro o que você quer dizer.
Fodder
Usei o script para Jackie Brown como parâmetro para programas modulares z / OS COBOL. Você sabe, para brincadeiras de coquetel ...
mckenzm 30/04
"faz sentido para uma criança de 5 anos sempre que possível." - para problemas do mundo real que pagam as contas, isso raramente é possível e visa a coisa errada
whatsisname