Os métodos longos são sempre ruins? [fechadas]


64

Então, olhando ao redor mais cedo, notei alguns comentários sobre métodos longos serem uma prática ruim.

Não tenho certeza se sempre concordo que métodos longos são ruins (e gostariam da opinião de outras pessoas).

Por exemplo, eu tenho algumas visualizações do Django que processam um pouco os objetos antes de enviá-las para a visualização, um método longo são 350 linhas de código. Eu tenho meu código escrito para que ele lide com os parâmetros - classificando / filtrando o conjunto de consultas e, pouco a pouco, faz algum processamento nos objetos que minha consulta retornou.

Portanto, o processamento é principalmente agregação condicional, que possui regras complexas o suficiente que não podem ser feitas facilmente no banco de dados, portanto, algumas variáveis ​​declaradas fora do loop principal são alteradas durante o loop.

variable_1 = 0
variable_2 = 0
for object in queryset :
     if object.condition_condition_a and variable_2 > 0 :
     variable 1+= 1
     .....
     ...    
     . 
      more conditions to alter the variables

return queryset, and context 

Então, de acordo com a teoria, devo fatorar todo o código em métodos menores, para que eu tenha o método view como tendo no máximo uma página.

No entanto, tendo trabalhado em várias bases de código no passado, às vezes acho que torna o código menos legível, quando você precisa pular constantemente de um método para o próximo, descobrindo todas as partes dele, mantendo o método mais externo em sua cabeça.

Acho que, com um método longo e bem formatado, é possível ver a lógica mais facilmente, pois ela não está sendo ocultada nos métodos internos.

Eu poderia fatorar o código em métodos menores, mas muitas vezes há um loop interno sendo usado para duas ou três coisas, por isso resultaria em código mais complexo, ou métodos que não fazem uma coisa, mas duas ou três (alternativamente Eu poderia repetir loops internos para cada tarefa, mas haverá um impacto no desempenho).

Existe um caso em que métodos longos nem sempre são ruins? Há sempre um caso para os métodos de escrita, quando eles serão usados ​​apenas em um só lugar?

ATUALIZAÇÃO: Parece que eu fiz essa pergunta há mais de um ano.

Então, refatorei o código após a resposta (mista) aqui, dividi-o em métodos. É um aplicativo Django que recupera conjuntos complexos de objetos relacionados do banco de dados, portanto o argumento de teste está fora (provavelmente levaria a maior parte do ano para criar objetos relevantes para os casos de teste. Eu tenho um tipo "isso precisa ser feito ontem" ambiente de trabalho antes que alguém reclame). Corrigir bugs nessa parte do código é marginalmente mais fácil agora, mas não em massa.

antes :

#comment 1 
bit of (uncomplicated) code 1a  
bit of code 2a

#comment 2 
bit of code 2a
bit of code 2b
bit of code 2c

#comment 3
bit of code 3

agora:

method_call_1
method_call_2
method_call_3

def method_1 
    bit of (uncomplicated) code 1a  
    bit of code 2a

def method_2 
    bit of code 2a
    bit of code 2b
    bit of code 2c

def method_3
    bit of code 3

156
Todos os absolutos são ruins. Sempre.
Joachim Sauer

30
Vejo o argumento "extrair métodos se você puder reutilizá-los" com bastante frequência (nesta ou em formas semelhantes), mas não o adianto: se o método estiver fazendo mais de uma coisa, você deve extrair métodos para facilitar a leitura / manutenção, mesmo que esses novos métodos sejam chamados de apenas um ponto no seu código.
Joachim Sauer

4
@gnat: uau, algum tipo de embutimento manual (via pré-processador) na etapa de compilação não seria uma solução melhor aqui?
Joachim Sauer

11
Um dos melhores programadores que conheço comentou que, se você realmente deseja uma medida, o número de variáveis ​​locais é melhor que o tamanho real. Ele estava trabalhando em um otimizador de caminho complexo, em que a coragem era um método de várias centenas de linhas, mas a quantidade de estado (variáveis ​​locais) sendo mantida era muito pequena.
Chuu 15/10/12

2
Métodos longos nem sempre são ruins; mas eles são algo que você deve sempre olhar e se perguntar "isso é ruim?"
Carson63000

Respostas:


80

Não, métodos longos nem sempre são ruins.

No livro Código Completo , mede-se que métodos longos às vezes são mais rápidos e fáceis de escrever e não levam a problemas de manutenção.

