Sempre que me pego escrevendo a mesma lógica mais de uma vez, costumo colocá-la em uma função para que haja apenas um lugar no meu aplicativo que eu tenha para manter essa lógica. Um efeito colateral é que às vezes acabo com uma ou duas funções de linha, como:
function conditionMet(){
return x == condition;
}
OU
function runCallback(callback){
if($.isFunction(callback))
callback();
}
Isso é preguiçoso ou é uma prática ruim? Eu só pergunto porque isso resulta em um número maior de funções que exigem peças muito pequenas de lógica.
programming-practices
coding-standards
Mark Brown
fonte
fonte
Assert.AreEqual<int>(expected, actual, message, arg1, arg2, arg3, ...);
. O segundo está bem como está. Eu incluiria potencialmente um sinalizador bool opcional que ditaria se lançaria uma exceção / etc. caso o retorno de chamada não seja uma função.def yes(): return 'yes'
Respostas:
Hehe, oh Sr. Brown, se eu pudesse convencer todos os desenvolvedores que encontro a manter suas funções tão pequenas quanto isso, acredite, o mundo do software seria um lugar melhor!
1) A legibilidade do seu código aumenta dez vezes.
2) É tão fácil descobrir o processo do seu código por causa da legibilidade.
3) SECO - Não se repita - você está se adaptando muito bem a isso!
4) testável. As pequenas funções são um milhão de vezes mais fáceis de testar do que os métodos de 200 linhas que vemos com muita frequência.
Ah, e não se preocupe com o "salto de função" em termos de desempenho. As versões "Release" e as otimizações do compilador cuidam disso muito bem para nós, e o desempenho é 99% do tempo em outro lugar no design de sistemas.
Isso é preguiçoso? - Muito pelo contrário!
Isso é uma prática ruim? - Absolutamente não. Melhor usar essa maneira de criar métodos do que as bolas de alcatrão ou "objetos de Deus", que são muito comuns.
Mantenha o bom trabalho, meu colega artesão;)
fonte
Eu diria que um método refatorado é muito curto se:
Ex:
ou...
Ex:
Esse poderia ser um padrão válido, mas eu apenas incorporaria o método configureDialog (), neste exemplo, a menos que pretendesse substituí-lo ou reutilizar esse código em outro local.
fonte
Uma função pode ser muito curta? Em geral não.
De fato, a única maneira de garantir que:
É manter suas funções tão pequenas quanto possível. Ou, em outras palavras, extraia funções de suas funções até que você não possa mais extrair. Eu chamo isso de "Extrair até cair".
Para explicar isso: Uma função é um escopo com blocos de funcionalidade que se comunicam por variáveis. Uma classe também é um escopo com blocos de funcionalidade que se comunicam por variáveis. Portanto, uma função longa sempre pode ser substituída por uma ou mais classes com método pequeno.
Além disso, uma função que é grande o suficiente para permitir que você extraia outra função dela, está fazendo mais de uma coisa por definição . Portanto, se você pode extrair uma função de outra, deve extrair essa função.
Algumas pessoas temem que isso leve a uma proliferação de funções. Eles estão certos. Será. Isso é realmente uma coisa boa. É bom porque as funções têm nomes. Se você for cuidadoso ao escolher bons nomes, essas funções atuam como postagens de sinalização que direcionam outras pessoas através do seu código. De fato, funções bem nomeadas dentro de classes bem nomeadas dentro de namespaces bem nomeados são uma das melhores maneiras de garantir que seus leitores NÃO se percam.
Há muito mais sobre isso no episódio III do código limpo em cleancoders.com
fonte
Uau, a maioria dessas respostas não ajuda muito.
Nenhuma função deve ser escrita cuja identidade seja sua definição . Ou seja, se o nome da função for simplesmente o bloco de código da função escrito em inglês, não a escreva como uma função.
Considere sua função
conditionMet
e essa outra funçãoaddOne
(perdoe-me pelo meu JavaScript enferrujado):conditionMet
é uma definição conceitual adequada;addOne
é uma tautologia .conditionMet
é bom porque você não sabe o queconditionMet
implica apenas dizendo "condição atendida", mas pode ver por queaddOne
é bobo se você ler em inglês:Pelo amor de qualquer coisa que ainda possa ser santa, por favor, não escreva funções tautológicas!
(E pelo mesmo motivo, não escreva comentários para todas as linhas de código !)
fonte
function nametoolong() { return name.size > 15; }
ou.function successorIndex(x) { return x + 1; }
O problema com suas funções é, na verdade, apenas que o nome delas é ruim.Eu diria que, se você acha que a intenção de algum código pode ser aprimorada adicionando um comentário, em vez de adicionar esse comentário, extraia o código em seu próprio método. Não importa o tamanho do código.
Por exemplo, se o seu código for parecido com:
faça com que seja assim:
com
Ou, em outras palavras, não é sobre o tamanho do método, mas sobre o código de auto-documentação.
fonte
if x == PIXEL_ON
. Usar uma constante pode ser tão descritivo quanto usar um método e é um pouco mais breve.Eu acho que isso é exatamente o que você quer fazer. No momento, essa função pode ter apenas uma ou duas linhas, mas com o tempo ela pode crescer. Também ter mais chamadas de função permite ler as chamadas de função e entender o que está acontecendo lá dentro. Isso torna seu código muito seco (não se repita), que é muito mais sustentável.
fonte
conditionMet
é um nome muito genérico e não aceita argumentos, por isso testa algum estado? (x == xCondition) é, na maioria dos idiomas e situações, tão expressivo quanto 'xConditition'.Concordo com todos os outros posts que vi. Este é um bom estilo.
A sobrecarga de um método tão pequeno pode ser nula, pois o otimizador pode otimizar a ligação e alinhar o código. Um código simples como esse permite que o otimizador faça seu melhor trabalho.
O código deve ser escrito para maior clareza e simplicidade. Eu tento limitar um método a uma das duas funções: tomar decisões; ou realizando trabalho. Isso pode gerar métodos de uma linha. Quanto melhor eu estou fazendo isso, melhor eu acho o meu código.
Código como este tende a ter alta coesão e baixo acoplamento, o que é uma boa prática de codificação.
EDIT: Uma nota sobre os nomes dos métodos. Use um nome de método que indique o que o método não faz e como faz. Acho verb_noun (_modifier) é um bom esquema de nomenclatura. Isso fornece nomes como Find_Customer_ByName em vez de Select_Customer_Using_NameIdx. O segundo caso pode ficar incorreto quando o método é modificado. No primeiro caso, você pode trocar toda a implementação do banco de dados do Cliente.
fonte
A refatoração de uma linha de código em uma função parece excessiva. Pode haver casos excepcionais, como ver muitoooooongo / cumprimento de linhas ou expessões, mas eu não faria isso a menos que saiba que a função aumentará no futuro.
e seu primeiro exemplo sugere o uso de globais (que podem ou não falar de outros problemas no código), refatoraria ainda mais e tornaria essas duas variáveis como parâmetros:
O
conditionMet
exemplo pode ser útil se a condição for longa e repetitiva, como:fonte
conditionMet
função é apenas um==
operador detalhado . Provavelmente, isso não é útil.conditionMet (x, relation condition) {
aqui, onde você passa x, '==' e relação. Então você não precisa repetir o código para '<', '>', '<=', '! =' E assim por diante. Por outro lado - a maioria das linguagens tem essas construções incorporadas à medida que os operadores (condição x ==) fazem exatamente isso. Funções para instruções atômicas estão um passo longe demais.Considere isto:
Uma simples função de detecção de colisão:
Se você escreveu esse liner "simples" em seu código o tempo todo, pode cometer um erro. Além disso, seria realmente torturante escrever isso várias vezes.
fonte
#define
;)Não, e isso raramente é um problema. Agora, se alguém sente que nenhuma função deve ter mais de uma linha de código (se pudesse ser assim tão simples), isso seria um problema e, de certa forma, preguiçoso, porque eles não estão pensando no que é apropriado.
fonte
function isAdult () = { age >= 18; }
mas certamente nãoisAtLeast18
.Eu diria que eles são muito curtos, mas esta é a minha opinião subjetiva.
Porque:
Funções longas são ruins, mas funções menores que 3 linhas e executam apenas uma coisa são IMHO igualmente ruins.
Então, eu diria que apenas escreva função pequena se for:
Aposto que o próximo desenvolvedor (sênior) terá coisas melhores a fazer do que lembrar de todas as suas funções SetXToOne. Então eles se transformarão em peso morto em breve, de qualquer maneira.
fonte
Eu não gosto do exemplo não. 1, por causa do i-ésimo nome genérico.
conditionMet
não parece ser genérico, significa uma condição específica? GostarIsso seria bom. É uma diferença semântica, enquanto
não seria bom para mim.
Talvez seja usado com frequência e possa ser sujeito a alterações posteriores:
está bem também. Ao usá-lo várias vezes, você só precisa mudar um único local, se for necessário - talvez chantilly seja possível amanhã.
não é atômico e deve oferecer uma boa oportunidade de teste.
Se você precisa passar uma função, é claro, passe o que quiser e escreva funções de aparência boba.
Mas, em geral, vejo muito mais funções, que são muito longas, do que funções que são muito curtas.
Uma última palavra: algumas funções parecem apropriadas, porque são escritas muito detalhadas:
Se você vê, é o mesmo que
você não terá problemas com
ao invés de
fonte
Não há código como nenhum código!
Mantenha-o simples e não complique demais as coisas.
Não é ser preguiçoso, está fazendo o seu trabalho!
fonte
Sim, não há problema em ter uma função de código curto. No caso de métodos como "getters", "setters", "accesors" é muito comum, como as respostas anteriores mencionaram.
Às vezes, essas funções curtas de "accesors" são virtuais, porque quando substituídas nas subclasses, as funções terão mais código.
Se você deseja que sua função não seja tão curta, bem, em muitas funções, sejam elas globais ou métodos, eu geralmente uso uma variável "result" (estilo pascal) em vez de um retorno direto, é muito útil ao usar um depurador.
fonte
Curto demais nunca é um problema. Alguns motivos para funções curtas são:
Reutilização
Por exemplo, se você tem uma função, como um método definido, você pode afirmar que tem certeza de que os parâmetros são válidos. Essa verificação deve ser feita em qualquer lugar em que a variável estiver definida.
Manutenção
Você pode usar alguma declaração que acha que pode mudar no futuro. Por exemplo, agora você mostra um símbolo em uma coluna, mas depois isso pode mudar para outra coisa (ou até um sinal sonoro).
Uniformidade
Você está usando, por exemplo, o padrão de fachada e a única coisa que uma função faz é passar exatamente a função para outra sem alterar os argumentos.
fonte
Quando você dá um nome a uma seção de código, é essencialmente para dar um nome a ela . Isso pode ser por qualquer um de vários motivos, mas o ponto crucial é se você pode atribuir um nome significativo ao seu programa. Nomes como "addOneToCounter" não adicionariam nada, mas
conditionMet()
sim.Se você precisar de uma regra para descobrir se o snippet é muito curto ou muito longo, considere quanto tempo leva para encontrar um nome significativo para o snippet. Se você não puder dentro de um período de tempo razoável, o snippet não será um tamanho adequado.
fonte
Não, mas pode ser muito conciso.
Lembre-se: o código é escrito uma vez, mas é lido muitas vezes.
Não escreva código para o compilador. Escreva para futuros desenvolvedores que precisarão manter seu código.
fonte
Sim querido, a função pode ser cada vez menor e se é bom ou ruim, depende da linguagem / estrutura que você está usando.
Na minha opinião, eu trabalho principalmente em Front End Technologies, as Small Functions são usadas principalmente como funções auxiliares; você provavelmente as usará muito quando estiver trabalhando com filtros pequenos e usando a mesma lógica em seu aplicativo. Se seu aplicativo tiver muita lógica comum, haverá várias funções pequenas.
Porém, em um aplicativo em que você não possui lógica comum, não será obrigado a criar pequenas funções, mas poderá dividir seu código em segmentos em que fica fácil gerenciar e entender.
Em geral, dividir seu código enorme em pequenas funções é uma abordagem muito boa. Em estruturas e linguagens modernas, você será obrigado a fazê-lo, por exemplo,
é uma função anônima no ES 2017 JavaScript e Typescript
no código acima, você pode ver 3 declarações de funções e 2 chamadas de funções. Esta é uma simples chamada de serviço no Angular 4 com texto datilografado. Você pode pensar nisso como seus requisitos
Acima, são 3 funções anônimas na linguagem clojure
O acima é uma declaração funcional em clojure
Portanto, sim, as FUNÇÕES podem ser menores, mas se é bom ou ruim, se você tem funções como:
Bem, não é uma boa prática fazê-lo, mas e se você estiver usando esta função em uma tag HTML, como fazemos no Angular Framework, se não houver suporte para Incremento ou Decremento em Modelos HTML Angulares, essa seria a solução para mim.
Vamos dar outro exemplo
O exemplo acima é essencial ao reproduzir quando matrizes dentro de modelos HTML angulares. Então, às vezes, você terá que criar pequenas funções
fonte
Não concordo com quase a resposta dada neste momento.
Recentemente eu encontrei um colega que escreve todas as turmas da seguinte forma:
Esse poderia ser um bom código em casos esporádicos, mas certamente não se você definir muitas classes com muitas e muitas propriedades. Não quero dizer, com isso, que métodos como os mencionados acima não sejam escritos. Mas, se você acabar escrevendo a maior parte do código como "invólucro" da lógica real, há algo errado.
Provavelmente, o programador perde a lógica geral, teme mudanças futuras e refatora o código.
A definição da interface é porque uma necessidade real; de fato, se você precisar definir e obter uma propriedade simples (sem muita lógica, o que reduz o membro), isso será possível. Mas, se a necessidade real pode ser analisada de uma maneira diferente, por que não definir uma interface mais intuitiva?
Para realmente responder à pergunta, é claro que não, e a razão é muito óbvia: o método / propriedade / o que mais deve ser definido para o que precisa. Mesmo uma função virtual vazia tem um motivo para existir.
fonte