Devo seguir um estilo ruim de codificação apenas para seguir as convenções estabelecidas no meu local de trabalho?


102

Trabalho no meu emprego há cerca de um ano. Eu trabalho principalmente em nossa interface GUI, que usa métodos de um back-end em C, mas geralmente não preciso lidar com eles, exceto pelos valores de retorno. Nossa GUI está estruturada de maneira bastante razoável, dadas as nossas limitações.

Fui encarregado de adicionar uma função à parte da linha de comando do programa. A maioria dessas funções tem 300 linhas e é difícil de usar. Estou tentando reunir partes deles para obter informações específicas sobre alarmes e estou tendo problemas para me manter organizado. Eu sei que estou tornando meus testes mais complicados, realizando-os em uma única função longa.

Devo manter tudo em uma função enorme, de acordo com o estilo das funções existentes, ou devo encapsular os alarmes em suas próprias funções?

Não tenho certeza se é apropriado ir contra as convenções de codificação atuais ou se devo apenas morder a bala e tornar o código um pouco mais confuso para eu escrever.

Em resumo, estou comparando

showAlarms(){
    // tons of code
}

contra

showAlarms(){
   alarm1();
   alarm2();
   return;
}

alarm1(){
    ...
    printf(...);
    return;
}

EDIT: Obrigado pelo conselho a todos, eu decidi que vou projetar meu código fatorado e, em seguida, pergunto o que eles querem, e se eles querem tudo em um, eu posso simplesmente cortar meu código fatorado e transformá-lo novamente em 1 grande função. Isso deve permitir que eu escreva e teste com mais facilidade, mesmo que eles queiram todo o código em uma única definição.

ATUALIZAÇÃO: Eles ficaram felizes com o código fatorado e mais de uma pessoa me agradeceu por estabelecer esse precedente.


117
É altamente duvidoso que a empresa para a qual você trabalhe assuma a posição de que suas funções devem ter 300 linhas, porque "é assim que sempre fazemos". Isso não é "convenções de estilo de codificação"; é apenas um estilo ruim.
Robert Harvey

64
Esse é o tipo de coisa que você deve discutir com outros membros da sua equipe, para descobrir quais práticas você vê são convenções que eles consideram importantes para todos seguirem e quais são as coisas que alguém fez uma vez e que você não segue. precisa emular. Sem dúvida, haverá uma quantidade de ambos.
Servy

17
@beginnerBinx Isso se resume a como você o expressa. Não a expresse como: "X está fazendo algo realmente estúpido, eu também tenho que fazer essa coisa estúpida". mas como algo do tipo: "Percebo que X está fazendo uma única coisa, existe uma razão específica para fazer dessa maneira; seria um problema se eu não fizesse a mesma coisa ao escrever Y?" Torna-se então a decisão deles de se basear no código antigo ou explicar por que eles tiveram que fazer dessa maneira (seja de má vontade ou entusiasmo).
Servy

11
O estilo bom ou ruim é frequentemente discutido e pouco comum. O ensino universitário é que as funções devem ser curtas, mas se isso obscurecer o significado, não faça. O teste deve ser mais claro do que seguir impensadamente um conjunto de regras.
quickly_now

9
Pessoas aleatórias na internet não se importam de ler seus companheiros de equipe, então todas as respostas que você recebe aqui são apenas preferências pessoais das pessoas. Você deve conversar com sua equipe. A função longa é um princípio de design deliberado? Eles gostariam que você continuasse com o estilo de função longa ou gostariam que você escrevesse o que você considera mais limpo?
JacquesB

Respostas:


102

Isso é realmente entre você e seus companheiros de equipe. Ninguém mais pode lhe dizer a resposta certa. No entanto, se eu ouso ler nas entrelinhas, o fato de você chamar esse estilo de "ruim" fornece algumas informações que sugerem que é melhor ir devagar. Muito poucos estilos de codificação são realmente "ruins". Existem alguns que eu não usaria, mas eles sempre têm uma rima ou razão para eles. Isso sugere, para mim, que há mais na história do que você viu até agora. Perguntar seria uma decisão muito sábia. Alguém pode saber algo que você não sabe.

