Olá, seguimos nossa exploração sobre sinais de alerta no código
os Coates mails. Com base no material de
engenharia de software Moderna, hoje vamos focar em como algumas
práticas comuns podem, na verdade, esconder problemas de
design. A missão é identificar esses
pontos e entender o impacto deles.
Vamos lá. O primeiro da lista é a obsessão
por tipos primitivos. Sabe aquela coisa de usar tipos
como o streaming ou wint pra tudo?
Até para representar conceitos que tem suas próprias regras,
tipo um CEP ou um e meio usando o som string simples.
Exato. E o interessante aqui não é só o
que a gente faz, mas o que a gente deixa de fazer, né?
Quando você cria uma classe específica, tipo CEP, você ganha
um lugar, um lugar natural para colocar validações formatações,
sabe? As regras de negócio daquele
conceito ficam ali usando só string, essa lógica acaba
espalhada. Repetida.
Repetida, inconsistente, às vezes pelo sistema, a gente
perde a chance de ter um guardião para aquele dado, para
aquele conceito específico. Faz todo o sentido.
Cria uma responsabilidade bem clara ali, né?
E essa ideia de objetos com responsabilidade me leva direto
para outro ponto, objetos mutáveis o material até cita o
Martin Fowler, que vê isso como um codes mel, mas.
Assim, qual é o problema de um objeto poder mudar de estado
depois de criado? Então, a questão central aqui é
a previsibilidade e a segurança. O objeto imutável, depois que
você cria ele não muda mais o estado interno dele.
Pensa na string em Java, por exemplo, métodos como two
apurcase, eles não alteram a string original.
Ah, sim, eles criam uma nova. Né?
Exatamente. Criam e retornam uma nova
string. E isso traz vantagens assim,
enormes objetos imutáveis podem ser compartilhados sem medo
entre diferentes partes do código ou até entre treds, sem
aquele receio de que uma função modifique o estado que a outra
está usando, sabe? Isso simplifica muito o
raciocínio sobre o código, principalmente em sistemas
concorrentes. Entendi AA parte da segurança,
mas e a performance ficar criando objeto novo toda hora?
Isso não pode pesar. É uma troca, né?
Como quase tudo em engenharia de software, em alguns cenários de
altíssima performance, sim, pode ser um fator, mas olha para
maioria dos casos, especialmente para objetos que representam
valores, tipo data, hora e-mail. O próprio CEP que a gente falou.
Os benefícios da clareza da segurança da manutenção
geralmente superam esse custo. E as linguagens os run times
modernos são bem otimizados para isso hoje em dia.
Certo. A recomendação geral é preferir
a imutabilidade, usar recursos como o final em Java pra
atributos e classes sempre que fizer sentido, claro.
Interessante essa prespetiva da troca.
Bom, seguindo nessa linha de objetos e seus papéis classes de
dados, aquelas classes que são basicamente um Monte de
atributos, talvez com gapters e setters, mas quase sem
comportamento próprio, parecem umas sacolas de dados.
Né, exato, tipo isso. E aqui o alerta não é que ela
seja um erro por si só, mas podem ser um sintoma, sabe?
O cheiro aqui levanta a pergunta, será que o
comportamento que opera nesses dados não deveria estar dentro
dessa classe? Hum, muitas vezes a lógica que
manipula os dados de uma classe de dados dessas está espalhada
em outras classes. Então a investigação é dá pra
gente mover essa lógica pra dentro da classe.
Para torná la mais coesa, mais responsável, transformar sacola
num objeto de verdade. É uma mudança de ponto de vista
sobre onde a lógica deveria morar, né?
E por falar em coisas que fazem a gente repensar práticas
comuns, o último ponto de hoje pode surpreender comentários
como colds, mel. Mas como assim comentar o código
não é sempre bom, a gente aprende isso.
É surpreendente mesmo. A referência que o material traz
é de corningham e plauger. Não comente código ruim
reescreva OA ideia não é acabar com todos os comentários, claro,
mas é questionar aqueles que só existem pra explicar um código
confuso. Ah, entendi.
Se um pedaço de código é tão complicado que precisa de um
parágrafo de comentário pra alguém entender?
Talvez o problema seja o próprio código, né?
Então, em. Vez de explicar o que o código
faz, o ideal é que o próprio código deixe isso claro.
Precisamente, a sugestão é refaturar extrair blocos lógicos
para métodos com nomes claros. Descritivos o exemplo no
material é muito bom o método longo com comentários tipo passo
um, passo 2. Uhum ao transformar cada passo
num método tipo executar, passo um, executar, passo 2.
O método original vira só uma sequência de chamadas que se
explicam sozinhas. Aí os comentários originais
ficam redundantes. Claro, comentários que explicam
o porquê de uma decisão de design que não é óbvia ou
documentação de API. Esses continuam super válidos,
certo? O cheiro é daquele comentário
que funciona como muleta para um código que ninguém entende.
Entendido? Bom, recapitulando, então a
gente viu a obsessão por tipos primitivos.
A questão da mutabilidade versus e mutabilidade as classes de
dados e até os comentários como sinais que merecem nossa atenção
no código. São todos assim.
Lembretes importantes de que clareza e manutensabilidade não
acontece ainda Do Nada, né? São resultado de decisões
conscientes de design. Identificar esses cheiros é só o
primeiro passo para a gente investigar, questionar essas
decisões. E quem sabe refaturar, buscando
um código mais robusto, mais compreensível?
Fica a reflexão, então, quanto desses cheiros a gente encontra
no nosso código do dia a dia? E o que eles realmente dizem
sobre nossos hábitos de design? Uma ótima questão pra gente
pensar. Agradecemos a atenção nesta
análise até o próximo episódio.