Uma defesa para clichê?

14

Para mim, o código padrão é obviamente ruim. No entanto, eu conheci um desenvolvedor que mostra resistência em qualquer tentativa de reduzir o clichê. Percebi que não tinha um argumento prontamente formado e bem pensado, além da aversão que desenvolvi para ele ao longo do tempo.

Para que eu possa formar um argumento convincente a favor de menos clichês, quais são alguns contra-argumentos? Em outras palavras, quais são os argumentos (se houver) a favor do clichê?

(Quero dizer, o que acho que geralmente se entende por boilerplate, mas um bom exemplo são getters e setters em Java.)

abstraído
fonte
7
Argumentos contra código duplicado (assumindo que o clichê é copiado / colado): stackoverflow.com/a/2490897/1583
Oded
1
@ Oded: Isso mesmo. Mas você interpretou mal a pergunta. :) Ele está tentando verificar se há algo a dizer sobre o código padrão. Meu palpite é que ele está muito bem informado sobre as desvantagens.
Steven Jeuris
3
@ StevenJeuris - eu li a pergunta perfeitamente. Por isso não postei uma resposta. Estou apenas adicionando ao outro lado do argumento. Só assim o OP tem "um prontamente formados, bem pensado argumento passado a aversão que tenho desenvolvido por ele ao longo do tempo" para a próxima vez;)
Oded
2
Clichê pode ser esteticamente agradável: en.wikipedia.org/wiki/This_Is_the_House_That_Jack_Built
SK-lógica
Várias boas respostas e comentários que se complementam ... difícil escolher qual deles aceitar.
abstraído

Respostas:

15

Uma coisa importante a lembrar é que o código geralmente é menor ao remover o contexto desnecessário. Se o compilador puder descobrir alguma coisa, continua o argumento, não há necessidade de escrevê-lo explicitamente.

E isso seria ótimo se apenas o compilador pretendesse lê-lo. Mas lembre-se de que "os programas devem ser escritos para as pessoas lerem e, incidentalmente, para as máquinas executarem". (Ironicamente, essa citação vem de um livro didático dedicado a uma das línguas mais difíceis de serem lidas por seres humanos comuns, devido em grande parte à sua excessiva discrepância.)

O que pode parecer chato e repetitivo para você, enquanto você está escrevendo, pode ser um contexto valioso para alguém que aparece um ano (ou cinco) depois e precisa manter seu código.

WRT especificamente o exemplo de Java, eu concordo que esse é um bom exemplo de clichê ruim, pois pode ser substituído por algo mais curto e fácil de ler, e também mais flexível: Propriedades. Mas isso não significa que todos os elementos sintáticos padronizados de todas as linguagens são tão inúteis quanto os getters e setters do Java e C ++.

Mason Wheeler
fonte
7
Obviamente, esse argumento funciona nos dois sentidos. Existe uma quantidade considerável de código padrão para apaziguar o compilador e não ajuda os seres humanos a compreender - para ficar com getters / setters, essas dezenas de linhas precisam ser lidas inteiramente para garantir que "esses são apenas getters e setters" , em vez de ler uma única linha curta por propriedade, que simplesmente afirma que é uma propriedade e que tipo ela possui.
6
Eu acho que o clichê também é prejudicial para o leitor humano. Ao ser forçado a escrever texto repetitivo e sem sentido, estamos obscurecendo as partes relevantes do código de outras pessoas. Se algo é útil, então, por definição, não é padrão.
Andres F.
1
@Giorgio: Pelo contrário, é muito mais do que apenas minha opinião; é a opinião da grande maioria das pessoas que já tentaram estudá-lo. E quando "difícil de ler" é inerentemente uma questão de opinião em primeiro lugar, o fato de que essa opinião é tão amplamente compartilhada praticamente o torna um fato.
Mason Wheeler
1
@Mason Wheeler: O modo como as pessoas percebem as linguagens de programação geralmente é influenciado por suas experiências passadas. As pessoas que aprenderam a programar em Scheme acham C ou Pascal desajeitado e difícil de ler. Por outro lado, a grande maioria das pessoas aprendeu a programar em um idioma convencional.
Giorgio
2
Eu sou da opinião de que, quando mais contexto é oculto do programador, removendo o clichê, isso significa apenas que o Humano precisa manter um mapa mental maior de todas as coisas que acontecem sem serem vistas nos bastidores. E isso é um grande prejuízo quando se trata de depuração do que economizando um pouco de espaço visual ao criar.
Patrick Hughes
7