Eu me deparei com isso, pessoalmente, na minha primeira incursão na codificação de missão crítica em tempo real. Eu vi código assim:

lockMutex(&mutex);
int rval;
if (...)
{
    ...
    rval = foo();
}
else
{
    ...
    rval = bar();
}
unlockMutex(&mutex);
return rval;

Sendo o desenvolvedor do OO C ++, eu os chamei imediatamente sobre os riscos de bugs que eles tinham, bloqueando e desbloqueando manualmente mutexes, em vez de usar RAII . Eu insisti que isso era melhor:

MutexLocker lock(mutex);
if (...)
{
    ...
    return foo();
}
else
{
    ...
    return bar();
}

Muito mais simples e mais seguro, certo ?! Por que exigir que os desenvolvedores se lembrem de desbloquear seus mutexes em todo o caminho do fluxo de controle quando o compilador pode fazer isso por você!

Bem, o que descobri mais tarde foi que havia uma razão processual para isso. Tivemos que confirmar que, sim, o software funcionava corretamente e havia uma lista finita de ferramentas que nos era permitido usar. Minha abordagem pode ter sido melhor em um ambiente diferente, mas no ambiente em que eu estava trabalhando, minha abordagem multiplicaria facilmente a quantidade de trabalho envolvida na verificação do algoritmo dez vezes, porque acabei de incluir um conceito de RAII em C ++ em uma seção de código isso estava sendo mantido em padrões realmente mais propensos ao pensamento no estilo C.

Então, o que parecia ruim, absolutamente perigoso, para mim foi realmente bem pensado e minha solução "boa" foi a perigosa que causaria problemas no caminho.

Então pergunte por aí. Certamente, há um desenvolvedor sênior que pode trabalhar com você para entender por que eles fazem dessa maneira. Ou, há um desenvolvedor sênior que pode ajudá-lo a entender os custos e benefícios de um refator nesta parte do código. De qualquer maneira, pergunte!


60
Indiscutivelmente, a parte mais perigosa do exemplo mutex é a aparente falta de comentários sobre o código, explicando por que não foi possível usar o RAII. É verdade que, se esse bloqueio / desbloqueio explícito estiver em toda a base de código, pode ser difícil adicionar um comentário para cada instância. Nesse caso, talvez seja necessário escrever um documento primário com o qual os novos desenvolvedores precisam estar familiarizados.
Kelvin13 /

10
Certamente, conversar com um idoso é sempre bom, e a refatoração deve ser feita com cuidado (e com testes). E, é claro, a simultaneidade / mutex é um animal especial por si só. Mas, ao ver funções com> 300 linhas, eu não investia muito tempo procurando uma "razão técnica oculta" pela qual essas funções são grandes demais. A razão pela qual as funções se tornam muito longas é sempre a mesma e não é técnica.
Doc Brown

8
@DocBrown Só porque eles não são técnicos não significa que não são razões. É importante que os desenvolvedores se lembrem de que eles fazem parte de uma máquina maior. (Eu não posso contar o número de vezes que tive que reaprender a lição)
Cort Ammon

4
@DocBrown De qualquer forma, é com os desenvolvedores seniores que devemos conversar. Eu escolhi o exemplo que fiz porque é fácil encontrar incontáveis ​​argumentos sobre por que o código estúpido é estúpido. Encontrar os argumentos sobre por que o código que parece estúpido na verdade não é estúpido é mais difícil.
precisa

3
@DocBrown De seus comentários e respostas, acho que posso dizer que a diferença de nossas opiniões é que você está partindo da suposição de que o código já é "ruim", com base nas evidências fornecidas, enquanto eu preferiria percorra caminhos que exploram se o código é ou não "ruim" primeiro.
Cort Ammon

84

Honestamente, você acredita que ter funções difíceis de usar, com 300 linhas, é apenas uma questão de estilo? Então, seguir o exemplo ruim pode manter o programa geral em um estado melhor por causa da consistência? Eu acho que você não acredita, caso contrário, você não teria feito essa pergunta aqui.

Meu palpite é que essas funções são tão longas, porque em nossos negócios existem muitos programadores medíocres que apenas empilham recursos sobre recursos, sem se preocupar com legibilidade, qualidade do código, nomeação adequada, testes de unidade, refatoração, e eles nunca aprenderam a criar abstrações adequadas . Você precisa decidir por si mesmo se deseja seguir esse rebanho ou se deseja ser um programador melhor.

