Guia de codificação: os métodos não devem conter mais de 7 declarações?

76

Eu estava pesquisando as Diretrizes de codificação do AvSol para o C # e concordo com quase tudo, mas estou realmente curioso para ver o que os outros pensam de uma regra específica.

AV1500

Methods should not exceed 7 statements A method that requires more than 7 statements is doing too much, or has too many responsibilities. It also requires the human mind to analyze the exact statements to understand what the code is doing. Break it down in multiple small and focused methods with self-explaining names.

A maioria de vocês segue essa regra? Mesmo que haja pouco a ser salvo de criar um novo método (seu código ainda é DRY ) além de aumentar a legibilidade ? E o seu número ainda é tão baixo quanto 7? Eu tenderia mais para 10.

Eu não estou dizendo que eu viole esta regra em todo o lugar - pelo contrário, meus métodos são 95% pequenos e focados, mas dizer que você nunca deve violar essa regra realmente me surpreendeu.

Eu realmente só quero saber o que todo mundo pensa NUNCA violar essa regra (é um '1' no padrão de codificação - o que significa NUNCA fazer isso). Mas acho que você teria problemas para encontrar uma base de código que não tem.

    
por brian 29.07.2014 / 12:16
fonte

17 respostas

194

Este é um "cheiro padrão" para mim. Sempre que vejo padrões de codificação com limites específicos neles, me preocupo. Você quase sempre se depara com um caso em que um método precisa ser maior do que o padrão permite (seja comprimento / número da linha, número de variáveis, número de pontos de saída, etc.). Padrões devem ser mais como diretrizes, e permitir espaço suficiente para exercer bom senso. Não me entenda mal, é bom ter padrões, mas eles não devem se tornar "microgerenciamento por proxy".

    
por 27.02.2012 / 16:39
fonte
82

Geralmente, é uma boa ideia dividir as coisas em pequenos métodos. Mas o importante é dividir as coisas onde isso fizer sentido.

Se não fizer sentido dividir, não divida. Este é frequentemente o caso de alguns procedimentos ou códigos GUI.

Steve McConnell indicado em Código completo que nem sempre é mais produtivo ao usar métodos curtos. Se você dividir quando não fizer sentido, você adicionará complexidade ao código sem nenhum benefício.

Como sempre com as diretrizes, é bom lembrar por que as restrições existem, para que você possa aprender quando isso não se aplica. Na maior parte do código, os métodos serão curtos, ou você provavelmente tem um problema com DRY ou separação de interesses . Mas se não for o caso, então tudo bem.

    
por 27.02.2012 / 19:45
fonte
28

Deve ser considerado como uma regra geral.

Coisas como "Não mais de 80 (100.120) colunas de texto", "um ponto de saída por método", "não mais do que 2 níveis de aninhamento", são o que eu chamaria de limites para indicadores de cheiro de código. Se você violá-los de vez em quando, isso não significa necessariamente que o código é ruim. Se você se encontrar violando-os constantemente, então algo cheira no código e você pode querer fazer uma pausa e repensar sua abordagem.

Para mim, os critérios mais importantes são: "Esse código é compreensível?", "É repetitivo?", "É dividido em lugares lógicos?", "É fracamente acoplado?" Há mais alguns, mas acho que a ideia básica pode ser resumida lembrando-se do conselho de Donald Knuth: "Os programas devem ser lidos por humanos e apenas incidentalmente para serem executados por computadores".

    
por 27.02.2012 / 17:45
fonte
18

Eu nunca gastei tempo para realmente contar o número de declarações em meus métodos, mas eu me esforço para escrever métodos que executem de maneira limpa uma finalidade única e clara. Contanto que seu código esteja limpo, legível e siga as DRY e Principais princípios de responsabilidade , você provavelmente já fez o seu trabalho. Acho que dividir arbitrariamente um método apenas para impor o limite de sete instruções pode tornar seu código menos legível / sustentável.

    
por 27.02.2012 / 16:32
fonte
11

É aproximado

Esses tipos de regras não devem ser considerados literalmente. Eles poderiam ter dito " métodos devem ser curtos ". No entanto, algumas pessoas teriam interpretado isso como "menos de uma página" e outras como "duas linhas no máximo".

Eu diria que eles disseram "7 declarações" para lhe dar uma idéia aproximada (embora eu ache que eles deveriam ter dito "cerca de 7"). Se você precisa de 9 de vez em quando, não se preocupe. Mas se você acertar 20, saberá que não está na situação certa para essa regra.

    
por 27.02.2012 / 18:25
fonte
10

7 é um número completamente arbitrário, sem qualquer significado.

