Há um tempo atrás, fiz uma pergunta no SO sobre algo escrito em C ++, mas, em vez de obter uma resposta para o problema em questão, os comentários enlouqueceram no meu estilo de codificação, mesmo quando indiquei que era um código WIP e que pretendia limpá-lo mais tarde, quando o gabinete básico estivesse funcionando. (Eu recebi tantos votos negativos que decidi fazer a pergunta, pois meu representante no SO já é quase abismal)
Isso me fez pensar por que as pessoas adotam uma atitude tão rígida de "você é um noob, vá se foder". Eu estava sendo acusado de escrever C ++ como se fosse Java. Algo que não consigo entender e que ainda me deixa perplexo.
Eu tenho programado em algumas linguagens OOP há vários anos, embora em intervalos. Eu escolhi o idioma a ser usado em termos de bibliotecas disponíveis e ambientes ideais de execução para o trabalho em questão. Adoto padrões de design no código OOP e estou bastante confiante de que meu uso de padrões é sólido e que, em termos de OO, posso me manter. Entendo a caixa de ferramentas OOP, mas optei por usá-las somente quando acho que é realmente necessário, e não apenas usar um truque para mostrar meu raciocínio de codificação. (Que eu sei que não são de primeira qualidade, mas acho que também não estão no nível n00b).
Eu projeto meu código antes de escrever uma única linha. Para definir testes, listo os objetivos de uma determinada classe e os critérios de teste aos quais ela deve aderir. Como é mais fácil criar diagramas de sequência e depois escrever código, escolhi escrever meus testes depois que a interface se tornou óbvia.
Devo admitir que, no trecho de código que postei na pergunta, eu ainda estava usando ponteiros, em vez de usar ponteiros inteligentes. Eu uso RAII sempre que posso. Sei que RAII adequado significa proteção contra ponteiros nulos, mas trabalho de forma incremental. Era um trabalho em andamento e pretendia limpá-lo mais tarde. Essa maneira de trabalhar foi fortemente condenada.
Na minha opinião, eu deveria ter um exemplo de trabalho primeiro para poder ver se o caso base é uma maneira viável de pensar. Também acho que limpar o código é algo típico da fase de refatoração do ágil, após a comprovação do caso base. Devo admitir que, embora esteja adquirindo lentamente o padrão Cxx, prefiro usar o que entendo, em vez de correr o risco de usar conceitos que ainda não dominei no código de produção. Eu tento coisas novas de vez em quando, mas geralmente em projetos que tenho ao lado, apenas para esse fim.
[editar] Gostaria de esclarecer que a sugestão do mosquito [1] não apareceu na pesquisa que fiz antes de começar a fazer minha pergunta. No entanto, embora sua sugestão cubra um aspecto da pergunta, a pergunta a que ele se vinculou não responde ao cerne da minha pergunta, apenas parte dela. Minha pergunta é mais sobre a resposta que cheguei ao meu estilo de codificação e os aspectos profissionais de lidar com diferentes estilos de codificação e níveis (aparentes) de habilidade. Com a minha pergunta anterior sobre SO e sua resposta como um caso em questão. [/editar]
A questão então é: por que zombar de alguém que não usa seu estilo de codificação?
Os assuntos / subdivisões em questão para mim são:
- Por que seria uma prática ruim de programação usar mais código propenso a erros em situações de protótipo, se a refatoração o tornar mais robusto posteriormente?
- Como o programa escrito em C ++ seria como se estivesse escrito em Java? O que o torna um programa ruim (considerando que eu indiquei a intenção do estilo atual e o trabalho planejado para melhorar?)
- Como eu seria um péssimo profissional se eu escolhesse usar um construto usado em um certo paradigma de programação (por exemplo, OOP / DP)?
[1] Desenvolva rápido e com bugs, corrija erros ou seja lento, tenha cuidado com cada linha de código?
int
variáveis separadas para acompanhar o tamanho real.Respostas:
Sem ver o código em questão, existem algumas maneiras de escrever código Java em C ++, algumas piores que outras.
Exceto o número 1, nenhum deles torna um programa C ++ um programa ruim, mas também não é o tipo de código que eu prefiro trabalhar como programador C ++. (Eu também não gostaria de trabalhar com Perl não idiomático ou de estilo C, Python não idiomático, etc.) Uma linguagem tem suas próprias ferramentas, expressões e filosofia, e um bom código usa essas ferramentas e expressões em vez de tentar usar o menor denominador comum ou tentando reproduzir a abordagem de outro idioma. Escrever código não-idiomático em um determinado idioma / domínio do problema / o que não faz de alguém um programador ruim, significa apenas que eles têm mais a aprender sobre esse idioma / domínio do problema / o que for. E não há nada de errado nisso; há uma lista muito longa de coisas que tenho mais a aprender e o C ++, em particular, tem uma tonelada absoluta de coisas para aprender.
Em relação à questão específica de escrever código propenso a erros com a intenção de limpá-lo mais tarde, não é preto e branco:
Para usar ponteiros brutos versus ponteiros inteligentes como exemplo, se você estiver trabalhando em C ++, usar RAII e ponteiros inteligentes é fundamental o suficiente para que seja mais rápido escrever código dessa maneira do que voltar e limpá-lo mais tarde. Novamente, deixar de fazer isso não significa que alguém seja um programador ruim, não profissional, etc., mas significa que há mais a aprender.
fonte
new
são considerados as ferramentas elétricas. O armazenamento automático é a ferramenta manual.Cada linguagem de programação possui um conjunto de idiomas e práticas recomendadas, que geralmente levam a um código elegante, correto e com bom desempenho. Aqui estão algumas das piores práticas perfeitamente bem em outro idioma:
for ($i = 0; $i < 42; $i++) { … }
em Perl, mas não em PHP(no Perl, as variáveis devem ser declaradas e esses loops devem percorrer um intervalo)
new Foo()
em C ++ sem uma boa razão, mas não em Java(o C ++ não possui coleta de lixo, portanto, o RAII deve ser usado. Noobs vazarão memória caso contrário)
(Python é uma linguagem de paradigma múltiplo, forçando "OOP" e suporta funções de nível superior)
return null
em Scala, mas não em nenhum idioma semelhante ao C(porque Scala tem um
Option
tipo)(porque a pilha do Java transborda rapidamente, enquanto o OCaml possui otimização de chamada de cauda)
É fácil usar um novo idioma como se fosse algo que você conhece e, com sorte, até funcionará. "Você pode escrever o Fortran em qualquer idioma". Mas você realmente não deseja ignorar os recursos específicos que o idioma X oferece, porque há boas chances de o X oferecer alguma vantagem sobre o U.
“ Escolho o idioma a ser usado em termos de bibliotecas disponíveis e ambientes ideais de execução para o trabalho em questão ” - mas se esse idioma X é realmente melhor que o idioma U para o trabalho em mãos também depende de quão familiarizado com esse idioma, ou quanto tempo levará para se familiarizar o suficiente para usá-lo bem. Você não produziria uma motosserra pesada apenas porque corta a madeira mais rapidamente, quando você realmente quer sua velha caneta porque ela se encaixa perfeitamente na sua mão. A menos que você queira realmente derrubar uma árvore.
Mas sua pergunta é mais sobre uma questão cultural : aprender todas as melhores práticas leva muito tempo e os novatos fazem mais perguntas, enquanto os gurus as respondem. Mas o que é óbvio para um guru não é óbvio para um novato, e os gurus às vezes esquecem isso. Como um novato, a solução não é parar de fazer perguntas. No entanto, é possível mostrar uma abertura para aprender e aplicar as melhores práticas, por exemplo, tentando limpar o seu código o máximo possível antes de mostrá-lo a outras pessoas. A maioria dos idiomas possui algumas práticas recomendadas básicas fáceis de aprender, mesmo quando toda a curva de aprendizado é realmente muito longa.
Um problema comum é que as pessoas novas na programação desconsideram qualquer recuo ou outra formatação e ficam confusas porque o programa não funciona. Eu também ficaria confuso, e o primeiro passo para entender um programa é garantir que ele esteja perfeitamente estruturado. Então, erros simples, como uma cotação de fechamento esquecida ou uma vírgula ausente, tornam-se subitamente óbvios. Confio em que você já pratica boa formatação, e aqui está uma metáfora para outras práticas recomendadas: as práticas recomendadas evitam erros, as práticas recomendadas facilitam a localização de erros, a aplicação das práticas recomendadas ocorre antes de encontrar o problema .
É muito barato dizer "eu vou consertar isso mais tarde", quando consertá-lo agora teria resolvido seu problema (também, essa lendária "fase de limpeza" pode nunca vir, então a única opção responsável é fazê-lo da maneira correta. primeira vez). No mínimo, tentar tornar o seu código o melhor possível antes de pedir ajuda a outras pessoas facilita a discussão sobre o seu código, assim é a coisa mais educada a se fazer.
fonte
optional<T>
eNullable<T>
respectivamente. Além disso, praticamente todo mundo vaza memória em C ++ sem RAII, noob ou não.Eu não sou um desenvolvedor hardcore de C ++, mas ...
Uma coisa a ter em mente é que um erro no C ++ geralmente significa "comportamento indefinido". Em um idioma seguro, o pior que pode acontecer é uma exceção que encerra seu programa imediatamente. No C ++, você tem sorte se receber um segfault. É perfeitamente possível que seu programa continue fazendo algo sutilmente errado. Ele também pode se comportar corretamente por um período de tempo e manifestar erros muito mais tarde, ou pode se comportar corretamente o tempo todo, mas eventualmente consome toda a sua memória.
De qualquer forma, basta um único erro para tirar a execução do programa completamente dos trilhos e entrar em território desconhecido. É provável que, para o desenvolvedor C ++ em período integral, o "caso base" signifique "nenhuma possibilidade de comportamento indefinido ou vazamento de memória".
Não acho que haja uma resposta para isso que não seja amplamente especulativa e opinativa. Se você quiser que eu entenda, o Java tende a ter alguns antipadrões associados, como o fato de que tudo tem que ser um objeto. Onde em outros idiomas que você passar um ponteiro, functor ou função, em Java você costuma encontrar toneladas de vácuo e por pouco-útil
ThingDoers
,FooFactories
eIFrobnicators
que são apenas funções disfarçados.Da mesma forma, onde em outros idiomas você pode passar uma estrutura simples de tupla ou sem nome, em Java para agrupar apenas dois objetos em um contêiner de dados simples, é necessário predefinir uma classe NamedThing de mais de 30 linhas com setters, getters e Javadocs. A relativa falta de recursos do Java força os programadores a executar backflips duplos orientados a objetos para realizar as tarefas algumas vezes. O código resultante raramente é idiomático fora do Java.
Depois, há o fato de que em C ++ você precisa de um gráfico de objetos muito simplificado para gerenciar a memória manualmente; geralmente um objeto pertence a exatamente um outro objeto. Em Java, você não precisa seguir restrições tão rígidas, porque o coletor de lixo garante que as coisas sejam limpas quando não houver mais referências a elas. Portanto, há definitivamente um risco de gerenciamento de memória incorreto se você apenas transliterar o código de Java para C ++.
Finalmente, poderia ser apenas elitismo. Não vou fingir que eles são a maioria, mas definitivamente vi um sentimento de "não preciso de uma linguagem que segure minha mão e me impeça de fazer coisas estúpidas" entre alguns desenvolvedores de C ++. Na opinião deles, C ++ é uma linguagem "real" e, se você não consegue lidar com suas idiossincrasias, não é um "programador real".
fonte
Resposta levemente fora do tópico ...
Não se preocupe - esse é um "comportamento" comum em qualquer comunidade de especialistas. E seja honesto, se você é bom em qualquer idioma e encontra um código "estranho", provavelmente também o criticará. (porque, quero ensinar).
Estou no mundo perl - quando verá algo como:
ao invés de:
com certeza comentará - (leia: ensine o autor) sobre a
join
função.De qualquer forma, muitas críticas são contraproducentes e um dos melhores exemplos é o seguinte: (extraído de: http://perl-begin.org/humour/#How_can_I_switch_off_the_T.V..3F )
(Este bit foi postado anonimamente em um pastebot em 23 de março de 2011. Ele é colocado aqui para posteridade após algumas edições.) - também ligeiramente editado
fonte
Ao escrever rápido e sujo, com a mente de corrigir mais tarde, existe o perigo de esquecer algo que você precisa corrigir.
No java, você não precisa pensar em quem possui um determinado objeto, basta passar a referência e esquecê-la como se não fosse nada. No entanto, em C ++, é necessário definir claramente quem é o proprietário do objeto e quem é responsável por limpá-lo.
Você não faria; O C ++ é uma linguagem com vários paradigmas, mas suporta OOP muito bem, mas também pode fazer muitas outras coisas. No entanto, a maior parte se resume ao uso da ferramenta correta para o trabalho, em vez de puxar o martelo toda vez que você precisa colocar um espigão pontudo em alguma madeira.
A razão pela qual você recebeu uma resposta ruim é que a maioria das pessoas no SO tende a julgar as habilidades pela idiomática que você pode codificar no idioma que está perguntando. As pessoas familiarizadas com o C ++ tendem a tremer de joelhos quando veem códigos ruins que parecem com algo que os havia mordido no passado.
fonte