Adendo, devido aos comentários: "300 linhas" e "difícil de usar" são fortes indicações do IMHO para códigos incorretos. Para minha experiência, é muito improvável que exista alguma "razão técnica oculta" pela qual esse código não possa ser implementado de maneira mais legível, comparável ao exemplo da resposta de Cort Ammon. No entanto, eu concordo com Cort que você deve discutir isso com os responsáveis ​​da equipe - não para descobrir razões obscuras pelas quais o código ou esse "tipo de estilo" não pode ser alterado, mas para descobrir como o código pode ser refatorado com segurança sem quebrar as coisas .


127
Até os programadores competentes cometem esses crimes quando têm prazos apertados.
gardenhead

13
@ Gardenhead, eu entendo que não refatorar uma função de 300 linhas para economizar tempo, mas não há maneira possível de escrever uma função de 300 linhas economizar tempo.
Dangph

39
@ Gardenhead: quando vou a um cirurgião porque preciso de ajuda urgente, ainda espero que ele reserve um tempo para lavar as mãos antes de começar a me apresentar. Isso é algo que muitas pessoas precisam aprender em nossos negócios para obter competência real : sempre deixe o código em um estado melhor para trás do que era antes, e isso também aumentará a capacidade de cumprir prazos. As funções de 300 linhas geralmente crescem dia a dia, por pessoas que não se importam e sempre usarão "o prazo" como desculpa.
Doc Brown

17
@Dangph economiza tempo quando você adiciona apenas 5 linhas à função em vez de refatorá-la. Isso geralmente cresce quando a função inicial é longa (mais de 30 linhas) e o próximo programador pensa "este não é meu código, não vou refatorar para não quebrá-lo, basta adicionar algumas linhas aqui e ali".
13132 Džuris

7
@Juris, como eu o entendo, a questão é criar uma nova função, não refatorar as existentes. Se você estiver escrevendo uma nova função, não economizará tempo transformando-a em uma única função de monstro.
Dangph

42

Não.

No livro Programador Pragmático, o autor fala sobre a Teoria da Janela Quebrada .

Esta teoria afirma:

Considere um prédio com algumas janelas quebradas. Se as janelas não forem reparadas, a tendência é que os vândalos quebrem mais algumas janelas. Eventualmente, eles podem até invadir o prédio e, se estiver desocupado, talvez se tornem invasores ou fogos leves no interior.

Ou considere um pavimento. Alguma ninhada se acumula. Logo, mais lixo se acumula. Eventualmente, as pessoas até começam a deixar sacos de lixo nos restaurantes de take-away ou até entram em carros.

No livro, o autor escreve um paralelo entre essa teoria e esse código. Depois de encontrar um código como esse, você para e se pergunta a mesma pergunta.

E a resposta é não.

Quando você sair dessa janela quebrada - no nosso caso, código incorreto - isso criará o efeito de que todos deixarão janelas quebradas para trás.

E um dia o código entrará em colapso.

Dê uma cópia do Clean Code e Clean Coder para todos.

E enquanto você está no assunto, uma cópia do TDD também é boa.


6
E se a base de código for uma estufa com nada além de janelas quebradas?
Alan Shutko

8
@AlanShutko Então, verifique se o seu currículo está atualizado? Encontre um empregador diferente agora .
David Montgomery

12
Código raramente "recolhe". Está ficando cada vez mais difícil adicionar novos recursos, leva mais e mais tempo, e as estimativas para a limpeza do código aumentam - o que significa que fica ainda mais difícil conseguir um orçamento de tempo para a limpeza necessária.
Doc Brown

8
Uau, que analogia arbitrária a teoria da "janela quebrada" parece ser.
Samthere 13/12/16

4
TDD não tem nada a ver com isso. Se você está indo para o design de driver de Negócios / Domínio / Teste / Nada que não altera nada, siga os princípios básicos do código limpo. Desculpe, mas é realmente cansativo para ver 'TDD' citado em todos os lugares onde nem mesmo no assunto
Walfrat

25

Sim, vá em frente. Estrutura! = Estilo

Você está falando sobre estrutura, não estilo. As diretrizes de estilo (geralmente) não prescrevem a estrutura, uma vez que a estrutura geralmente é escolhida por sua adequação a um problema específico, não por uma organização.

Seja cuidadoso

Apenas tenha certeza de que não está causando consequências negativas em outras áreas que podem não ter ocorrido a você. Por exemplo,

  • Verifique se você não está complicando as diferenças ou as mesclagens de código, porque você eliminou qualquer semelhança com o código existente.
  • Certifique-se de que os fluxos de exceção borbulhem corretamente e os traços da pilha não sejam poluídos com uma pilha enorme de bobagens ilegíveis.
  • Verifique se não está expondo acidentalmente pontos de entrada públicos que causariam problemas se fossem chamados diretamente (não os coloque no mapa e / ou não exporte).
  • Não bagunce o espaço de nomes global, por exemplo, se todas as suas funções menores exigirem algum tipo de contexto global que foi declarado anteriormente no escopo da função local.
  • Verifique todos os logs e pergunte a si mesmo se você estava na equipe de suporte se os logs gerados pelo seu código seriam confusos quando vistos entrelaçados com os logs de qualquer código que você não toque.
  • Certifique-se de que aderem ao estilo existente, por exemplo, mesmo se eles estão usando old-school notação húngara e faz seus olhos sangrar, ficar consistente com a base de código geral. A única coisa mais dolorosa do que ler notação húngara é ler código que usa uma dúzia de tipos diferentes de notação, dependendo de quem escreveu o quê.

Seja gentil

Lembre-se de que você faz parte de uma equipe e, embora um bom código seja importante, também é muito importante que os membros da sua equipe consigam manter as coisas que você escreveu quando sai de férias. Tente manter um fluxo que faça sentido para as pessoas que estão acostumadas com o estilo antigo. Só porque você é o cara mais inteligente da sala não significa que você deve falar acima da cabeça de todos!


"Tente manter um fluxo que faça sentido para as pessoas que estão acostumadas com o estilo antigo". - então, seu conselho é programar da mesma maneira que qualquer palhaço incompetente já fez antes? A adição da função de 300 linhas não facilitará.
13136

11
Eu não disse para manter um fluxo semelhante. Eu disse para manter um fluxo que eles entenderão.
John Wu

2
Bom conselho. Quando refatorei um único comando em 5 funções nesta resposta, alterei sutilmente a semântica pré-computando valores dentro de uma expressão lógica que originalmente era computada apenas condicionalmente. Os revisores o pegaram ;-). O conselho sério é revisar e testar minuciosamente. Cada alteração pode introduzir erros, e esse pode ser o principal motivo pelo qual ninguém os cometeu.
Peter A. Schneider

6

Não vejo isso como uma convenção de código. Eu vejo isso como alguém que não entende como escrever código de manutenção fácil de entender. Eu dividiria seu código em diferentes funções, como você sugere e instrui sua equipe sobre os benefícios de fazer isso enquanto tenta entender por que eles consideram aceitáveis ​​as funções de 300 linhas. Eu ficaria muito interessado em ouvir o raciocínio deles.


1
" Não há razão, é apenas nossa política. "

5

A resposta está na revisão de código.

A verdadeira questão é: se você digitar um código bem fatorado, será o único disposto a trabalhar com ele?

Eu, como a maioria das pessoas aqui, acredito que 300 funções de linha são uma abominação. No entanto, levar o Windex para um aterro sanitário não será muito bom. O problema não é o código, são os codificadores.

Apenas estar certo não é suficiente. Você precisa vender pessoas nesse estilo. Pelo menos ao lê-lo. Se não, você acaba como esse pobre rapaz: demitido porque suas habilidades estão muito acima dos seus colegas de trabalho

Comece pequeno. Pergunte ao redor e descubra se mais alguém favorece funções menores. Melhor ainda bisbilhotar a base de código e ver se você consegue descobrir quem escreve os menores (você pode achar que o código mais feio é o mais antigo e os codificadores atuais estão escrevendo um código melhor). Converse com eles sobre isso e veja se você tem um aliado. Pergunte se eles conhecem alguém que se sente da mesma maneira. Pergunte se eles conhecem alguém que odeia pequenas funções.