De fato, o que é realmente importante é permanecer SECO e respeitar a separação de preocupações. Em algum momento, o cálculo será demorado, mas realmente não causará problemas no futuro.

No entanto, pela minha experiência pessoal, a maioria dos métodos longos costuma ter falta de preocupação. De fato, métodos longos são uma maneira fácil de detectar que algo PODE estar errado no código, e que um cuidado especial é necessário aqui ao fazer a revisão do código.

EDIT: À medida que os comentários são feitos, eu adiciono um ponto interessante à resposta. Na verdade, eu também verificaria as métricas de complexidade da função (NPATH, complexidade ciclomática ou CRAP ainda melhor).

Na verdade, eu recomendo não verificar essas métricas em funções longas, mas incluir alertas nelas com ferramentas automatizadas (como estilo de verificação para java, por exemplo) EM TODAS AS FUNÇÕES.


41
+1: "Não, métodos longos nem sempre são ruins", mas quase sempre são ruins
Binary Worrier 15/10/12

67
Os corpos de métodos longos são um cheiro de código clássico : não é, por si só, um problema, mas é uma indicação de que provavelmente há um problema lá.
Joachim Sauer

6
+1, mas ainda assim recomendo verificar a complexidade ciclomática do método long. Valores altos indicam métodos que são efetivamente impossíveis de realizar testes de unidade (e métodos longos raramente são desprovidos da lógica do fluxo de controle).
Daniel B

11
Eu uso nomes de métodos para minimizar comentários. Às vezes, isso leva a coisas como "getSelectedNodeWithChildren", mas meu colega continua me dizendo que meu código é bem legível. Eu também tento evitar abreviações, elas são legais de escrever, mas não tão legais de ler.
K ..

4
@ da_b0uncer Essa também é uma política que eu sigo. É mais difícil ler o código do que escrevê-lo; portanto, um esforço extra ao escrever para tornar o código mais legível compensa.
Deadalnix 15/10/12

55

A maior parte do foco aqui parece estar sempre presente . Sim, absolutos são ruins, e a engenharia de software é quase tanto arte quanto ciência, e tudo isso ... mas eu vou ter que dizer que, para o exemplo que você deu, o método seria melhor se fosse dividido acima. Estes são os argumentos que eu normalmente usaria para justificar a divisão do seu método:

Legibilidade: Não tenho certeza dos outros, mas não consigo ler 350 linhas de código rapidamente. Sim, se é o meu próprio código, e eu posso fazer muitas suposições sobre isso, eu poderia examiná-lo muito rapidamente, mas isso está além do ponto. Considere como esse método seria mais fácil de ler, se consistisse em 10 chamadas para outros métodos (cada um com um nome descritivo). Ao fazer isso, você introduziu uma camada no código, e o método de alto nível fornece um esboço breve e agradável ao leitor sobre o que está acontecendo.

Editar - para colocar isso de uma maneira diferente, pense assim: como você explicaria esse método para um novo membro da equipe? Certamente, tem alguma estrutura que você pode resumir ao longo das linhas de "bem, começa fazendo A, depois B, depois às vezes C, etc". Ter um breve método de "visão geral" chamando outros métodos torna essa estrutura óbvia. É extremamente raro encontrar 350 linhas de código que não se beneficiam; se o cérebro humano não pretende lidar com listas de centenas de itens, nós os agrupamos.

Reutilização: métodos longos tendem a ter baixa coesão - geralmente fazem mais de uma coisa. A baixa coesão é inimiga da reutilização; se você combinar várias tarefas em um método, ele será reutilizado em menos lugares do que deveria.

Testabilidade e coesão: mencionei a complexidade ciclomática em um comentário acima - é uma boa medida de quão complexo é o seu método. Ele representa o limite inferior do número de caminhos exclusivos através do seu código, dependendo das entradas (editar: corrigido de acordo com o comentário de MichaelT). Isso também significa que, para testar seu método corretamente, você precisa ter pelo menos tantos casos de teste quanto o número de complexidade ciclomática. Infelizmente, quando você cria partes de código que não são realmente dependentes uma da outra, não há como ter certeza dessa falta de dependência, e a complexidade tende a se multiplicar. Você pode pensar nessa medida como uma indicação do número de coisas diferentes que você está tentando fazer. Se estiver muito alto, é hora de dividir e conquistar.

Refatoração e estrutura: métodos longos geralmente indicam que falta alguma estrutura no código. Freqüentemente, o desenvolvedor não conseguiu descobrir quais são os pontos em comum entre as diferentes partes desse método e onde uma linha pode ser traçada entre eles. Perceber que um método longo é um problema e tentar dividi-lo em métodos menores é o primeiro passo em um caminho mais longo para realmente identificar uma estrutura melhor para a coisa toda. Talvez você precise criar uma classe ou duas; não será necessariamente mais complexo no final!

Eu também acho que, neste caso, a desculpa para ter um método longo é "... algumas variáveis ​​declaradas fora do loop principal são alteradas durante o loop". Não sou especialista em Python, mas tenho quase certeza de que esse problema pode ser corrigido trivialmente por alguma forma de passagem por referência.


13
+1 por rejeitar a parte sempre da pergunta e se concentrar na carne: se os métodos longos são ruins ou não. Eu acho que o OP está procurando justificativa como se o cenário dele fosse um caso extremo, embora geralmente quando ouço as pessoas explicando suas más práticas como necessárias para o cenário incomum, é apenas porque elas não se esforçaram muito para usar boas práticas. Os cenários incomuns são realmente muito incomuns, métodos longos são infelizmente muito comuns.
Jimmy Hoffa

2
OK, olhando para a lista acima: a legibilidade que eu diria da experiência passada é aumentada ao ter o método mais longo, contendo muitos comentários e bem formatado, em vez de precisar pular o código do método para os métodos Embora isso seja provavelmente bastante subjetivo. Não espero que as partes do código sejam reutilizadas. A maior parte da reutilização do código é obtida a partir da herança no momento.
Wobily_col #

11
@wobbily_col BTW, se você estiver procurando por um texto bem escrito que analise os métodos mais curtos, leia os primeiros capítulos do Código Limpo , que fazem um bom trabalho na explicação.
Daniel B

5
@wobbily_col Você diz que ter que pular muito para entender o código com muitos métodos é confuso, acho que o ponto que falta aqui é a importância da nomeação. Se um método é bem nomeado, você não precisa procurá-lo para descobrir o que está fazendo, o método de chamada deve ser completamente compreensível sem nenhum conhecimento subjacente do que os métodos que ele está fazendo, por exemplo, você já usou someVar.toString()e sentiu você precisava ver o código do toString para saber o que está fazendo? Você acabou de ler o passado por causa da boa nomeação de métodos.
21812 Jimmy Hoffa

4
Em uma nota lateral, ter um método que precise de n parâmetros também é um cheiro de código e indica que o método pode fazer mais de uma coisa. O mesmo vale para ter um método difícil de nomear. E se ele realmente precisa de todos esses parâmetros, eles geralmente fazem parte de um conceito maior, que pode e deve ser incluído em uma classe própria. Obviamente, poderíamos criar um exemplo que é melhor não usar essa regra - meu argumento é que, se você vir esse método, investigá-lo completamente, provavelmente é ruim de alguma forma.
KL

28

Métodos longos são sempre ruins, mas ocasionalmente são melhores que as alternativas.


5
sem uma explicação, essa resposta pode se tornar inútil se outra pessoa postar uma opinião oposta. Por exemplo, se alguém postar uma declaração como "Métodos longos nunca são ruins, mas são ocasionalmente piores que as alternativas". , como essa resposta ajudaria o leitor a escolher duas opiniões opostas? Considere editar ing-lo em uma melhor forma
mosquito

9

Métodos longos são um cheiro de código . Eles geralmente indicam que algo está errado, mas não é uma regra rígida. Normalmente, os casos em que são justificados envolvem muitas regras de negócios estatais e bastante complexas (como você descobriu).

Quanto à sua outra pergunta, é frequentemente útil separar pedaços de lógica em métodos separados, mesmo que sejam chamados apenas uma vez. Isso facilita a visualização da lógica de alto nível e pode tornar a manipulação de exceções um pouco mais limpa. Contanto que você não precise passar vinte parâmetros para representar o estado do processamento!


7

Métodos longos nem sempre são ruins. Eles geralmente são um sinal de que pode haver um problema.

No sistema em que estou trabalhando, temos meia dúzia de métodos com mais de 10.000 linhas de comprimento. Um deles tem atualmente 54.830 linhas. E tudo bem.

Essas funções ridiculamente longas são muito simples e são geradas automaticamente. Esse grande monstro de 54.830 linhas contém os dados diários de movimento polar de 1 de janeiro de 1962 a 10 de janeiro de 2012 (nossa última versão). Também liberamos um procedimento pelo qual nossos usuários podem atualizar esse arquivo gerado automaticamente. Esse arquivo de origem contém os dados de movimento polar de http://data.iers.org/products/214/14443/orig/eopc04_08_IAU2000.62-now , traduzidos automaticamente para C ++.

Não é possível ler esse site em tempo real em uma instalação segura. Não há conexão com o mundo exterior. Baixar o site como uma cópia local e analisar em C ++ também não é uma opção; a análise é lenta e isso deve ser rápido. Download, tradução automática para C ++ e compilação: Agora você tem algo rápido. (Apenas não o compile otimizado. É incrível quanto tempo um compilador otimizador leva para compilar 50.000 linhas de código de linha reta extremamente simples. Leva mais de meia hora no meu computador para compilar esse arquivo otimizado. E a otimização não realiza absolutamente nada Não há nada para otimizar. É um código linear simples, uma declaração de atribuição após a outra.)


6
"uma declaração de atribuição após a outra" ... eu chamaria isso de "arquivo de dados". Por que é código?
Joachim Sauer

3
@JoachimSauer - Porque analisar um grande arquivo de dados em tempo de execução em uma instalação de Monte Carlo é uma má idéia. Uma ideia muito, muito ruim.
11138 David Hammen

4
@ DavidHammen: faça-o no momento da inicialização, exatamente como você está forçando seu vinculador / carregador a fazer. Ou escreva o arquivo de dados como uma estrutura C em um arquivo de cabeçalho, em vez do código C. Pelo menos o carregador carregaria como um bloco de dados.
21412 Javier

3
@Javier: Mesmo no momento da inicialização, pode ser uma péssima idéia, pelo menos em uma configuração de Monte Carlo. Uma simulação que leva alguns minutos para inicializar, mas apenas alguns segundos para executar, contraria o processo de obter dezenas de milhares de execuções durante a noite. Alterar as tarefas de tempo de inicialização das chaves para compilar tarefas de tempo corrige esse problema. Tentamos várias técnicas, incluindo a abordagem de estrutura de dados compilada. Simplesmente não funciona ou seria muito difícil fazer o trabalho em alguns casos (por exemplo, um grande modelo de gravidade). A abordagem do código linear é fácil de gerar automaticamente, de verificar. É apenas um código feio.
10134 David Hammen

7
+1 história interessante. o código gerado não é realmente o código-fonte, é claro, portanto, pode-se argumentar que isso não 'quebra' a regra. presume-se que o gerador de código em si tenha bons métodos curtos
jk.

7

Digamos apenas que existem maneiras boas e ruins de interromper um método longo. Ter que "[manter] o método mais externo em sua cabeça" é um sinal de que você não o está quebrando da melhor maneira possível, ou que seus submétodos são mal nomeados. Em teoria, há casos em que um método longo é melhor. Na prática, é extremamente raro. Se você não conseguir descobrir como tornar um método mais curto legível, peça a alguém para revisar seu código e peça especificamente idéias sobre como encurtar os métodos.

Quanto a vários loops que causam um suposto impacto no desempenho, não há como saber isso sem medir. Vários loops menores podem ser significativamente mais rápidos se isso significa que tudo o que precisa pode permanecer no cache. Mesmo se houver um impacto no desempenho, geralmente é insignificante em favor da legibilidade.

Eu direi que geralmente os métodos longos são mais fáceis de escrever , embora sejam mais difíceis de ler . É por isso que eles proliferam, embora ninguém goste deles. Não há nada de errado em planejar desde o início a refatoração antes de fazer o check-in.


11
"Não há nada errado em planejar desde o início a refatoração antes de fazer o check-in". +1 para isso. Atualmente, a maioria dos IDEs possui ferramentas de refatoração que tornam isso extremamente fácil também. Mas existe um método reverso no qual você delega coisas para funções inexistentes e depois vai e preenche os métodos, mas nunca consegui codificar dessa maneira, por mais que tentei.
Tjaart

+1 para "Ter que" [manter] o método mais externo em sua cabeça "é um sinal de que você não está dividindo da melhor maneira possível",
Michael Shaw

4