Complexidade ciclomática é um problema maior que o número de declarações. Eu vi código que tinha 100s de instruções em um único método (que eu achava que era terrível), mas tinha uma complexidade ciclomática de 1 e realmente só fez 1 coisa. Houve apenas muitos passos. Discutimos o desmembramento em métodos menores, mas esses métodos só seriam chamados por esse método.

Embora esse seja um caso bastante extremo, o ponto é que você precisa manter o código DRY e uma baixa complexidade ciclomática. Isso é mais importante que o número de linhas em um método.

Tome um switch / declaração de caso, por exemplo. Se você tem mais de 7 valores possíveis, você precisa dividir a avaliação em vários métodos? Claro que não, isso seria bobo.

Quebrar artificialmente o código em mais métodos apenas para manter o número de instruções abaixo de 7 só piora o seu código.

A diretriz deve ser Cada método deve fazer 1 coisa e manter seu código DRY.

    
por 28.02.2012 / 09:54
fonte
4

Bem, isso depende um pouco. Eu escrevo um monte de código que acessa bancos de dados. O código da placa de caldeira para tratamento de exceções tem mais de sete declarações em muitos casos. Eu diria que a melhor diretriz é garantir que sua função tenha um propósito

    
por 27.02.2012 / 16:40
fonte
4

Tudo é um trade-off. O problema com a abordagem proposta - refatorar em vários métodos e classes para que cada método seja curto - é que, embora por diferentes razões, ele leva a um código ilegível quando levado ao extremo.

Imagine um método foo() que faz 7 coisas. Você pode argumentar que 7 coisas são demais. Talvez em muitos casos você esteja certo. Por outro lado, essas 7 coisas podem estar intimamente relacionadas; a lógica pode fluir suavemente e ler como prosa; você pode não ter dificuldade em entendê-lo quando realmente precisar. O que pode acabar sendo muito pior é ter essas 7 coisas distribuídas em uma grande árvore de fontes, de modo que se você olhar para foo() você não tem idéia do que faz sem olhar em 7 lugares diferentes.

Muitas pessoas têm regras assim, e o resultado é o que eu acho como espaguete OO. Tudo é arrumado, encaixado em seu próprio método ou classe, com pequenas micro transações atômicas ocorrendo em cada lugar. Mas é impossível chegar de novo a essa base de código e saber o que está fazendo. Você se perdeu.

    
por 27.02.2012 / 17:57
fonte
4

não é uma má orientação. Eu nunca me arrependi de dividir métodos e classes (nunca achei que tivesse muitos), desde que eles estejam bem agrupados e inter-relacionados.

O truque é NÃO dividi-lo verticalmente (apenas aperte um método em um ponto e inicie um novo). O truque, como com o teste de unidade, é manter essa regra em mente desde o início, para que você realmente desenhe melhor, passando 3 ou 4 instruções do meio para outro método, porque ter uma chamada de método descreve melhor o que você está fazendo. aquelas 3 ou 4 declarações no meio do seu código.

Esse tipo de divisão, mesmo que seja arbitrário e usado apenas uma vez, pode levar a refatorações melhores posteriormente devido a uma nova clareza de código, isso também é verdade para classes menores.

Pense nisso como se fosse um teste de unidade. Se você tentar adicionar testes unitários após o fato, é difícil e, às vezes, parece impossível, mas se você projetá-lo desde o início, ele realmente torna todo o seu código melhor.

Resumo? Se compararmos o cheiro de design de "Usar menos de 7 declarações" ao cheiro de código de "Eu usei mais de 7 declarações", prefiro eliminar o cheiro de código.

    
por 27.02.2012 / 19:31
fonte
4

Uau! Eu nunca esperei encontrar uma discussão tão intensa em uma diretriz simples que diz que seus métodos devem ser muito pequenos. Como eles são sempre desenvolvedores que querem que suas diretrizes sejam explícitas, eu escolho 7 porque isso soa como um bom limite.

Alguns de vocês já citaram o aviso de isenção no começo do documento. Mas, para deixar claro, este documento representa uma coleção de diretrizes que tentam ajudar você a escrever um código melhor e projetar sistemas melhores. Eu nunca afirmei que qualquer coisa deveria ser uma regra, mesmo que uma diretriz esteja marcada como um nível 1. Esses níveis são simplesmente a opinião coletiva de muitas pessoas que têm usado este documento há algum tempo.

Eu também nunca afirmei ser um especialista. Mas eu estou nessa profissão há 15 anos, com cerca de 4 anos de experiência em C ++ e 11 anos de experiência em C #. Ele foi originalmente baseado no Industrial Strength C ++, mas eu o refino desde então com a contribuição da comunidade.

