Executando verificação de segurança...
6

Código complexo é sinônimo de bom programador?

O título provocativo desse post, "Código complexo é sinônimo de bom programador?", nos conduz a uma reflexão sobre a relação entre a complexidade do código e a qualidade do desenvolvimento de software. Antes de responder a essa provocação, é essencial analisar o papel fundamental da simplicidade e legibilidade na construção de softwares sustentáveis.

A Comunicação Intrínseca do Código

Assim como explicar conceitos complexos de maneira clara é fundamental para a comunicação efetiva, escrever código de forma simples é uma expressão direta dessa habilidade. Martin Fowler, em uma de suas obras, destaca que a simplicidade é uma das metas mais relevantes do refatoramento. Esta busca incessante por simplificação não somente torna o código compreensível, mas também facilita a evolução do software ao longo do tempo, garantindo a manutenção contínua e aprimoramentos graduais.

Uncle Bob, nos lembra que o código é, em essência, uma forma de comunicação entre os membros da equipe. Quando o código é complexo e de difícil leitura, as mensagens transmitidas tornam-se obscuras e confusas. A legibilidade, de acordo com Uncle Bob, é a chave para estabelecer uma comunicação clara e eficaz entre os programadores, permitindo que o software seja entendido, modificado e aprimorado de maneira eficiente.

O Código Ruim: Uma Ameaça Latente

É crucial compreender os impactos de um código mal escrito e planejado ao longo do tempo. Códigos mal escritos, frequentemente se tornam verdadeiras armadilhas de manutenção. A resistência à mudança aumenta, a detecção e correção de bugs se tornam tarefas homéricas, e a capacidade de adicionar novos recursos é prejudicada.

O Custo Humano da Complexidade

A reverberação dos efeitos do código ruim não se limita apenas ao sistema, mas também afeta profundamente a equipe de desenvolvimento. A dificuldade de compreensão e manipulação do código complexo resulta em um ambiente de trabalho frustrante e desafiador. Desenvolvedores são frequentemente sobrecarregados com a necessidade de decifrar funcionalidades obscuras e inconsistências, o que pode levar à exaustão e desmotivação.

A presença de um código mal estruturado e complexo não apenas impacta negativamente o moral da equipe, mas também aumenta a probabilidade de perder talentos valiosos. A rotatividade de desenvolvedores pode ser desastrosa para uma empresa, resultando em perda de conhecimento, atrasos no projeto e até mesmo custos adicionais para recrutamento e treinamento.

Conclusão

Um código complexo é um fardo que compromete a evolução do software, levando a defeitos e reduzindo a capacidade de inovação.

Além disso, o custo humano não pode ser subestimado. A complexidade do código tem o potencial de corroer a moral da equipe, levar à exaustão e resultar na perda de talentos preciosos. Creio que com base nisso, é inegável que a resposta à pergunta inicial é código complexo não é sinônimo de um bom programador.

Ao priorizar a simplicidade e a legibilidade no desenvolvimento de software, os desenvolvedores não apenas fortalecem o código em si, mas também criam um ambiente de trabalho mais saudável e uma base sólida para a inovação. A busca pela excelência na programação é intrinsecamente ligada à capacidade de comunicar soluções complexas de maneira clara e acessível. Nesse caminho, os programadores se transformam em verdadeiros artesãos de software, contribuindo para a construção de sistemas robustos, confiáveis e evolutivos, que atendem tanto às necessidades atuais quanto às futuras.

Carregando publicação patrocinada...
6

Vou começar falando sobre os termos "complexo" e "complicado".

Embora não haja uma distinção geral de significado entre os dois, eu gosto de usar na área de engenharia um significado diferente para cada. Pra mim, complexo é algo inerente ao problema, é a dificuldade fazer porque o que tem em mãos envolve muitos elementos e suas relações são entremeadas. Já complicado é algo evitável e geralmente feito assim só por desconhecimento de forma melhor ou relaxo.

Portanto, dentro dessa definição, o programador não consegue evitar código complexo mas consegue evitar código complicado.

O problema é que a decisão do que é complicado pode ser subjetivo. O que é complicado para um pode não ser para outro. Frequentemente eu acho complicado códigos que a maioria das pessoas fazem o tempo todo. Ou seja, cheia de elementos que não precisariam estar ali, e violam o YAGNI e o KISS. Ao mesmo tempo eu faço código simples que algumas pessoas podem achar complicadas porque elas desconhecem a forma de programar assim. Vou dar um exemplo:

if (ativo == true)

   
é complicado para mim

if (ativo)

   
é complicado para outras pessoas.

Então algumas pessoas entendem que complicado é ser tão explícito que se torna redundante, e para outras é tudo o que é desnecessário.

Todo mundo concorda que deve fazer código simples. "Ninguém" concorda sobre o que é um código simples. Boa parte do que os autores citados pregam são complexidades muitas vezes desnecessárias em um código, mas que muita gente adota porque está em um livro. Se o que eles pregam é realmente necessário para o código ser sustentável então é uma complexidade aceitável. Caso contrário é só complicação que a pessoa adotou por falta de entendimento completo sobre o processo de desenvolvimento de software, o que eu acho frequentemente de "seguir receita de bolo".

Código sustentável é aquele que observa um contexto. E não coloca penduricalhos desnecessários. Porque cada token de código que coloca e não serve para nada, é um código a mais para dar manutenção. Se o código tem aquela necessidade, então está tudo bem.

Em geral, um código ruim acontece por falta de domínio da computação e engenharia de software e/ou do domínio específico que está trabalhando. O exemplo que eu dei acima é falta do primeiro. Frequentemente o segundo acontece porque o programador não tem todas informações necessárias, e isso é relativamente normal. É muito difícil obter todas as informações necessárias, então ele vai deixar de colocar algo importante e colocará algo no código que não faz o menor sentido, só porque ele acha que será um dia, de acordo com a informação atual que obteve.

Minha observação pessoal é que acontece mais os extremos. Ou a pessoa faz sem qualquer planejamento ou ela faz um monte de coisa porque ela acredita que terá necessidade, paga o preço por isso e nunca compensa o esforço. Achar o equilíbrio é difícil até para os experientes, a não ser em um problema idêntico que a pessoa já tenha trabalhado e já cometeu todos os erros e já os corrigiu antes. O que é muito raro acontecer.

Uma das justificativas que as pessoas dão para tornar a solução mais complexa é a redução da complexidade, o que torna complicado. Para isso é comum usar soluções em camadas, como o anti pattern chamado "código lasanha", em geral mal pensado e sem vazamento de abstração se torna muito difícil usá-lo em uma situação diferente do que ele foi pensado. A pessoa faz o código como se estivesse produzindo um carro, só que carros são difíceis de dar manutenção já que eles têm regras próprias que você tem que se conformar, você não pode usar do jeito que bem entende.

Repito, é muito difícil prever o futuro, e o software sempre tem um futuro incerto. Se preparar demais para o futuro será tudo complexo demais, complicado de fazer e até mesmo, de certa forma, de dar manutenção. Se fizer simples demais terá que refazer tudo depois. E isso pode ser melhor em alguns casos, ao contrário da crença popular. O problema é saber quando usar um ou outro.

De forma geral concordo com o texto e ele é valioso para ajudar as pessoas entenderem o problema, só achei que precisava complementar com isso.

Faz sentido para você?

Espero ter ajudado.


Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).

1

Mestre maniero, como sempre com reflexões importantes que enriquecem o conteúdo.

Sobre o código simples, penso eu, que é aquele que você consegue bater o olho no algoritmo e ler como se fosse uma história. Tu entende o inicio o meio e o fim da instrução de código.

Nomes de métodos e variáveis bem descritivas e por ai vai.

Concordo 100% sobre o fazer código sem planejamento, na maioria das vezes é colocando um Over Engineering absurdo em cima de coisas que deveriam ser simples.

1

Importantíssimo a parte explicando sobre complexidade. Realmente, alguns domínios do conhecimento são complexos, não há oque fazer, é uma característica inerente a eles.

Consequentemente, a implementação desses domínios em um software irá requerer uma estruturação relativamente complexa para criar uma abstração à altura da complexidade inerente. Um framework MVC de alto nível, por exemplo, possui diversos módulos necessários para caracterizar essa ferramenta como eficiente.

Uma implementação de leitura de request, de um esquema de rotas, de uma camada de acesso a um banco de dados são implementações relativamente complexas, que muitas das vezes são abstraídas o máximo possível para que o usuário da ferramenta não enfrente dificuldades. Porém, com uma rápida olhada no código pode debaixo dos panos, percebe-se que o que está em alto nível é apenas a casca de um todo, de complexidade muito maior.

Achei interessante também a explanação sobre o fato do conceito de 'complicado' ser relativo. A implementação e a leitura de um código com design patterns pode ser complicada para um iniciante, porém, é sabido que esses patterns tornam o projeto mais saudável e manutenível, e na maioria das vezes diminuem a curva cognitiva para entendimento do código.

2

Concordo com os pontos mencionados! Também acredito que um código complexo possa prejudicar um projeto em inúmeros aspectos, entretanto, um dúvida pairou na minha mente enquanto lia seu post: o que é um código complexo?

Muitas vezes eu preciso acessar códigos de companheiros de equipe para resolver alguma coisa, procurar uma informação ou entender como algo está funcionando, e, por conta de outras partes do projeto serem escritas linguagens que não são meu forte, tudo pra mim é complexo! E o mesmo acontece com as outras partes da equipe, já que cada um atua em uma área.

Sendo assim, acredito que um código complexo esteja mais ligado a escrever coisas desnecessárias, esquecendo dos princípios do Clean Code, por exemplo, deixando o código "sujo", do que comandos específicos que "ninguém" entenda.

1

Vocês têm a cultura de praticar code review? Talvez isso possa ajudar a reduzir o número de code smells e tornar a base de código mais legível e de fácil manutenção a todos.

Sobre código complexo usei esse termo de propósito mesmo para gerar discussão. Na minha opnião código complexo é aquele código "macarrônico" que chega a dar Lesões por esforços repetitivos (LER) no dedo de tanto ficar com o dedo no scroll do mouse.

1

Não temos esse costume. Na verdade, nunca havia escutado esses termos, então fui procurar aprender! Caso mais alguém tenha interesse, seguem alguns links sobre Code Smell e Code Review.
Vou aplicar esses conceitos com a minha equipe! Valeu pela dica!

1

É por isso tão difícil de aplicar em sua essência."A simplicidade é o último grau da sofisticação” – o conceito atribuída a Leonardo Da Vinci.
Certamente os melhores programadores são aqueles capazes expressar ideias complexas de forma simples.

1

Eu gosto da simplicidade. Mas escrever algo complexo de uma forma simples, ao meu ver é uma das habilidades do progamador(a) excepcional. Exige treino e creio que também isso amadurece no decorrer da carreira também

1

Na minha opinião, quanto mais simples é o código que você desenvolve para resolver problema X, melhor programador você é. Quanto mais complexo é o código, mais difícil se torna mantê-lo.

1

Eu adicionaria mais dois aspectos para o código "complexo" (se bem que eu concordo com o que o Mestre maniero comentou sobre código complexo e complicado): falta de tempo e arquitetura.

Falta de tempo - É comum muitas empresas quererem que o sistema seja entregue o mais rápido possível, apenas que esteja funcionando, sem planejar o código e entender bem as regras de negócio e isso gera muita "complexidade" (ou "complicabilidade") ao código. Há situações que é um Xtreme GoHorse disfarçado. Infelizmente é comum eu ter que lidar com código meu que esteja muito complicado simplesmente porque no passado não foi me dado tempo para pensar bem a estruturação do código e só foi virando uma bola de neve.

Arquitetura - Aqui é algo mais específico, mas como muitos sistemas utilizam microsserviços, então eu acho que é válido. Normalmente quando colocamos microsserviços na jogada as coisas tendem a ficar mais "complexas" naturalmente, e nem seria por falta de código simples, mas porque começamos a orientar a comunicação dos microsserviços por evento/mensagem, o que pode gerar muita confusão ou a famosa "Microservice Death Star" (que também pode ser bem feita, mas é mais suscetível à complexidade/complicabilidade)

1

Sem definir o contexto, as respostas serão superficiais e genéricas. E mesmo assim:

  1. Pessoas são diferentes, pensam diferentes e possuem uma bagagem cultural diferente. A definição vai variar para cada pessoa.

  2. Existem linguagens com estruturas diferentes. Algumas mais rígidas como COBOL que deixam os programas mais parecidos e com uma facilidade maior de leitura/entendimento. Outras mais flexíveis e com diversas regras e redundância onde é possível fazer a mesma coisa de diversas maneiras diferentes. O problema 3 do Projeto Euler é facilmente resolvido com: {:q: 13195. Será que é complexo? Será que é difícil? Ou, será que qualquer programador que conheça a linguagem dirá: Pois é, simples assim.

  3. Relacionado com o item 1, elementos de um determinado grupo podem utilizar características diferente pelo seu modo de raciocinar sobre as coisas. Os programas em C de quem programa em APL ou alguma linguagem parecida, certamente não entrarão na cesta simplicidade da maioria dos mortais. Olhe o código que deu origem ao J. Foi escrito em 4h por Kiln Farm e o Ken Iverson estudou durante uma semana. Outro exemplo de código em C que a maioria acharia uma porcaria em termos de legibilidade. Mas, para eles, assim é mais fácil de desenvolver o raciocínio.

  4. Já que eu citei raciocínio, Se tu estás acostumado com linguagens imperativas (Java[Script], C, Python, Ruby, etc.), pega um program ridicuamente simples com o primeiro do AOC 2021, resolve na tua linguagem e depois tenta uma funcional tipo Haskell, Elm, F#, tec..

Basicamente isso. Como em um artigo sobre Linux e o cara escreve: para instalar o Apache basta digitar sudo apt install apache. Só é valido para distros baseadas no Debian.

1

Pra mim sempre vale a distinção do Rich Hickey

Simples - Complexo (Objetivo) e Fácil - Difícil (Subjetivo)

Algo simples é objetivamente uma parte que pode ser totalmente isolada das demais e ainda assim funciona pra função que foi criada.

Algo complexo seria quando as varias partes de misturam entre si, e acabam por afetar as demais.

Já Fácil e Difícil são subjetivas, eu posso achar o framework X facil e o Y difícil. Mas se o framework Y separa os conceitos de Router e Controller e o framework X trata ambos de uma maneira unificada o framework X é mais complexo que o Y

Recomendo sempre a palestra Simple Made Easy onde explica esses conceitos de maneira melhor.

Essa avaliacao esta sujeita a falhas de julgamento, mas é um ponto de inicio pra uma conversa melhor sobre Simple - Complexo, tentando deixar de lado o Facil e Dificil.