paint-brush
Cómo encontrar las partes apestosas de su código [Parte XXII]por@mcsee
783 lecturas
783 lecturas

Cómo encontrar las partes apestosas de su código [Parte XXII]

por Maximiliano Contieri8m2022/08/29
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

Huele porque es probable que haya muchos casos en los que podría editarse o mejorarse.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Cómo encontrar las partes apestosas de su código [Parte XXII]
Maximiliano Contieri HackerNoon profile picture

Los olores a código son un clásico.

Huele porque es probable que haya muchos casos en los que podría editarse o mejorarse.


La mayoría de estos olores son solo indicios de algo que podría estar mal. No se requieren fijos per se... (Sin embargo, deberías investigarlo).


Olores de código anteriores

Continuemos...


Código Olor 106 - Código dependiente de la producción

No agregue IF para verificar el entorno de producción.

TL; DR: evite agregar condicionales relacionados con la producción

Problemas

  • Violación del principio de fallo rápido
  • Falta de capacidad de prueba

Soluciones

  1. Si es completamente necesario, modele entornos y pruébelos TODOS .

Contexto

A veces, necesitamos crear diferentes comportamientos en el desarrollo y la producción.

Por ejemplo, la fortaleza de las contraseñas.

En este caso, necesitamos configurar el entorno con la estrategia de fuerza y probar la estrategia y no el entorno en sí.

Código de muestra

Equivocado

 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]>

Derecha

 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]>

Detección

  • [x] manuales

Este es un olor de diseño.

Necesitamos crear configuraciones de desarrollo/producción vacías y delegarlas con objetos polimórficos personalizables.

Etiquetas

  • Acoplamiento

Conclusión

Evite agregar condicionales no comprobables.

Crear configuraciones delegando reglas de negocio.

Utilice abstracciones, protocolos e interfaces, evite jerarquías estrictas.

Relaciones

Code Smell 56 - Preprocesadores

Más información

Créditos

Foto de Birmingham Museums Trust en Unsplash

Este tuit fue inspirado por @Jan Giacomelli

Gorjeo


La complejidad es un signo de inmadurez técnica. La simplicidad de uso es el verdadero signo de un producto bien diseñado, ya sea un cajero automático o un misil Patriot.

daniel t ling

Grandes citas de ingeniería de software


Code Smell 107 - Reutilización de variables

La reutilización de variables hace que los alcances y los límites sean más difíciles de seguir

TL; DR: no lea y escriba la misma variable para diferentes propósitos

Problemas

  • Legibilidad
  • Problemas ocultos

Soluciones

  1. No reutilices variables
  2. Método de extracción para aislar ámbitos

Contexto

Al programar un script, es común reutilizar variables.

Esto genera confusión y dificulta la depuración.

Debemos reducir el alcance tanto como sea posible.

Código de muestra

Equivocado

 // 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

Derecha

 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 ); }

Detección

  • [ ] Automático

Linters puede usar el árbol de análisis para encontrar definiciones y usos de variables.

Etiquetas

  • Legibilidad

Conclusión

Evite reutilizar nombres de variables. Use nombres más específicos y diferentes.

Relaciones

Code Smell 03 - Las funciones son demasiado largas

Más información

Refactorización 002 - Método de extracción

Créditos

Foto de Sigmund en Unsplash


Simplicidad antes que generalidad, uso antes que reutilización.

kevlin henney

Grandes citas de ingeniería de software


Code Smell 108 - Afirmaciones flotantes

Afirmar que dos números flotantes son iguales es un problema muy difícil

TL;DR: No compares flotadores

Problemas

  • Resultados de prueba incorrectos
  • Pruebas frágiles
  • Violación del principio de fallo rápido

Soluciones

  1. Evite los flotadores a menos que tenga preocupaciones REALES sobre el rendimiento
  2. Usar números de precisión arbitraria
  3. Si necesita comparar flotadores, compare con la tolerancia.

Contexto

Comparar números flotantes es un viejo problema de informática.

La solución habitual es utilizar comparaciones de umbral.

Recomendamos evitar los flotantes y tratar de usar números de precisión infinitos.

Código de muestra

Equivocado

 Assert.assertEquals(0.0012f, 0.0012f); // Deprecated Assert.assertTrue(0.0012f == 0.0012f); // Not JUnit - Smell

Derecha

 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

Detección

  • [ ] Automático

Podemos agregar una verificación con assertEquals() en nuestros marcos de prueba para evitar la verificación de flotadores.

Etiquetas

  • Prueba de olores

Conclusión

Siempre debemos evitar comparar flotadores.

Relaciones

Code Smell 71 - Flotadores mágicos disfrazados de decimales

Más información

Créditos

Foto de Mika Baumeister en Unsplash


Dios hizo los números naturales; todo lo demás es obra del hombre.

Leopoldo Kronecker

Grandes citas de ingeniería de software


Olfato de código 109 - Propiedades automáticas

¿Qué pasa si combinas 4 olores de código?

TL;DR: Evitar Getters, Evitar Setters, Evitar Metaprogramación. Piensa en el Comportamiento.

Problemas

Soluciones

  1. Eliminar setters y getters automáticos

Contexto

Setters y getters son una mala práctica de la industria.

Muchos IDE favorecen este olor a código.

Algunos lenguajes brindan soporte explícito para construir modelos anémicos y DTO.

Código de muestra

Equivocado

 class Person { public string name { get; set; } }

Derecha

 class Person { private string name public Person(string personName) { name = personName; //imutable //no getters, no setters } //... more protocol, probably accessing private variable name }

Detección

  • [ ] Automático

Esta es una característica del lenguaje.

Debemos evitar lenguajes inmaduros o prohibir sus peores prácticas.

Etiquetas

  • Encapsulación

Conclusión

Necesitamos pensar cuidadosamente antes de exponer nuestras propiedades.

El primer paso es dejar de pensar en propiedades y centrarse únicamente en el comportamiento.

Relaciones

Code Smell 28 - Setters

Code Smell 68 - Captadores

Code Smell 70 - Generadores de modelos anémicos

Código Olfato 40 - DTO

Code Smell 01 - Modelos anémicos

Más información

Créditos

Foto de Kony en Unsplash


No hay nada más difícil que trabajar con un plazo ajustado y aun así tomarse el tiempo para limpiar sobre la marcha.

Kent Beck

Grandes citas de ingeniería de software


Code Smell 110 - Interruptores con valores predeterminados

Predeterminado significa 'todo lo que aún no sabemos'. No podemos prever el futuro.

TL; DR: no agregue una cláusula predeterminada a sus casos. Cámbialo por una excepción. Sea explícito.

Problemas

Soluciones

  1. Reemplazar si y casos con polimorfismo
  2. Cambiar el código predeterminado a una excepción

Contexto

Cuando usamos casos, generalmente agregamos un caso predeterminado para que no falle.

Fallar siempre es mejor que tomar decisiones sin pruebas.

Dado que la caja y los interruptores también son un olor, podemos evitarlos.

Código de muestra

Equivocado

 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; }

Derecha

 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; }

Detección

  • [x] Semiautomático

Podemos decirle a nuestros linters que nos adviertan sobre los usos predeterminados a menos que haya una excepción.

Etiquetas

  • Fallar rapido

Conclusión

Escribir código robusto no significa que debamos tomar decisiones sin evidencia.

Relaciones

Code Smell 36 - Declaraciones Switch/case/elseif/else/if

Más información

Créditos

Foto de Joshua Woroniecki en Unsplash


El costo de agregar una función no es solo el tiempo que toma codificarla. El costo también incluye la adición de un obstáculo para la futura expansión. El truco consiste en elegir las características que no luchan entre sí.

Juan Carmack

Grandes citas de ingeniería de software



Y eso es todo por ahora…

¡El próximo artículo explicará 5 olores de código más!