Reúna esse pequeno grupo e fale sobre como fazer mudanças. Mostre a eles o tipo de código que você deseja escrever. Certifique-se de que eles possam lê-lo. Leve as objeções a sério. Faça as alterações. Obtenha seu código aprovado. Agora você tem o poder de uma reunião atrás de você. Mais algumas delas e você pode produzir um documento de uma página que aceite explicitamente o novo estilo que você introduziu.

Reuniões são coisas surpreendentemente poderosas. Eles podem produzir influência. Clout é o que você usará para combater aqueles que se opõem a esse movimento. E é isso que é neste momento. Um movimento. Você está lutando pelo direito de melhorar o status quo. As pessoas temem mudanças. Você precisará de conversa fiada, persuasão e prod. Mas com um pouco de sorte, você se tornará certo em ser aceito.


5
Se são necessárias muitas reuniões socializadoras e múltiplas para convencer os desenvolvedores de que um método de 300 linhas é muito longo, não acho que a conversa vá ajudar. O problema com a abordagem acima é que, se você pedir permissão para escrever um bom código, estará na defensiva. Mas se você apenas escrever um bom código e reservar um tempo para refatorar o código existente, qualquer um que se oponha estará na defensiva para explicar por que um método de 300 linhas é bom e para justificar gastar o tempo devolvendo-o.
Brandon

3
Posso dizer-lhe que, se fosse convidado para uma série de reuniões para discutir linhas de código por limites de função, encontraria uma maneira de escapar dessas reuniões. Não existe um número correto e você nunca fará as pessoas concordarem. Às vezes, as pessoas precisam mostrar uma maneira melhor.
Brandon

