Skip to content

Instantly share code, notes, and snippets.

@omarkdev
Created May 10, 2017 13:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omarkdev/a14872ae82d13d1706b676832b891399 to your computer and use it in GitHub Desktop.
Save omarkdev/a14872ae82d13d1706b676832b891399 to your computer and use it in GitHub Desktop.

Como escrever um código melhor

É aqui que diferenciamos os programadores, dos bons programadores.

Um código é bem mais importante que apenas letras que executam funções definidas. Você se lembra na escola, quando um professor dizia que "O caderno é o espelho do aluno", cada vez vejo que isso se torna mais verdade, porém o caderno é o código e o aluno é o programador. Imagine o que seria de uma confeiteira se ela entregasse seus bolos de qualquer jeito, porém gostosos?

Hoje em dia existe milhões de Design Patterns, nesse série iremos abordar alguns que são fáceis de implementar ou que causam um grande impacto em seu mindset. Nesse post iremos abordar o Object Calisthenics, que na minha opinião é o Design Pattern mais importante, pois acredito que seja o pontape inicial para um código perfeito e legível.

Object Calisthenics

O Object Calisthenics é uma série de boas práticas e regras de programação que foram criados pela comunidade de desenvolvedores Java. Contendo apenas 9 regras fáceis, que mantém organização e clareza para compreensão de um código.

Primeira Regra: Apenas um nível de identação por método

Ao olharmos aquele método gigante e nos perguntamos "Por onde começar?", isso com certeza já foi muito comum para você. Seria um sonho enterdemos rápidamente o que um método faz?

A idéia principal é que um método faça apenas uma coisa, desse modo facilitamos a leitura e facilidade de manutenção do código. Você pode extrair comportamentos para outros métodos, garantindo um único nível de identação, fazendo isso você também está aplicando o Extract Method Pattern.

-- EXEMPLO ANTES -- -- EXEMPLO DEPOIS --

Segunda Regra: Não use else

Com certeza a regra mais polêmica, porém acredito que seja a mais importante. O olhar assustador ou pensativo quando se olha essa regra é normal, porém iremos perceber que é algo extramente simples.

A idéia principal é simples, negue todo o possível em seu método antes. Nessa forma assumimos retornos antecipados e definindo um fluxo de trabalho padrão.

-- EXEMPLO ANTES -- -- EXEMPLO DEPOSS --

Por mais difícil que seja essa regra, dessa forma nós sempre teremos uma maneira de evitar if-elseque não são divertidos de ver e analisar. Em alguns outros casos mais complexos, você pode também aplicar algumas práticas como State ou Strategy Design Patterns que irao te auxiliar com o fluxo de estado usando a composição de objetos. Falaremos dessas duas estratégias depois.

Terceira regra: Envolva seus tipos primitivos

Essa regra na realidade é uma das mais simples, pois ela diz que você deve encapsular todos os tipos primitivos dentro dos objetos, assim você previne Primitive Obsession Anti-Pattern.

Um int por conta propia, é um tipo sem significado. Quando se tem um método que um de seus parâmetros é um int, o nome do método precisa fazer todo o trabalho para expressar a intenção, ou, o programador ter que perder um certo tempo tentando entender o intuito. Suponhamos que o método requer um parâmetro do tipo Hora, será muito mais fácil saber o comportamento desse parâmetro e do método. Seguindo essa ideia, um pequeno objeto como esse pode tornar sua aplicação muito mais sustentável, uma vez que nesse caso não seria possível passar Ano como parâmetro em um lugar que deve receber Hora.

-- EXEMPLO ANTES -- -- EXEMPLO DEPOIS --

Quarta regra: Envolva suas collectinos em classes

A idéia inicial dessa regra, diz que se você tiver um conjunto de elementos e quiser manipulá-los, crie uma classe dedicada (collection) apenas para este conjunto, assim ao atualizar aquele valor, com certeza será em sua collection.

Seguindo o comportamento dessa regra, você deixa os comportamentos relacionados. O maior objetivos dessa regra é: aderir o Single Responsibility Principle (A letra S do S.O.L.I.D.) e High Cohesion.

-- EXEMPLO ANTES -- -- EXEMPLO DEPOIS --

Quinta regra: Use apenas um ponto por linha

Esse "ponto" é o que você usa para chamar métodos em Java ou C#, no caso do PHP seria uma seta.

