Clean Code: A Filosofia da Programação Através de Metodologias Limpas
- #Arquitetura de Sistemas
RESUMO
A minuciosa atividade de programar requer diversos padrões e estruturas a serem seguidos. A soma de uma boa legibilidade com técnicas de redução de erros aliadas a correção de alta complexidade configura-se, portanto, no que chamamos de Clean Code. Tal filosofia de desenvolvimento, digna destaque no âmbito da programação, corrobora com a redução de custos de manutenção, clareza de escrita, aprimorando, então, a qualidade final estrutural do código, refletindo em uma arquitetura lógica limpa. O presente artigo busca ressaltar e discutir sobre conceitos e principais estruturas desta técnica.
1 INTRODUÇÃO
O conceito que conhecemos atualmente por Clean Code, tem seu primeiro aparecimento em 2008, através do famoso livro “Clean Code: a Handbook of Agile Software Craftsmanship”, escrito por Robert Cecil Martin, também conhecido como "Uncle Bob". Tal obra teve sua base fundamentada sob a ideia de que a fácil manutenção e legibilidade de um código é tão significante quanto sua construção lógica. Ademais, com o passar dos anos, a agravante consequência de códigos redigidos ordinariamente torna-se explícito na comunidade tech, resultando em códigos obsoletos, que necessitam de manutenções de custos exorbitantes e tempo demasiado longo para sua inteligibilidade. Nesse âmbito, podemos salientar a dimensão que um código limpo pode precaver e protagonizar no cotidiano de todo programador.
Clean Code possui como principal objetivo agregar legibilidade, produtividade e funcionalidade ao aprimorar a fluidez de leitura e manutenção, poupando tempo e recursos, dois pontos cruciais na área de desenvolvimento da programação solo ou mesmo em equipes. O investimento, antes consequente da necessidade de manutenção do software constantemente devido a bugs indesejados, é drasticamente inferior, pois agora centralizamos o trabalho do código em áreas de complexidade menores, focalizando em sua arquitetura e qualidade após testes graduais. A técnica Clean Code também provê agilidade de compreensão quando lidamos com uma grande quantidade de dados e códigos redigidos, prevenindo eficientemente possíveis desvios lógicos e gastos desnecessários de ferramentas e recursos.
Dessa maneira, diversas equipes e programadores adotam esse conjunto de boas práticas, usufruindo de seus plurais benefícios. Evidenciando, portanto, o mérito do levantamento de questões como formas de aplicabilidade e estruturação geral do aclamado Clean Code.
2 BOAS PRÁTICAS DE FORMAÇÃO DE CÓDIGO
As boas práticas que consistem em como escrever um bom código vão além de um simples raciocínio lógico ou percepção prévia de possíveis erros. Cada ponto que será citado a seguir, tem sua devida importância quando colocadas em ação. Abaixo sobressaltam-se algumas destas práticas:
1. Bons nomes são cruciais: a definição de um nome inteligível em classes, variáveis, funções e afins, que representa, assim, seu significado sem conflitos de linguagem podem poupar muito tempo ao ter o código lido e usado por outro programador ou equipe.
2. Originalidade: muitas vezes ao buscar inspirações para a construção de um código, torna-se rotineiro mesclar com frações encontradas via web. Porém, busque sempre aprimorar seu conhecimento a ponto de desenvolver suas soluções personalizadas, visto que, um raciocínio autoral é superiormente valoroso quando tratamos de originalidade.
3. Formatação: se atente aos detalhes da indentação do código, destacando a organização e sua estrutura geral, isso agrega valor visual ao trabalho final.
4. Comentários somente quando necessário: evite comentar a cada linha ou função escrita, este ato pode poluir visualmente seu código ou o tornar menos funcional. Opte apenas por explicar fragmentos mais complexos do trabalho em questão.
5. Criar tratamento de erros: estratégias para solucionar possíveis erros poupam tempo e são úteis como guia caso a execução do código sofra alguma inconsistência. Sempre lembre de organizar variáveis e estratégias a serem consideradas se o código apresentar alguma falha.
6. Categorização de classes: organizar suas classes em uma espécie de hierarquia de diretórios relacionados evidencia uma elaboração que reflete em uma lógica bem raciocinada. Quanto mais categorias e especificações nominais são agregadas a cada funcionalidade, mais clareza é refletida em seu projeto.
3 BENEFÍCIOS DA PRATICA TDD NA TÉCNICA CLEAN CODE
Um software mal estruturado é, em outras palavras, um programa que sofre inúmeras instabilidades em seu desenvolvimento e acarreta em diversos malefícios que implicam em um mal funcionamento a curto ou a longo prazo. Um programa com propósito a ser distribuído para futura utilização se assemelha a um automóvel disponível no mercado, obviamente ambos exigem testes previamente calculados para garantir a qualidade do serviço final a ser disponibilizado. Atestar a usabilidade de tal produto necessita, primeiramente, conhecer minuciosamente seus pontos e construção, só assim é possível elaborar um teste de proporção eficiente. No âmbito da programação, quando lidamos com um projeto específico, é preciso ser feita uma pesquisa e análise detalhada sobre a arquitetura e lógica por trás de cada parcela escrita. Fora da analogia, trazendo esta perspectiva a programação, a técnica criada por Kent Beck, denominada TDD: “test driven development” visa otimizar tempo, recursos e trabalho no andamento de um projeto.
TDD tem sua aplicabilidade voltada para teste de unidades singulares do código, eliminando bugs e apartando os pontos úteis dos repetitivos e descartáveis. Tudo isso é estruturado em ciclos que, em suma, são fundamentais para a conclusão. Abaixo é possível a ilustração de cada etapa:
Temos, portanto, que a fase inicial red é o ponto de partida, onde cria-se um teste completo e independente, que tornará respostas não ambíguas, ou seja, validando todo conjunto do código apenas em true or false. A proposta aqui é identificar os principais erros.
Na segunda parte, denominada de green, o código passa por uma limpeza e se necessário alterações, mesmo assim, com probabilidade de erros arquitetônicos. O que não desencoraja a seguir com o próximo passo, que ajusta qualquer erro possível.
Por último, mas como protagonista do processo, temos a conclusão do ciclo com o refatoramento do código. Basicamente é anulado a soma de bugs, otimizando a estrutura do código.
Em síntese, esse ciclo auxilia no processo de trabalhar com um produto que demanda um resultado de alta qualidade, o que sempre é visado em projetos reais, seja individual ou coletivo. Lembrando que, o ideal é repetir estes passos múltiplas vezes, a fim de eliminar qualquer variável de falha. Sempre atentando-se a frações individuais do código, observando com detalhes a reação a cada teste, progressivamente.
4 ABRANGENDO A ETAPA DE REFATORAÇÃO
Em um determinado momento do desenvolvimento de um código, suas inconsistências de escrita tornam-se complexas e impossibilitam que ciclos TDD sejam realizados com êxito, o que, muitas vezes, retarda a evolução de um projeto e abre lacunas para erros. A refatoração realizada no terceiro passo é crucial para evitar esse cenário caótico. Ela auxilia a implementar ajustes no código, tornando-o mais limpo e eliminando qualquer vestígio de duplicidade, de maneira a não modificar sua funcionalidade primordial. Em outras palavras, é como se o projeto sofresse uma espécie de refinação
A meta da técnica de refatoração é alcançar um nível de código simples, limpo e objetivo e de fácil manutenção, minimizando a chance de que bugs ocorram. Quando a refatoração ocorre, o código continua a executar sua função inicial, porém torna-se mais legível em sua estrutura e, consequentemente, mais organizado. Para isso, temos abaixo listadas algumas das técnicas utilizadas nesse processo:
Mover Método (Move Method): Usado em ocasiões onde identificamos um método que será utilizado múltiplas vezes em outras classes diferentes. A estratégia é criar um método similar na classe em que o está utilizando e depois fazer uma cópia para o novo método, substituindo chamadas para o local.
Extrair Método (Extract Method): Um dos erros na programação é ter frações de código duplicadas. Neste cenário é interessante mesclar estas partes para métodos nomeados. O nome deve ter explicitamente o significado da proposta em sua função, evitando equívocos de leitura.
Extrair Classe (Extract Class): No processo de desenvolvimento, algumas vezes, é comum sobrecarregar uma classe com diversas funções, isto acaba poluindo a legibilidade do código e perdendo sua coesão. O ideal para solucionar esta situação é criar novas classes e distribuir estas funções, desta maneira, as classes não crescem desnecessariamente e tornam-se desordenadas.
5 SOLID DESIGN COMO APRENDIZADO
O acrônimo criado por Michael Feathers, autor de obras relacionadas a programação e design, representa a relação com os princípios da Programação Orientada a Objetos (POO). Auxiliam no desenvolvimento de softwares, tornando-os de fácil compreensão e modificação. Podemos observar abaixo os estes princípios diluídos em cinco pontos:
- S — Single Responsibility Principle (Princípio da responsabilidade única)
- O — Open/Closed Principle (Princípio Aberto/Fechado)
- L — Liskov Substitution Principle (Princípio da substituição de Liskov)
- I — Interface Segregation Principle (Princípio da Segregação da Interface)
- D — Dependency Inversion Principle (Princípio da inversão da dependência)
Seus Respectivos Significados
SRP - Single Responsibility Principle: Este principio evita que tenhamos diversas classes conflituosas no código, pois alega que uma classe deve possuir uma única função a ser cumprida. A classe que possui uma tarefa singular no código tem a eficiência mais centralizada, pois não é complexa.
OCP - Open/Closed Principle: Ao criar um objeto, devemos nos atentar em deixá-lo aberto para uma possível extensão, mas não uma modificação. Portanto, será possível assegurar que os objetos criados mantenham-se independentes uns dos outros, trazendo maior flexibilidade para implementações futuras e adições de novas funcionalidades. Prezando por extensões, mas nao alterações abruptas.
LSP - Liskov Substitution Principle: Nos orienta que subclasses devem ser substituíveis por suas classes de base. Exemplificando, se a classe X for uma subclasse da classe Y, podemos mover um objeto de uma classe X para qualquer método que o espere na classe Y. É possível, então, chamar nossas classes derivadas referindo-se à sua classe e isso não resultará em anomalias no código.
ISP - Interface Segregation Principle: Mostra que é interessante a criação de interfaces mais específicas, em troca de uma única classe genérica e absorta para todos do mesmo tipo, ou seja separar/segregar as interfaces. Conseguimos, com esse método, uma segurança mais estável ao programa, pois com mais especificidades em cada parcela do código, agregamos somente as funcionalidades relacionadas que serão úteis para o funcionamento individual de interfaces.
DIP - Dependency Inversion Principle: Este princípio introduz que as classes devem depender de interfaces ou de classes abstratas. Sobre isso, Uncle Bob nos resume duas definições, legitimamente esclarecedoras:
1. Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender da abstração.
2. Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações.
Assim, conquistamos classes desacopladas de bibliotecas ou interfaces específicas. Elas passam a utilizar abstrações, deixando mais livre outras ferramentas.
6 CONCLUSÃO
Neste artigo, exemplificamos conceitos e práticas do Clean Code, bem como sua aplicabilidade e as diversas técnicas que o acompanham. Após a análise das pluralidades de alternativas a serem seguidas para programar um código com êxito, destaca-se, portanto, a significância da prática Clean Code como hábito. Em suma, seus princípios são a base para a eficácia da funcionalidade de um código, sugerível a consideração em toda e qualquer ocasião em que se deva criar, modificar ou estender um código. A aplicabilidade deste conhecimento é, em certa instância, admitir que podemos otimizar nosso trabalho, organizando-o sem o distanciar de sua essência.
Cabe citar a famosa frase de Martin Fowler, autor conhecido nas áreas de arquitetura de software, refatoração e metodologia ágil: “If you're afraid to change something it is clearly poorly designed”, traduzido para o Português como: “Se você tem medo de mudar algo, isso é claramente mal projetado”. Em vista disso, não tenhamos medo de modificar nossos métodos, pois nossa maneira de pensar pode evoluir a ponto de admitirmos nossos erros com mais naturalidade e saber portar as estratégias corretas de como lidar com eles, cada vez mais amadurecendo nossos códigos em projetos refinados e consistentes. Afinal, não há nada sujo que não possa ser limpo.
7 LINKS DE REFERÊNCIA
https://www.sydle.com/br/blog/clean-code-602bef23da4d09680935509b
https://www.hostgator.com.br/blog/clean-code-o-que-e/
https://medium.com/@pablodarde/testes-unit%C3%A1rios-com-tdd-test-driven-development-657f3dadad06
https://www.hostgator.com.br/blog/clean-code-o-que-e/
https://www.freecodecamp.org/portuguese/news/os-principios-solid-da-programacao-orientada-a-objetos-explicados-em-bom-portugues/
https://www.devmedia.com.br/tdd-fundamentos-do-desenvolvimento-orientado-a-testes/28151
https://www.devmedia.com.br/introducao-a-refatoracao/21377