Às vezes, dividir uma enorme função (e nomear as coisas melhor e adicionando comentários e documentação como eu descobrir isso é o primeiro passo necessário antes savely mqking uma mudança.
JDługosz

@Brandon Você provavelmente não quer que isso pareça assim, mas o que estou ouvindo é que você está certo e todo mundo pode simplesmente lidar com isso. Desde que seu código funcione, não importa se o resto da equipe não o entende. Certamente não vale a pena se preocupar em ensinar-lhes qualquer coisa. Você fica perfeitamente feliz em vê-los continuar a criar 300 funções de linha enquanto escreve o seu próprio caminho.
candied_orange

1
@CandiedOrange Eu certamente não quis dizer ir contra a equipe. O que eu quis dizer foi que alguns tópicos são melhor aprendidos ao vê-los em ação, mas tentar obter uma equipe para tomar uma decisão democrática sobre estilo não será produtivo. Vi a consistência usada como desculpa para escrever código ilegível. Resultado? Código mais ilegível. Eu poderia organizar uma série de reuniões para falar sobre isso, ou poderia apenas consertar e depois mostrar às pessoas os resultados.
Brandon

3

Às vezes você tem que ir com o fluxo.

Como você disse, você foi encarregado de implementar uma função em uma base de código existente.

Independentemente da bagunça, e eu entendo que é tentador limpá-la. mas no mundo dos negócios, você nem sempre tem a chance de refatorar o código.

Eu diria apenas faça o que lhe pediram e siga em frente.

Se você acha que vale a pena refatorar ou reescrever, é necessário trazê-lo para discussão com a equipe.


2
Se você pedir permissão para cada pequena refatoração, terá sempre um código não sustentável, o que é perigoso para uma empresa. Os gerentes olham apenas para o custo de uma mudança, mas raramente olham para o custo de não mudar.
Brandon

5
Foi solicitado ao OP que escrevesse uma função que não modificasse centenas de linhas de código
meda

2
@meda exatamente! Estou na mesma situação. Estou desenvolvendo novos módulos para a intranet da empresa e encontrando o que pode ser descrito como "anos de negligência além do reparo", com o software e as bibliotecas do servidor não sendo atualizados desde 2006. Não devo limpar essa bagunça , mas levo mais tempo para codificar devido às limitações. (Imagine o MySQl 5.2, o MySQL 5.0). Não consigo atualizar nada, porque provavelmente o código existente não será executado em versões mais recentes devido ao código obsoleto.
precisa saber é

3
"Se não está quebrado, não conserte." Eu tenho um carro de 20 anos que vaza um pouco de óleo. Vale a pena gastar dinheiro? Não. Confiável? Sim.

3

Antes de afirmar que as práticas são ruins, primeiro daria um passo no sentido de entender a razão dos grandes métodos e outras práticas que podem parecer ruins.

Em seguida, você precisa garantir que a cobertura do teste seja bastante alta ou muito alta (o máximo que puder, sem grandes refatorações). Caso contrário, eu trabalharia para tornar a cobertura realmente alta, mesmo que você não tenha escrito o código. Isso ajuda a criar rapport e sua nova equipe o levará mais a sério.

Depois de cobrir essas bases, ninguém em sã consciência o desafiará. Como um item de bônus, faça alguns micro-benchmarking e isso realmente aumentará o seu caso.

Freqüentemente, a maneira como você expressa isso ajuda bastante a mudar a cultura do código. Lidere pelo exemplo. Ou melhor ainda, espere por um pedaço de código que você possa escrever - refatorar e testar a unidade com ele e viola - você será ouvido.


Eu não estou refatorando o código atual, estou apenas escrevendo uma nova função, não tenho certeza se devo seguir a 'convenção' e codificá-la em uma monstruosidade de mais de 300 linhas ou dividi-la em pedaços lógicos, como faria normalmente, mas não foi feito nesta parte da base de código.
Justin

1
eles têm regras para garantir que você escreva novos métodos em mais de 300 linhas? se não, eu escreveria da maneira certa. mas eu faria o possível para garantir que eu os testasse, incluindo os ramos. Eu já passei por experiências semelhantes e, geralmente, você as conquista. O truque é fazer isso ao longo do tempo e criar rapport.
Skipy

3

Esse tipo de pergunta é basicamente " leia atentamente meus companheiros de equipe ". Pessoas aleatórias na internet não podem fazer isso, então todas as respostas que você receberá são apenas opiniões pessoais das pessoas sobre o estilo de codificação. O consenso é que métodos mais curtos são preferíveis, mas parece que você já pensa assim, então não há necessidade de reafirmar isso.

Portanto, a base de código atual parece usar um estilo de codificação diferente daquele que você preferir. O que você deveria fazer? Primeiro você precisa descobrir:

  1. Esta é uma decisão deliberada de design, suportada pela sua equipe atual?
  2. Eles querem que você siga esse estilo?

Há apenas uma maneira de descobrir. Peça .

Pode haver vários motivos para ter funções longas. Pode ser porque a equipe acredita que funções longas são melhores que várias funções curtas. Também pode ser porque é um código legado, e a equipe prefere que o novo código siga um design mais limpo. Portanto, qualquer uma das opções pode causar problemas como desenvolvedor, se você não conversar com a equipe e entender o raciocínio deles.


1
Concordo plenamente e acrescento: "Você foi demitido ou teve problemas por não seguir o que os outros fizeram?" Então a resposta é sim! Após todas as coisas ruins que a empresa exige que você faça e lide com isso.
Rob

1

Existem diferentes níveis de "estilo".

Em um nível, geralmente parte das convenções de codificação, isso significa onde colocar espaços em branco, linhas em branco, colchetes e como nomear coisas (maiúsculas e minúsculas, sublinhados, etc.).

Em outro nível, está o modelo de programação, às vezes coisas como evitar estática ou usar interfaces em classes abstratas, como expor dependências, talvez até mesmo evitar alguns recursos da linguagem esotérica.

Depois, há as bibliotecas e estruturas em uso pelo projeto.

Às vezes, haverá um limite máximo no tamanho da função. Mas raramente existe um limite mínimo! Portanto, você deve descobrir quais dessas coisas os poderes que consideram importantes e tentar respeitar isso.

Você precisa descobrir se a equipe é adversa à refatoração do código existente, o que deve ser feito independentemente da adição de novo código, quando possível.

No entanto, mesmo que eles não desejem refatorar o código existente, você poderá introduzir algumas camadas nas abstrações para o novo código que adicionar, ou seja, com o tempo, poderá desenvolver uma base de código melhor e talvez migrar o código antigo como manutenção dele exige.

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.