Métodos longos podem ser mais computacionais e eficientes em termos de espaço, pode ser mais fácil ver a lógica e mais fácil depurá-los. No entanto, essas regras só se aplicam quando apenas um programador toca nesse código. O código será muito difícil de estender se não for atômico; essencialmente, a próxima pessoa terá que começar do zero e, em seguida, depurar e testar isso levará uma eternidade, pois não está usando nenhum código válido.


34
Sempre há pelo menos dois programadores envolvidos: "você" e "você, daqui a três semanas".
Joachim Sauer

3

Há algo que chamamos de Decomposição Funcional, que implica dividir seus métodos mais longos em métodos menores, sempre que possível. Como você mencionou que seu método envolve classificação / filtragem, é melhor você ter métodos ou funções separados para essas tarefas.

Precisamente, seu método deve se concentrar apenas na execução de 1 tarefa.

E se precisar chamar outro método para algum motivo, faça-o de outra forma com o que você já está escrevendo. Também para fins de legibilidade, você pode adicionar comentários. Convencionalmente, os programadores usam comentários de várias linhas (/ ** / em C, C ++, C # e Java) para descrições de métodos e usam comentários de linha única (// em C, C ++, C # e Java). Também existem boas ferramentas de documentação disponíveis para maior legibilidade do código (por exemplo, JavaDoc ). Você também pode pesquisar comentários baseados em XML se for um desenvolvedor .Net.

Os loops afetam o desempenho do programa e podem causar sobrecarga no aplicativo, se não forem utilizados adequadamente. A idéia é projetar seu algoritmo de forma que você use loops aninhados o mínimo possível.


Também conhecida como "Uma função deve fazer UMA COISA".
Lorddev 18/10

3

É perfeitamente bom escrever funções demoradas. Mas isso varia no contexto, se você realmente precisa ou não. Por exemplo, alguns dos melhores algorthms são expressos melhor quando um pedaço. Por outro lado, uma grande porcentagem de rotinas em programas orientados a objetos serão rotinas de acessadores, que serão muito curtas. Algumas das rotinas de processamento demoradas que possuem casos de comutação longos, se as condições puderem ser otimizadas através de métodos orientados por tabela.

Há uma excelente discussão curta no Código Completo 2 sobre o tamanho das rotinas.

O melhor comprimento máximo teórico 497 é geralmente descrito como uma ou duas páginas da lista de programas, 66 a 132 linhas. Os programas modernos tendem a ter volumes de rotinas extremamente curtas misturadas com algumas rotinas mais longas.

Décadas de evidências dizem que rotinas com esse tamanho não são mais propensas a erros do que rotinas mais curtas. Permitir que questões como profundidade de aninhamento, número de variáveis ​​e outras considerações relacionadas à complexidade ditem a duração da rotina em vez de impor uma duração

Se você deseja escrever rotinas com mais de 200 linhas, tenha cuidado. Nenhum dos estudos que relataram custo reduzido, taxas de erro reduzidas ou ambos com rotinas maiores distinguiram entre tamanhos maiores que 200 linhas, e você provavelmente encontrará um limite superior de compreensão ao passar 200 linhas de código. 536 restrição per se.


2

Outra votação que quase sempre está errada. No entanto, encontro dois casos básicos em que é a resposta adequada:

1) Um método que basicamente chama vários outros métodos e que não funciona em si. Você tem um processo que leva 50 etapas para realizar, você obtém um método com 50 chamadas. Geralmente, não há nada a ganhar tentando acabar com isso.

2) Despachantes. O design de POO se livrou da maioria desses métodos, mas as fontes de dados recebidas são, por sua própria natureza, apenas dados e, portanto, não podem seguir os princípios de POO. Não é exatamente incomum ter algum tipo de rotina de expedidor no código que manipula os dados.

Eu diria também que não se deve considerar a questão ao lidar com coisas geradas automaticamente. Ninguém está tentando entender o que o código gerado automaticamente, não importa se é fácil para um ser humano entender.


11
O processo de 50 etapas provavelmente pode ser resumido em vários intervalos. As etapas 1 a 9 são verificações de parâmetros, portanto, crie um novo método chamado verificação de parâmetros. (Tenho certeza de que existem alguns exemplos em que isso não é possível. Eu estaria interessado em ver um).
sixtyfootersdude

@sixtyfootersdude: Claro, você pode acabar com isso. Eu não disse que era impossível, eu disse que não havia nada a ganhar com a separação. Embora não tenham sido 50 passos, eu atingi algo parecido: Criando um mundo de jogo. O número 1 criou o mundo vazio, o número 2 criou o terreno e, em seguida, um monte de passos depois que o massagearam de uma maneira ou de outra.
Loren Pechtel 17/10/12

& sixtyfootersdude: É incrível como você conhece o código que nunca viu e como melhorá-lo.
gnasher729 16/07

2

Eu queria abordar o exemplo que você deu:

Por exemplo, eu tenho algumas visualizações do Django que processam um pouco os objetos antes de enviá-las para a visualização, um método longo são 350 linhas de código. Eu tenho meu código escrito para que ele lide com os paramaters - classificando / filtrando o conjunto de consultas e, pouco a pouco, processando os objetos que minha consulta retornou.

Na minha empresa, nosso maior projeto é construído no Django e também temos funções de visualização longa (muitas são mais de 350 linhas). Eu diria que a nossa não precisa demorar tanto, e eles estão nos machucando.

Essas funções de exibição estão realizando um trabalho muito relacionado que deve ser extraído para o modelo, classes auxiliares ou funções auxiliares. Além disso, acabamos reutilizando visualizações para fazer coisas diferentes, que devem ser divididas em visualizações mais coesas.

Suspeito que suas opiniões tenham características semelhantes. No meu caso, sei que isso causa problemas e estou trabalhando para fazer alterações. Se você não concorda que está causando problemas, não precisa corrigi-lo.


2

Não sei se alguém já mencionou isso, mas uma das razões pelas quais os métodos longos são ruins é porque geralmente envolvem vários níveis diferentes de abstração. Você tem variáveis ​​de loop e todos os tipos de coisas acontecendo. Considere a função fictícia:

function nextSlide() {
  var content = getNextSlideContent();
  hideCurrentSlide();
  var newSlide = createSlide(content);
  setNextSlide(newSlide);
  showNextSlide();
}

Se você estivesse fazendo toda a animação, cálculo, acesso a dados etc. nessa função, seria uma bagunça. A função nextSlide () mantém uma camada de abstração consistente (o sistema de estado do slide) e ignora outras. Isso torna o código legível.

Se você precisar constantemente usar métodos menores para ver o que eles fazem, o exercício de dividir a função falhará. Só porque o código que você está lendo não está fazendo coisas óbvias nos métodos filhos não significa que os métodos filhos sejam uma má ideia, apenas que foi feita incorretamente.

Quando crio métodos, geralmente acabo dividindo-os em métodos menores, como uma espécie de estratégia de dividir e conquistar. Um método como

   if (hasMoreRecords()) { ... }

é certamente mais legível do que

if (file.isOpen() && i < recordLimit && currentRecord != null) { ... } 

Direito?

Concordo que afirmações absolutas são ruins e também concordo que geralmente um método longo é ruim.


1

História real. Certa vez, encontrei um método com mais de duas mil linhas. O método tinha regiões que descreviam o que estava fazendo nessas regiões. Depois de ler uma região, decidi fazer um método de extração automatizada, nomeando-o de acordo com o nome da região. quando terminei, o método não passava de 40 chamadas de método, com cerca de cinquenta linhas cada, e tudo funcionava da mesma maneira.

O que é muito grande é subjetivo. Às vezes, um método não pode ser dividido além do que é atualmente. É como escrever um livro. A maioria das pessoas concorda que parágrafos longos geralmente devem ser divididos. Mas, às vezes, há apenas uma idéia e dividi-la causa mais confusão do que seria causado pelo comprimento desse parágrafo.


0

O objetivo de um método é ajudar a reduzir a regurgitação de código. Um método deve ter uma função específica pela qual é responsável. Se você acabar reformulando o código em vários locais, corre o risco de obter resultados inesperados se as especificações que o software foi projetado para atender forem alteradas.

Para um método ter 350 linhas, sugeriria que muitas das tarefas que ele está executando são replicadas em outros lugares, pois é incomum exigir uma quantidade tão grande de código para executar uma tarefa especializada.


Ajude a reduzir o código, o que ?
Avner Shahar-Kashtan,

@ AvnerShahar-Kashtan, ele provavelmente significa "duplicação" :-)
Péter Török

0

Na verdade, não são os métodos longos que são más práticas, é mais deixá-los assim.

Quero dizer que o ato real de refatorar sua amostra de:

varaible_1 = 0
variable_2 = 0
for object in queryset :
     if object.condition_condition_a and variable_2 > 0 :
     variable 1+= 1
     .....
     ...    
     . 
      more conditions to alter the variables

return queryset, and context 

para

Status status = new Status();
status.variable1 = 0;
status.variable2 = 0;
for object in queryset :
     if object.condition_condition_a and status.variable2 > 0 :
     status.variable1 += 1
     .....
     ...    
     . 
      more conditions to alter the variables (status)

return queryset, and context 

e depois para

class Status {
    variable1 = 0;
    variable2 = 0;

    void update(object) {
        if object.condition_condition_a and variable2 > 0 {
            variable1 += 1
        }
    }
};

Status status = new Status();
for object in queryset :
     status.update(object);
     .....
     ...    
     . 
      more conditions to alter the variables (status)

return queryset, and context 

Agora você está no caminho certo, não apenas para um método muito mais curto, mas para um método muito mais utilizável e compreensível.


0

Eu acho que o fato de o método ser muito longo é algo a ser verificado, mas definitivamente não é um antipadrão instantâneo. A grande coisa a procurar em métodos enormes é muito aninhamento. Se você tem

foreach(var x in y)
{
    //do ALL the things
    //....
}

e o corpo do loop não é extremamente localizado (ou seja, você pode enviar menos de quatro parâmetros), provavelmente é melhor convertê-lo para:

foreach(var x in y)
{
    DoAllTheThings(x);
}
...
void DoAllTheThings(object x)
{
    //do ALL the things
    //....
}

Por sua vez, isso pode reduzir bastante o comprimento de uma função. Além disso, procure um código duplicado na função e mova-o para uma função separada

Finalmente, alguns métodos são longos e complicados e não há nada que você possa fazer. Alguns problemas precisam de soluções que não sejam fáceis de codificar. Por exemplo, analisar uma gramática de muita complexidade pode criar métodos realmente longos que você realmente não pode fazer muito sem piorá-lo.


0

A verdade é que depende. Como mencionado, se o código não separar preocupações e tentar fazer tudo em um método, será um problema. A separação do código em vários módulos facilita a leitura do código e a gravação do código (por vários programadores). Aderir a um módulo (classe) por arquivo de origem é uma boa idéia para começar.

Em segundo lugar, quando se trata de funções / procedimentos:

void setDataValueAndCheckForRange(Data *data) {/*code*/} 

é um bom método se verificar apenas o intervalo de "Dados". É um método MAU quando o mesmo intervalo se aplica a várias funções (exemplo de código incorreto):

void setDataValueAndCheckForRange(Data *data){ /*code */}
void addDataValuesAndCheckForRange(Data *result, Data *d1, Data *d2){ /*code*/}
void subDataValuesAndCheckForRange(Data *result, Data *d1, Data *d2){ /*code*/}
void mulDataValuesAndCheckForRange(Data *result, Data *d1, Data *d2){ /*code*/}

Isso deve ser refatorado para:

bool isWithinRange(Data *d){ /*code*/ }
void setDataValue(Data *d) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 
void addDataValue(Data *d, Data *d1, Data *d2) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 
void subDataValue(Data *d, Data *d1, Data *d2) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 
void mulDataValue(Data *d, Data *d1, Data *d2) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 

REUTILIZE o código o máximo possível. E isso é possível quando cada função do seu programa é SIMPLES (não necessariamente fácil) o suficiente.

CITAÇÃO: A MONTANHA é composta de pequenos grãos de terra. O oceano é composto de pequenas gotas de água .. (- Sivananda)


0

Métodos longos tendem a ser "ruins" em linguagens imperativas que favorecem afirmações, efeitos colaterais e mutabilidade, precisamente porque esses recursos aumentam a complexidade e, portanto, os erros.

Nas linguagens de programação funcionais, que favorecem expressões, pureza e imutabilidade, há menos motivos para preocupação.

Em linguagens funcionais e imperativas, é sempre melhor levar em consideração trechos reutilizáveis ​​de código em rotinas comuns de nível superior, mas em linguagens funcionais que suportam escopo lexical com funções aninhadas etc., é realmente melhor encapsulamento para ocultar sub-rotinas na parte superior função de nível superior (método) do que dividi-las em outras funções de nível superior.


Em linguagens funcionais, porém, métodos longos são muito menos comuns.
precisa saber é
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.