Esta regra é o exemplo da Lei de Deméter, apenas fale com seus amigos, onde você nunca deve usar mais de um operador de objeto. Simplificando, você não deve encadear chamadas de métodos. Porém existe uma exceção, ela não se aplica a Fluent Interfaces e a qualquer coisa que se implementa o Chaining Pattern (muito usado por exemplo em Query Builders).

-- EXEMPLO ANTES -- -- EXEMPLO DEPOIS --

Sexta regra: Não abrevie

Incontável as vezes em que nós abrimos um código e encontramos uma váriavel $i, por mais comum que seja encontramos essa váriavel em varios projetos em funções de iterações, imagine entender o que seria a váriavel $nou $x. Por mais tentador que seja abreviamos nomes de váriaveis, classes ou métodos, lute contra essa tentação! As abreviações podem ser confusas e tendem a esconder problemas maiores.

Analisar o mótivo de estar abreviando é uma ótima solução. Será que isso pode estar acontecendo por estar digitando a mesma palavra várias vezes? Se for verdade, talvez você deva reanalisar seu código para remover duplicações. Outro caso é quando os nomes dos seus métodos ou váriaveis estão ficando longos, isso pode ser um sinal que sua classe esteja fazendo coisas que não pertence a ela.

Uma dica importante: Sempre tente manter nome de suas classes, métodos ou váriaveis com apenas duas palavras e que essas palavras não sejam coisas repetitivas. Considere uma classe com o nome Profile. Um método dessa classe não tem nenhuma necessidade de se chamar createProfile, basta chamá-lo de create, pois podemos invocá-lo com profile->create(), mantendo uma repesentação clara do que será realizado.

Sétima regra: Mantenha todas as classes pequenas

Tenha em mente que é recomendável que uma classe tenha no máximo 50 linhas e os pacotes não tenham mais que 10 arquivos. Geralmente quando criamos uma classe com mais de 50 linhas, atribuimos a ela mais responsabilidades, tornando-se mais díficeis de entender e reutilizar.

Classes e pacotes, devem ser coesos e ter um propósito e esse propósito deve ser fácil de se entender.

Oitava regra: Não tenha mais que duas variáveis de instância em sua classe

Uma regra que não precisamos de um exemplo, pois é muito simples, porém uma das mais díficeis de ser implementada, pois ela depende de um mindset totalmente diferente do habitual.

Ao termos no máximo duas variáveis de instância, isso garante que estamos respeitando novamente o Single Responsibility Principle e High Cohesion. Se sua classe tem mais que duas váriaveis de instância, bem provável que ela esteja fazendo mais de uma responsabilidade.

Nona regra: Não use Getters ou Setters

No primeiro momento pode parecer uma regra bem estranha, no entando a idéia é bem básica, você retira os getters e setters para poder adicionar decisões no própio objeto. Qualquer decisão baseada inteiramente no estado de um objeto deve ser feita diretamente no objeto.

Há muitos benefícios quando aplicamos essa regra. Reduzimos a duplicação de regras e damos uma melhor compreensão à aquele objeto. Também enriquecemos nosso objeto com lógica e métodos mais valiosos e significativos, não apenas usá-lo como uma classe com apenas dados.

-- EXEMPLO ANTES -- -- EXEMPLO DEPOIS --

Bônus: Não comente seus códigos

Essa não é uma regra do Object Calisthenics porém mais polêmica que a regra do else.

A um tempo atrás li um post no Medium com o seguinte título: Nunca mais comente seu código e achei extremamente polêmico, no decorrer da leitura percebi que aquilo era extremamente essencial. Recomendo a leitura completa do post.

Irei simplificar o que o autor queria dizer. Os métodos muitas vezes fazem mais coisas que o necessário e isso torna o código ilegível. Ao quebrar um método em vários metodos removemos a necessidade de escrever comentários, pois se tornaria redundante, já que nosso método faz exatamente o que seu nome diz.

-- EXEMPLO ANTES -- -- EXEMPLO DEPOIS --

Conclusão

Algumas dessas regras são extramemente simples, porém implementá-las no seu dia a dia pode se tornar complexas. Com certeza será muito díficil você migrar um projeto com um legado, do dia para a noite usando essas regras, mas aos poucos você consegue implementá-las.

Toda a questão se resume em você querer que seu código chegue o mais próximo da perfeição possível. Como você acabou de ver não é algo tão fora da realidade, permita-se evoluir como um programador. Um ótimo programador não é um programador que sabe 1000 linguagens, é um programador que consegue escrever um código perfeito e coeso.

No próximo post falaremos de S.O.L.I.D. e alguns outros Design Patterns bem conhecidos.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment