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
- Parte I
- Parte II
- Parte III
- Parte IV
- Parte V
- Parte VI
- Parte VII
- Parte VIII
- Parte IX
- Parte X
- Parte XI
- Parte XII
- Parte XIII
- Parte XIV
- Parte XV
- Parte XVI
- Parte XVII
- Parte XVIII
- Parte XIX
- Parte XX
Continuemos...
Code Smell 101 - Comparación con booleanos
Al comparar con booleanos, realizamos lanzamientos mágicos y obtenemos resultados inesperados.
TL; DR: No compares con la verdad. O eres verdadero o falso o no debes comparar
Problemas
- Fundición oculta
- La violación del principio de la menor sorpresa.
- Violación del principio Fail Fast
Soluciones
- Usar booleanos
- No mezcle booleanos con objetos moldeables booleanos
Contexto
Muchos lenguajes emiten valores a dominios de cruce booleano.
Código de muestra
Equivocado
#!/bin/bash if [ false ]; then echo "True" else echo "False" fi # this evaluates to true since # "false" is a non-empty string if [ false ] = true; then echo "True" else echo "False" fi # this also evaluates to true
Derecha
#!/bin/bash if false ; then echo "True" else echo "False" fi # this evaluates to false
Detección
- [x] Automático
Los linters pueden buscar comparaciones y advertencias explícitas.
Etiquetas
- Fundición
Conclusión
Es una práctica común en la industria utilizar muchos valores no booleanos como valores booleanos. Deberíamos ser muy estrictos al usar booleanos.
Relaciones
Code Smell 69 - Big Bang (Castings ridículos de JavaScript)
Más información
Créditos
Foto de Michael Held en Unsplash
Si no funciona, no importa lo rápido que no funciona.
-Mich Ravera
Código Olor 102 - Código de flecha
Los IF y Els anidados son muy difíciles de leer y probar
TL; DR: Evite los IF anidados. Aún mejor: evite TODOS los IF
Problemas
- Legibilidad
Soluciones
- Método de extracción
- Combinar condiciones booleanas
- Eliminar IF accidentales
Contexto
En el código de procedimiento, es muy común ver ifs anidados complejos. Esta solución está más relacionada con las secuencias de comandos que con la programación orientada a objetos.
Código de muestra
Equivocado
if (actualIndex < totalItems) { if (product[actualIndex].Name.Contains("arrow")) { do { if (product[actualIndex].price == null) { // handle no price } else { if (!(product[actualIndex].priceIsCurrent())) { // add price } else { if (!hasDiscount) { // handle discount } else { // etc } } } actualIndex++; } while (actualIndex < totalCounf && totalPrice < wallet.money); } else actualIndex++; } return actualIndex; }
Derecha
foreach (products as currentProduct) addPriceIfDefined(currentProduct) addPriceIfDefined() { //Several extracts }
Detección
- [x] Automático
Dado que muchos linters pueden analizar árboles, podemos verificar el tiempo de compilación para ver los niveles de anidamiento.
Etiquetas
- Legibilidad
- Complejidad
Conclusión
Siguiendo el consejo del tío Bob , deberíamos dejar el código más limpio de lo que lo encontramos.
Refactorizar este problema es fácil.
Relaciones
Code Smell 78 - Infierno de devolución de llamada
Code Smell 03 - Las funciones son demasiado largas
Code Smell 36 - Declaraciones Switch/case/elseif/else/if
Más información
El propósito de la ingeniería de software es controlar la complejidad, no crearla.
-Pamela Zavé
Code Smell 103 - Doble encapsulación
Llamar a nuestros propios métodos de acceso puede parecer una buena idea de encapsulación. Pero no lo es.
TL; DR: no use setters y getters, incluso para uso privado
Problemas
- Setters
- captadores
- Exponiendo atributos privados
Soluciones
- Eliminar setters
- Quitar captadores
- Protege tus atributos
Contexto
El uso de doble encapsulación era un procedimiento estándar en los años 90.
Queríamos ocultar los detalles de implementación incluso para uso privado.
Esto ocultaba otro olor cuando demasiadas funciones se basan en la estructura de datos y la implementación accidental.
Por ejemplo, podemos cambiar la representación interna de un objeto y confiar en su protocolo externo.
El costo/beneficio no vale la pena.
Código de muestra
Equivocado
contract MessageContract { string message = "Let's trade"; function getMessage() public constant returns(string) { return message; } function setMessage(string newMessage) public { message = newMessage; } function sendMessage() public constant { this.send(this.getMessage()); // We can access property but make a self call instead } }
Derecha
contract MessageContract { string message = "Let's trade"; function sendMessage() public constant { this.send(message); } }
Detección
- [x] Semiautomático
Podemos inferir getters y setters y comprobar si se invocan desde el mismo objeto.
Etiquetas
- Encapsulación
Conclusión
La doble encapsulación era una idea de moda para proteger la implementación accidental, pero exponía más que protegía.
Relaciones
Code Smell 37 - Atributos protegidos
Más información
Créditos
Foto de Ray Hennessy en Unsplash
Encapsular el concepto que varía.
-Erich Gamma
Code Smell 104 - Afirmar verdadero
Afirmar contra booleanos hace que el seguimiento de errores sea más difícil.
TL; DR: no afirme que es verdadero a menos que esté verificando un valor booleano
Problemas
- Principio de fallo rápido
Soluciones
- Compruebe si la condición booleana se puede reescribir mejor
- Favor afirmar Iguales
Contexto
Al afirmar un valor booleano, nuestros motores de prueba no pueden ayudarnos mucho.
Simplemente nos dicen que algo falló.
El seguimiento de errores se vuelve más difícil.
Código de muestra
Equivocado
<? final class RangeUnitTest extends TestCase { function testValidOffset() { $range = new Range(1, 1); $offset = $range->offset(); $this->assertTrue(10 == $offset); // No functional essential description :( // Accidental description provided by tests is very bad } } // When failing Unit framework will show us // // 1 Test, 1 failed // Failing asserting true matches expected false :( // () <-- no business description :( // // <Click to see difference> - Two booleans // (and a diff comparator will show us two booleans)
Derecha
<? final class RangeUnitTest extends TestCase { function testValidOffset() { $range = new Range(1, 1); $offset = $range->offset(); $this->assertEquals(10, $offset, 'All pages must have 10 as offset'); // Expected value should always be first argument // We add a functional essential description // to complement accidental description provided by tests } } // When failing Unit framework will show us // // 1 Test, 1 failed // Failing asserting 0 matches expected 10 // All pages must have 10 as offset <-- business description // // <Click to see difference> // (and a diff comparator will help us and it will be a great help // for complex objects like objects or jsons)
Detección
- [x] Semiautomático
Algunos linters nos advierten si estamos verificando contra booleanos después de establecer esta condición.
Necesitamos cambiarlo a un control más específico.
Etiquetas
- Prueba de olores
Conclusión
Intenta reescribir tus aserciones booleanas y arreglarás las fallas mucho más rápido.
Relaciones
Code Smell 101 - Comparación con booleanos
Code Smell 07 - Variables booleanas
Más información
Créditos
Foto de Joël de Vriend en Unsplash
Finalmente he aprendido lo que significa 'compatible con versiones superiores'. Significa que podemos mantener todos nuestros viejos errores.
-Dennie van Tassel
Code Smell 105 - Métodos del comediante
Use nombres profesionales y significativos
TL;DR: No seas informal ni ofensivo
Problemas
- Legibilidad
- trabajo no profesional
Soluciones
- Elige nombres buenos y profesionales.
Contexto
Nuestra profesión tiene un lado creativo.
A veces nos aburrimos y tratamos de ser graciosos.
Código de muestra
Equivocado
function erradicateAndMurderAllCustomers(); // unprofessional and offensive
Derecha
function deleteAllCustomers(); // more declarative and professional
Detección
- [x] Semiautomático
Podemos tener una lista de palabras prohibidas.
También podemos comprobarlos en revisiones de código.
Los nombres son contextuales, por lo que sería una tarea difícil para un linter automático.
Las convenciones de nombres deben ser genéricas y no deben incluir jerga cultural.
Etiquetas
- Denominación
Conclusión
Sea profesional en la forma en que nombra las cosas en su código.
No intente ser un comediante dándole a una variable un nombre tonto.
Debe escribir el código de producción para que los futuros desarrolladores de software (incluso usted) puedan entenderlo fácilmente.
Relaciones
Code Smell 38 - Nombres abstractos
Más información
Créditos
Foto de Stewart Munro en Unsplash
Esta mentalidad de 'usuarios son idiotas y están confundidos por la funcionalidad' de Gnome es una enfermedad. Si cree que sus usuarios son idiotas, solo los idiotas lo usarán.
-Linus Torvalds
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!