Independentemente disso, o ponto que eu estava tentando levantar é que você deve continuar pensando por si mesmo. Se você acha que a diretriz das 7 afirmações não é útil, apenas aumente. Heck, eu até viole essa diretriz de vez em quando. Eu apenas violei-o conscientemente e aceito as conseqüências.

    
por 28.02.2012 / 20:50
fonte
3

Primeiramente: é uma diretriz, não uma regra. É chamado de diretriz, então, por favor, trate-o como tal. Isto implica que o seu próprio julgamento também é necessário (como sempre)

Além disso, posso pensar em muitos exemplos de códigos bons que não aderem a essa restrição. Mesmo que seja apenas uma diretriz, é ruim.

    
por 27.02.2012 / 23:28
fonte
2

Concordo com a afirmação acima de mim. Isso é apenas uma diretriz e, num mundo perfeito, tudo seria objeto, reutilizado em todos os programas, e o mundo seria um lugar bonito. Nem sempre é verdade e às vezes isso levaria a muita sobrecarga ou recursos desperdiçados. Você precisa ter isso em mente também.

    
por 27.02.2012 / 18:42
fonte
2

Muito bobo quando você adiciona manipulação de exceção à mistura.

Depois de "try, catch, finally" você fica com quatro declarações por método!

Considere também um método "validateForm" para um formulário de 20 campos, mesmo se você manipular todas as validações individuais em métodos separados, você ainda terá 20 métodos de validação de campo para invocar. De acordo com essas diretrizes, você acabaria com uma divisão sem sentido, como "validateTopOfScreen", "validateMiddleOfScreen" e "validateBottomOfScreen".

    
por 28.02.2012 / 09:21
fonte
2

A questão é confundir "regras" com "diretrizes". As regras devem ser obedecidas - as diretrizes são conselhos que devem levar você a considerar o que você está fazendo e, se realmente pudesse ser feito de uma maneira melhor.

Eu diria, em média, que a maioria da programação provavelmente é melhor seguindo as diretrizes, mas sempre haverá casos em que seguir as diretrizes dogmaticamente causará mais problemas do que eles pretendiam resolver. É por isso que eles não são apresentados como regras, mas como diretrizes.

Um respondente anterior mostrou que os redatores das diretrizes nunca pretenderam que fossem aplicados dogmaticamente e incluíram declarações nesse sentido em seu documento.

    
por 29.02.2012 / 16:40
fonte
0

Concordo com o soe dos comentários acima. 7 para mim é arbitrário e pode ser útil em algumas linguagens onde ruby, mas para linguagens como C #, Java, C ++ eu duvido dessa convenção de "7 linhas". Deixe-me dar um exemplo. Meu aplicativo atual tem 22 campos de texto e eu faço a validação do lado do servidor. O método é chamado validateInput () e minha preferência é validar todos os campos em um método em si, a menos que eu tenha validado algo complexo como checkEmailFormat (). Então, basicamente, meu código do método validateInput é de 108 linhas com chamadas ocasionais para validação complexa.

Agora imagine se eu chamei 25 métodos para validar cada campo. Se um novo desenvolvedor entrar, ele terá que entrar e sair do método principal para passar por 25 métodos que, por sua vez, podem chamar alguns outros. Ele está fadado a se perder em grandes projetos.

O que eu realmente faço para tornar meu código claro é fornecer comentários limpos que basicamente dizem o que essas 4 linhas estão fazendo ex -

validateInput (UserObj user) {

// Validar nome ....... ......

// validar sobrenome ...... ......

// validar e-mail ..... // muito complexo para verificar formato de e-mail expresion regular checkEmailFormat (); .... .....

e assim por diante .. }

    
por 29.02.2012 / 03:26
fonte
0

Má regra. Com código para manipulação de exceção, definindo campos de banco de dados, validação, como a maioria dos métodos pode ter menos de sete declarações? Nunca deveríamos fazer funções lambda inline?

Linhas de código são uma contagem arbitrária de complexidade. Com os métodos de extensão, posso criar um código como

                Parallel.ForEach(regions, region => {   Console.Write(region.Resorts.Where(x => x.name == "Four Seasons").OrderBy(x => x.RegionId).ThenBy(x => x.ResortId).ThenBy(x => x.name).ToList());   });
    
por 01.03.2012 / 20:41
fonte
-1

Todos os programadores juniores devem ser forçados a aderir a este princípio. Isso os forçaria a pensar sobre a estrutura do que eles estão ocupados, em vez de apenas adicionar mais e mais código de linhas.

Atualmente, estou vendo um método de 550 linhas de código com muitas instruções else e continua e retorna entrelaçadas. É porcaria. Se o programador tivesse sido forçado a pensar no que estava fazendo ...

    
por 27.02.2013 / 00:12
fonte