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. Por lo tanto, no es necesario que se arreglen per se... (Sin embargo, debe investigarlo).
Puedes encontrar todos los olores del código anterior (Parte i - XXVIII) aquí.
Continuemos...
¿Alguna vez has visto un IEngine en la naturaleza?
TL;DR: No agregue prefijos ni sufijos a sus clases
Algunos lenguajes tienen convenciones culturales relacionadas con tipos de datos, clases abstractas o interfaces. Estos nombres cargan nuestros modelos con traducciones cognitivas difíciles de seguir.
Debemos BESAR .
public interface IEngine { void Start(); } public class ACar { } public class ImplCar { } public class CarImpl { }
public interface Engine { void Start(); } public class Vehicle { } public class Car { }
Si tenemos un diccionario de sinónimos, podemos señalar nombres extraños.
En C#, es una práctica común poner "I" en el nombre de una interfaz porque, sin ella, no se puede saber si es una interfaz o una clase.
Este es un olor a lenguaje.
Utilice nombres reales para sus modelos.
Code Smell 130 - DirecciónImpl
Foto de Tim Mossholder en Unsplash
Algunas personas, cuando se enfrentan a un problema, piensan “Lo sé, usaré expresiones regulares”. Ahora ellos tienen dos problemas.
jamie zawinski
Grandes citas de ingeniería de software
Acceder a una base de datos en objetos de dominio es un olor a código. Hacerlo en una constructora es un doble olor.
TL; DR: los constructores deben construir (y probablemente inicializar) objetos.
En el código heredado, la base de datos no se separa correctamente de los objetos comerciales.
Los constructores nunca deberían tener efectos secundarios.
De acuerdo con el principio de responsabilidad única, solo deben construir objetos válidos
public class Person { int childrenCount; public Person(int id) { childrenCount = database.sqlCall("SELECT COUNT(CHILDREN) FROM PERSON WHERE ID = " . id); } }
public class Person { int childrenCount; // Create a class constructor for the Main class public Person(int id, int childrenCount) { childrenCount = childrenCount; // We can assign the number in the constructor // Accidental Database is decoupled // We can test the object } }
Nuestros linters pueden encontrar patrones SQL en los constructores y advertirnos.
La separación de preocupaciones es clave, y el acoplamiento es nuestro principal enemigo cuando diseñamos software robusto.
<span>Foto de Callum Hill en Unsplash </span>
Mi creencia sigue siendo que, si obtiene las estructuras de datos y sus invariantes correctamente, la mayor parte del código se escribirá solo.
Pedro Deustch
Grandes citas de ingeniería de software
Algunos objetos siempre están juntos. ¿Por qué no los dividimos?
TL; DR: hacer que los objetos primitivos cohesivos viajen juntos
Este olor es amigo de la obsesión primitiva.
Si se pegan dos o más objetos primitivos, con lógica empresarial repetida y reglas entre ellos, necesitamos encontrar el concepto existente de la biyección .
public class DinnerTable { public DinnerTable(Person guest, DateTime from, DateTime to) { Guest = guest; From = from; To = to; } private Person Guest; private DateTime From; private DateTime To; }
public class TimeInterval { public TimeInterval(DateTime from, DateTime to) { // We should validate From < To From = from; To = to; } } public DinnerTable(Person guest, DateTime from, DateTime to) { Guest = guest; Interval = new TimeInterval(from, to); } // Even Better... public DinnerTable(Person guest, Interval reservationTime) { Guest = guest; Interval = reservationTime; }
La detección basada en patrones de cohesión está disponible en unos pocos linters.
Agrupe el comportamiento en el lugar correcto y oculte los datos primitivos.
Code Smell 122 - Obsesión primitiva
Code Smell 01 - Modelos anémicos
Code Smell 27 - Matrices asociativas
Foto de Dynamic Wang en Unsplash
El corazón del software es su capacidad para resolver problemas relacionados con el dominio para su usuario. Todas las demás características, por vitales que sean, respaldan este propósito básico.
eric evans
Grandes citas de ingeniería de software
Hemos oído hablar mucho de las NFT. Ahora, dominamos el concepto Fungible.
TL;DR: Respeta el MAPPER . Hacer fungible lo que es fungible en el mundo real y viceversa.
Según Wikipedia :
La fungibilidad es la propiedad de un bien o una mercancía cuyas unidades individuales son esencialmente intercambiables y cada una de cuyas partes es indistinguible de otra parte.
En el software podemos sustituir objetos fungibles por otros.
Al mapear nuestros objetos con los reales, a veces nos olvidamos del modelo parcial y construimos sobre el diseño.
public class Person implements Serializable { private final String firstName; private final String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } } shoppingQueueSystem.queue(new Person('John', 'Doe'));
public class Person { } shoppingQueueSystem.queue(new Person()); // The identity is irrelevant for queue simulation
Este es un olor semántico.
Necesitamos entender el modelo para comprobar si es correcto o no.
Hacer fungible lo fungible y viceversa.
Suena fácil pero requiere habilidades de diseño y evitar la complejidad accidental.
Foto de Andrey Metelev en Unsplash
La gente piensa que la informática es el arte de los genios, pero la realidad real es todo lo contrario, solo mucha gente haciendo cosas que se construyen entre sí, como un muro de mini piedras.
donald knuth
No utilice la evaluación booleana como un atajo de legibilidad.
TL; DR: no use la comparación booleana para las funciones de efectos secundarios.
A los programadores inteligentes les gusta escribir código pirateado y oscuro incluso cuando no hay pruebas sólidas de esta mejora.
La optimización prematura siempre perjudica la legibilidad.
userIsValid() && logUserIn(); // this expression is short circuit // Does not value second statement // Unless the first one is true functionDefinedOrNot && functionDefinedOrNot(); // in some languages undefined works as a false // If functionDefinedOrNot is not defined does // not raise an error and neither runs
if (userIsValid()) { logUserIn(); } if(typeof functionDefinedOrNot == 'function') { functionDefinedOrNot(); } // Checking for a type is another code smell
Podemos comprobar si las funciones son impuras y cambiar el cortocircuito a un IF.
Algunos linters reales nos advierten de este problema
No intentes parecer inteligente.
Ya no estamos en los 50.
Sea un desarrollador de equipo.
Code Smell 140 - Evaluación de cortocircuito
Code Smell 06 - Programador demasiado inteligente
Code Smell 149 - Encadenamiento opcional
Foto de Michael Dziedzic en Unsplash
Una computadora es una máquina estúpida con la capacidad de hacer cosas increíblemente inteligentes, mientras que los programadores de computadoras son personas inteligentes con la capacidad de hacer cosas increíblemente estúpidas. Son, en definitiva, una pareja perfecta.
Bill Bryson
Artículo siguiente: 5 olores de código más.