A maioria desses cheiros são apenas indícios de algo que pode estar errado. Eles não são necessariamente consertados per se ... (Você deve investigar isso.)
Não adicione IFs verificando o ambiente de produção.
TL;DR: Evite adicionar condicionais relacionados à produção
def send_welcome_email(email_address, environment): if ENVIRONMENT_NAME == "production": print(f"Sending welcome email to {email_address} from Bob Builder <[email protected]>") else: print("Emails are sent only on production") send_welcome_email("[email protected]", "development") # Emails are sent only on production send_welcome_email("[email protected]", "production") # Sending welcome email to [email protected] from Bob Builder <[email protected]>
class ProductionEnvironment: FROM_EMAIL = "Bob Builder <[email protected]>" class DevelopmentEnvironment: FROM_EMAIL = "Bob Builder Development <[email protected]>" # We can unit test environments # and even implement different sending mechanisms def send_welcome_email(email_address, environment): print(f"Sending welcome email to {email_address} from {environment.FROM_EMAIL}") # We can delegate into a fake sender (and possible logger) # and unit test it send_welcome_email("[email protected]", DevelopmentEnvironment()) # Sending welcome email to [email protected] from Bob Builder Development <[email protected]> send_welcome_email("[email protected]", ProductionEnvironment()) # Sending welcome email to [email protected] from Bob Builder <[email protected]>
Code Smell 56 - Pré-processadores
A complexidade é um sinal de imaturidade técnica. Simplicidade de uso é o sinal real de um produto bem projetado, seja um ATM ou um míssil Patriot.
Daniel T. Ling
Grandes Citações de Engenharia de Software
A reutilização de variáveis torna os escopos e limites mais difíceis de seguir
TL;DR: Não leia e escreva a mesma variável para propósitos diferentes
// print line total double total = item.getPrice() * item.getQuantity(); System.out.println("Line total: " + total ); // print amount total total = order.getTotal() - order.getDiscount(); System.out.println( "Amount due: " + total ); // variable is reused
function printLineTotal() { double total = item.getPrice() * item.getQuantity(); System.out.println("Line total: " + total ); } function printAmountTotal() { double total = order.getTotal() - order.getDiscount(); System.out.println( "Amount due: " + total ); }
Cheiro de código 03 - as funções são muito longas
Refatoração 002 - Método Extrair
Simplicidade antes da generalidade, uso antes da reutilização.
Kevlin Henney
Grandes Citações de Engenharia de Software
Afirmar que dois números float são iguais é um problema muito difícil
TL;DR: Não compare floats
Assert.assertEquals(0.0012f, 0.0012f); // Deprecated Assert.assertTrue(0.0012f == 0.0012f); // Not JUnit - Smell
Assert.assertEquals(0.0012f, 0.0014f, 0.0002); // true Assert.assertEquals(0.0012f, 0.0014f, 0.0001); // false // last parameter is the delta threshold Assert.assertEquals(12 / 10000, 12 / 10000); // true Assert.assertEquals(12 / 10000, 14 / 10000); // false
Podemos adicionar uma verificação com assertEquals() em nossas estruturas de teste para evitar a verificação de flutuações.
Code Smell 71 - Flutuadores Mágicos Disfarçados de Decimais
Deus fez os números naturais; tudo o mais é obra do homem.
Leopold Kronecker
Grandes Citações de Engenharia de Software
O que acontece se você combinar 4 code smells?
TL;DR: Evite getters, evite setters, evite metaprogramação. Pense no Comportamento.
class Person { public string name { get; set; } }
class Person { private string name public Person(string personName) { name = personName; //imutable //no getters, no setters } //... more protocol, probably accessing private variable name }
Code Smell 70 - Geradores de modelos anêmicos
Cheiro de Código 01 - Modelos Anêmicos
Nada é mais difícil do que trabalhar com um prazo apertado e ainda reservar um tempo para limpar enquanto trabalha.
Kent Beck
Grandes Citações de Engenharia de Software
Padrão significa 'tudo o que ainda não sabemos'. Não podemos prever o futuro.
TL;DR: Não adicione uma cláusula padrão aos seus casos. Altere-o para uma exceção. Seja explícito.
Como o gabinete e os interruptores também são um cheiro, podemos evitá-los.
switch (value) { case value1: // if value1 matches the following will be executed.. doSomething(); break; case value2: // if value2 matches the following will be executed.. doSomethingElse(); break; default: // if value does not presently match the above values // or future values // the following will be executed doSomethingSpecial(); break; }
switch (value) { case value1: // if value1 matches the following will be executed.. doSomething(); break; case value2: // if value2 matches the following will be executed.. doSomethingElse(); break; case value3: case value4: // We currently know these options exist doSomethingSpecial(); break; default: // if value does not match the above values we need to take a decision throw new Exception('Unexpected case ' + value + ' we need to consider it'); break; }
Cheiro de código 36 - instruções switch/case/elseif/else/if
O custo de adicionar um recurso não é apenas o tempo necessário para codificá-lo. O custo também inclui a adição de um obstáculo à expansão futura. O truque é escolher os recursos que não lutam entre si.
John Carmack
Grandes Citações de Engenharia de Software