Um argumento a favor do código clichê é que, se você o alterar em um só lugar, ele afeta apenas um fluxo do código. Isso deve ser equilibrado com o fato de que, na maioria das vezes, você realmente deseja que uma mudança afete cada parte do código que a usa. Mas vi exemplos raros que apóiam o argumento.

Digamos que você tenha um código que diz

public ForTheBar(Foo foo)
{
    Bar bar = foo.bar();
    return bar.BeFooed();
}

Isso é usado em cerca de 2 lugares no seu código.

Um dia, alguém aparece e diz: "ok, apenas neste caminho, queremos que você abra o bar antes de ir embora".

E você pensa "bem, isso é simples".

public ForTheBar(Foo foo, bool shouldIGrommit)
{
    Bar bar = foo.bar();

    if (shouldIGrommit)
    {
        bar.BeGrommitted();
    }

    return bar.BeFooed();
}

Em seguida, seu usuário adiciona algumas novas funcionalidades e você acha que elas se encaixam bem com o FooTheBar. E você obedientemente pergunta a eles se você deve Grommit aquela barra antes de você tocar e eles dizem "não, não desta vez".

Então você acabou de chamar o método acima.

Mas então o usuário diz "ok, espere, no terceiro caso, queremos que você faça o Doodle the Bar antes de ligar para o BeFooed".

Não tem problema, você pensa, eu posso fazer isso.

public ForTheBar(Foo foo, bool shouldIGrommit, bool shouldIDoodle)
{
    Bar bar = foo.bar();

    if (shouldIGrommit)
    {
        bar.BeGrommitted();
    }

    if (shouldIDoodle)
    {
        bar.BeDoodled();
    }

    return bar.BeFooed();
}

De repente, seu código está se tornando menos padronizado. Talvez você devesse ter aceitado as duas linhas de código repetidas. A essa altura, você teria três códigos, cada um com duas a três linhas e não parecendo mais repetir.

Tudo isso dito, eu diria que "esse não é um caso comum e, quando isso acontece, você pode refatorar".

Outro argumento que ouvi recentemente é que o código clichê às vezes pode ajudá-lo a navegar pelo código. O exemplo que discutimos foi onde removemos toneladas de código de mapeamento padrão e o substituímos pelo AutoMapper. Agora, argumentou-se, porque tudo é baseado em convenções, você não pode dizer "Onde esta propriedade está definida" para o IDE e esperar que ele saiba.

Já vi pessoas discutindo coisas semelhantes sobre contêineres IoC.

Para não dizer que concordo com eles, mas é um argumento justo.

pdr
fonte
2
Eu preferi a segunda parte da sua resposta. ; p +1
Steven Jeuris
basta perceber o meu exemplo é bastante semelhante ao seu ... acho que mesmo se não é o senso comum parece acontecer um pouco :)
kritzikratzi
6

A evolução da eficiência

Você começa com isso:

<p>
    <label for="field">My field</label>
    <input type="text" id="field">
</p>

então você se livra de todo esse clichê irritante e o coloca em uma função:

  1. createFieldHtml( id, label )

    isso é bom, estou me salvando tantas linhas!

  2. createFieldHtml( id, label, defaultValue )

    sim, também preciso de um valor padrão, que foi fácil de adicionar.

  3. createFieldHtml( id, label, defaultValue, type )

    legal, também posso usá-lo para caixas de seleção

  4. createFieldHtml( id, label, defaultValue, type, labelFirst )

    O designer do UX disse que a etiqueta deve estar após a caixa de seleção.

  5. createFieldHtml( id, label, defaultValue, type, labelFirst, isDate )

    agora renderiza um selecionador de data quando necessário. Hum ... os parâmetros estão ficando um pouco fora de controle

  6. createFieldHtml( id, label, defaultValue, type, labelFirst, isDate, containerCssClasses )

    houve um caso em que eu preciso adicionar classes CSS

  7. createFieldHtml( id, label, defaultValue, type, labelFirst, isDate, containerCssClasses, fieldCssClasses, disabled, clearAfter, helpText, uploadPath )

    aaaaaaaaaaaaaaaaaaaaa

Em defesa do clichê

Eu tenho dificuldade em colocar isso em palavras, porque é algo que eu tenho notado recentemente, então vou fazer uma lista:

  1. Parece-me que há um certo medo de ter linhas duplicadas que se estendem um pouco. Se forem apenas algumas linhas, pode não haver nenhum problema. algumas coisas são inerentemente "quase repetitivas" (como o exemplo acima). Vejo poucas chances de otimizar lá a longo prazo.
  2. As pessoas gostam de encapsular funcionalidade em algum lugar; se você olhar objetivamente e parecer que está apenas "escondendo a bagunça" - desconfie! pode ser a hora de um bom e velho clichê
  3. Quando você tem uma função que se torna cada vez mais poderosa; que usa muitos caminhos de execução diferentes, dependendo da entrada e, em última análise, faz muito pouco - pode ser o tempo padrão!
  4. Quando você adiciona uma camada de abstração em cima de outra camada de abstração, mas apenas para tornar seu código mais curto (a camada subjacente não deve ser alterada) - tempo padrão!
  5. Quando você tem uma função que usa tantos parâmetros que você realmente precisa nomear parâmetros - talvez seja o tempo padrão.

Uma coisa que sempre me pergunto recentemente é:
Posso copiar e colar em outro projeto sem alterar nada? se sim, não há problema em encapsular ou colocar em uma biblioteca, se não: é hora do clichê.

Isso se opõe muito à percepção geral de que clichê é copiar e colar código. Para mim, clichê é sobre copiar e colar, mas sempre ter que ajustá-lo um pouquinho.


Atualização : acabei de encontrar um artigo que dá o meu exemplo acima com um nome real: "anti-padrão muito seco".

A função obtém mais parâmetros e possui uma lógica interna cada vez mais complexa para controlar seu comportamento em diferentes casos. Funções muito secas são fáceis de detectar. Eles têm muita lógica intrigante de se-então que tenta abordar uma ampla diversidade de uso. [...] Além disso, repetir código nem sempre é uma coisa ruim se o código é pequeno e executa uma função discreta.

É uma leitura curta e interessante, você pode encontrar o artigo aqui: Anti-Pattern Too Dry

kritzikratzi
fonte
1
"Quando você adiciona uma camada de abstração em cima de outra camada de abstração, mas apenas para tornar seu código mais curto" Verdadeiro, você deve adicionar camadas de abstração apenas quando houver possibilidade de reutilização.
Steven Jeuris
4
+1. Não se repita, mas não se esforce para evitar quase se repetir.
Julia Hayward
4

Eu desprezo o código padrão, mas ser capaz de remover o código padrão nem sempre significa que esse é o melhor caminho a percorrer.

A estrutura do WPF possui propriedades de dependência , o que envolve uma quantidade insana de código clichê. Durante meu tempo livre , investiguei uma solução que reduz bastante a quantidade de código que precisa ser escrita. Mais de um ano depois , ainda estou aprimorando esta solução e ainda preciso estender sua funcionalidade ou corrigir bugs.

Qual é o problema? Isso é ótimo para aprender coisas novas e explorar soluções alternativas, mas provavelmente não é a melhor decisão comercial .

A estrutura do WPF está bem documentada. Ele documenta corretamente como escrever seu código padrão. Tentar remover esse código padrão é um bom exercício, e algo que definitivamente vale a pena explorar, mas alcançar o mesmo nível de 'polimento' que o msdn oferece leva muito tempo, o que nem sempre temos.

Steven Jeuris
fonte
No entanto, ainda estou muito feliz com o resultado que tenho no momento e com prazer o uso em meus projetos de tempo livre. :)
Steven Jeuris
3
toda vez que toco o WPF e essas propriedades de dependência, sempre acabo desejando que o C # tenha algo tão simples quanto as macros do C ++. As macros com certeza são maltratadas em mãos erradas, mas podem eliminar muitas repetições aqui. Eu vou ter que dar uma olhada em seu quadro AOP próxima vez que eu começar desejando para as macros :)
DXM
@ DXM Se o fizer, e ele trava miseravelmente, não se esqueça de me culpar e postar os erros. ; p
Steven Jeuris
O snippet de código funcionou muito bem para mim nas propriedades de dependência.
Codism
@ Codism: Bem, eles são uma solução, mas eu também os desprezo . :)
Steven Jeuris
1

O problema com o boilerplate é que ele viola o DRY. Em essência, quando você escreve clichê, está repetindo o mesmo código (ou código muito semelhante) em várias classes. Quando esse código precisa ser alterado, não é absolutamente certo que o desenvolvedor se lembre de todos os lugares em que o código foi repetido. Isso leva a erros nos quais APIs antigas ou métodos antigos são usados.

Se você refatorar o clichê em uma biblioteca comum ou classe pai, precisará alterar o código em um único local quando a API for alterada. Mais importante, quando mudanças inesperadas acontecem, o código é quebrado em um só lugar e permite que você saiba exatamente o que precisa corrigir para que tudo funcione novamente. Isso é preferível a um cenário em que uma alteração causa falhas em dezenas ou mesmo centenas de classes.

quanticle
fonte
2
Como isso é um argumento a favor do clichê ?
22412 Chris Wesseling
0

Eu vou tomar um tato diferente. A consistência no desenvolvimento é um dos recursos mais importantes do design de software; é uma ferramenta crítica para tornar os aplicativos extensíveis e de manutenção, mas pode ser difícil de obter ao gerenciar uma equipe em vários sites, idiomas e fusos horários.

Se alcançada, a consistência torna o código muito mais acessível "depois de ver um, você já viu todos", muito mais barato de manter e refatorar, mas acima de tudo, muito mais fácil de estender. Quando você escreve uma biblioteca que requer alguns clichês, juntamente com o poder da sua biblioteca, você também fornece ao desenvolvedor:

  • Um ponto de partida para entender o preâmbulo (clichê) em sua funcionalidade, a maioria das classes principais e pontos de acesso geralmente serão apresentados como parte do clichê. Isso fornece aos desenvolvedores um ponto de partida para a documentação
  • As expectativas de sua colocação nos desenvolvedores se tornarão aparentes, por exemplo, se você configurar um objeto de rastreamento como parte do preâmbulo, os desenvolvedores saberão onde registrar exceções e informações
  • Compreensão implícita, à medida que você força o desenvolvedor a passar por seu processo de instanciação de classes, ele pode inferir as técnicas necessárias para acessar o restante da sua biblioteca e ter a oportunidade de apresentá-las a todas as convenções que você usou em toda a sua biblioteca
  • Validação fácil quando o código do seu clichê é necessário, ele geralmente pode validar-se facilmente com exceções e cláusulas de guarda, impedindo que os consumidores fiquem presos muito mais adiante quando você já está comprometido com um processo defeituoso
  • A configuração de uma biblioteca que requer código padrão é fácil, pois já existe um ponto de implementação óbvio para personalizar a funcionalidade para um único caminho de execução. Isso é particularmente útil se o código padrão necessário for aprimorado com o padrão Factory ou Command

Quando os consumidores da sua biblioteca controlam a instanciação, podem facilmente criar métodos privados / de extensão, classes pai ou até modelos para implementar o código padrão.

Dead.Rabit
fonte
-3

O único problema real com o código clichê é que, quando você encontra um bug, precisa corrigir todos os lugares em que o usou e não o único lugar em que você reutilizou .

Edward Strange
fonte