Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

¿A qué huele tu código? Afinando nuestro olfato

3,256 views

Published on

Repaso por los principales olores de código que podemos encontrar en el desarrollo de software.
Obtenidos a partir del libro "Refactoring: Improving the design of existing code" de Martin Fowler

Published in: Technology
  • (Unlimited)....ACCESS WEBSITE Over for All Ebooks ................ accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M }
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • muy bueno
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • mola!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

¿A qué huele tu código? Afinando nuestro olfato

  1. 1. ¿A qué huele tu código? Afinando nuestro olfato Code Smells Rubén Bernárdez @rubenbpv www.rubenbernardez.com
  2. 2. ¿Qué es un Code Smell?• Son todos los síntomas que podemos encontrar en el código fuente de un sistema que indican que muy probablemente existan problemas más profundos de calidad de código, de diseño o de ambos.• Es difícil definir si el código es malo o bueno, o cuando deberíamos cambiarlo.• Un buen desarrollador tiene el “olfato fino”.
  3. 3. Es VITAL aprender a detectar y reconocer el olor de nuestro propio código
  4. 4. ¿Qué hacer cuando se detecta un ‘Code Smell’? Pero antes, proteger con test automatizados aquella parte de código que se va a modificar. .
  5. 5. ¿Qué es la refactorización?• Refactorizar significa cambiar el código internamente sin alterar su funcionalidad externa. En general, con motivos de mejorar el diseño y obtener un código mas simple.• Refactorización enseña técnicas para descubrir el código de mala calidad y técnicas para cambiarlo.
  6. 6. Code Smells
  7. 7. #0 Código duplicadoDuplicate code• El peor olor de todos, el rey de la pestilencia!• Un código duplicado 5 veces con un bug, es tener 5 bugs en tu software.• Si algún día quieres mejorar lo que hace un código duplicado, tienes que modificar cada parte duplicada de tu código.• Más líneas de código, más probabilidades de error.POSIBLE SOLUCIÓN• Sacar el código duplicado a un método o clase nueva y utilizarlo en todos aquellos lugares que se necesita.
  8. 8. #1 Código muerto• Aparición de código que no se utiliza, probablemente procedente de versiones anteriores, prototipos o pruebas.• También incluye aquel código comentado que se dejó por si alguna día…POSIBLE SOLUCIÓN• Revisar si realmente se debe de usar, sino, borrarlo (para recuperarlo algún día siempre está control de código fuente)
  9. 9. #2 Métodos largosLong method• ¿A quién le gusta un método de decenas o cientos de líneas?• Dificulta muchísimo su compresión• Seguramente estará realizando más de una responsabilidad.• El extraer un trozo de código a un método y llamarlo, no penalizará la velocidad de tu programa.• Tu código es menos reutilizable.POSIBLE SOLUCIÓN• Detectar las diferentes responsabilidades y sacarlas a métodos o clases nuevos.• Antes de ello intentar eliminar variables temporales por querys.
  10. 10. #3 Clases largasLarge class• Ocurre lo mismo que con los métodos largos.• Seguramente esté encargándose de más de una responsabilidad.• La pestilencia nº1 #0 (código duplicado) no estará muy lejos si es que no le ha afectado ya…• Un síntoma es cuando la case tiene demasiados atributos.POSIBLE SOLUCIÓN• Detectar las diferentes responsabilidades y sacarlas a clases nuevas colaboradoras.
  11. 11. #4 Lista larga de parámetrosLong parameter list• Una lista larga de parámetros es difícil de comprender y sin muchos son del mismo tipo, fácil de equivocarte al usar el método.POSIBLE SOLUCIÓN• Encapsular los parámetros relacionados en objetos tipados o reemplazar parámetro por un métodos.• NO usar datos globales sólo para traspasar datos.
  12. 12. #5 Cambios divergentesDivergent Change• Cuando una única clase que tiene que modificarse de diferentes maneras por distintos motivos (más de una responsabilidad).• Esta mala señal indica que la clase no es cohesiva.POSIBLE SOLUCIÓN• Extraer las diferentes responsabilidades a distintas clases.
  13. 13. #6 Cirugía a escopetazosShotgun Surgery• Un determinado tipo de modificación en el sistema lleva repetidamente a la realización de cambios pequeños en muchas clases.• La “cirugía a escopetazos" generalmente implica una sola idea o función lógica distribuida por varias clases.POSIBLE SOLUCIÓN• Trata de corregir ese problema reuniendo todas las partes del código que tienen que modificarse en una única clase cohesiva.• Es recomendable tener algo de “cambios divergentes” que este olor, ya que será más fácil de tratar.
  14. 14. #7 Envidia de característicasFeature Envy• Un método en la ClassA parece más interesado por la ClassB que por su propia clase.• Generalmente la envidia suele venir por los datos de otra clase.• La "envidia" de la ClassA por los recursos de la ClassB es una indicación del acoplamiento fuerte de la ClassA con la ClassB.POSIBLE SOLUCIÓN• Mover la funcionalidad del método de ClassA a ClassB, que ya está más cerca de la mayoría de datos implicados en la tarea.• Si no todo el método tiene “envidia”, extraer a un método el código envidioso y mover sólo ese método a ClassB.
  15. 15. #8 Grupos de datosData Clumps• Uso de un mismo conjunto de variables o propiedades en diferentes lugares en vez de crear una clase apropiada para almacenar los datos, lo que a su vez provoca el incremento de parámetros en métodos y clases.Ejemplo:public void DarDeAltaNuevoCliente( string Public void DarDeAltaNuevoCliente( nombre, string apellido1, string apellido2, string direccion, string Cliente cliente) codigoPostal) {{ ……} }POSIBLE SOLUCIÓN• Aglutinar los parámetros en uno o varios objetos lógicos y pasarlos como nuevos parámetros.
  16. 16. #9 Obsesión por primitivosPrimitive obsession• Muchas personas tienen la obsesión de negarse a utilizar objetos pequeñitos para modelar algunos comportamientos.• Por ejemplo: Un número de teléfono, igual sale más rentable utilizar un objeto pequeñito que modele el comportamiento que tener que lidiar con una cadena de caracteres para modelarlo y tener que parsearla y tratarla.POSIBLE SOLUCIÓN• Crear una nueva clase con los primitivos con algo en común, usa enumerados, subclases o el patrón State o Strategy.
  17. 17. #10 Sentencias switchSwitch statements• La duplicación de código no está lejos con este tipo de sentencias, puedes llegar a verlo varias veces en un mismo sitio. Si añades una condición a un switch en un sitio, tendrás que propagarlo donde se haya repetido.POSIBLE SOLUCIÓN• Generalmente, utilizar polimorfismo.
  18. 18. #11 Jerarquías de herencias paralelasParallel Inheritance Hierarchies• Es un caso especial de la cirugía a escopetazos (shotgun surgery).• Paralelismo que aparece cuando cada vez que se crea una instancia de una clase es necesario crear una instancia de otra clase, evitable uniendo ambas en una única clase final.POSIBLE SOLUCIÓN• Mover los métodos y campos de una jerarquía de objetos a otra para que la jerarquía de objetos referida desaparezca.
  19. 19. #12 Clase perezosaLazy class• Toda clase debe de tener definida una responsabilidad, una razón para existir. Si no es así, ¿para qué sirve esa clase?• Cada clase que crees cuesta dinero para mantenerla y comprenderla.POSIBLE SOLUCIÓN• Una clase sin apenas responsabilidad hay que dotarla de sentido, o bien eliminarla.
  20. 20. #13 Generalización especulativaSpeculative generality• Este olor es bastante general, y siempre comienza por las palabras de: "Algún día necesitaré que ..." o “… por si algún día lo necesito”.• En ese momento suena la señal de alarma. Tienes que tener en cuenta que si vas a montar una infraestructura para hacer cosas complejas, puede ser compleja de comprender y eso tiene un coste también. Si lo vas a tener que utilizar algún día, no te preocupes; no hay plazo que no se cumpla.POSIBLE SOLUCIÓN• Complica tu solución sólo lo necesario y escribe la funcionalidad que te hace falta para tus necesidades actuales y no para las futuras.
  21. 21. #14 Campo temporalTemporary field• Se salta el principio de encapsulamiento y ocultación de variables haciendo que éstas pertenezcan a la clase cuando su ámbito debería ser exclusivamente el método que las usa.POSIBLE SOLUCIÓN• Si una propiedad sólo se una para un par de métodos, conviértela en un parámetro de esos métodos.• Otra alternativa es sacar a una clase nueva los campos y métodos que los usan.
  22. 22. #15 Mensajes encadenadosMessage Chains• Cuando se realiza una cadena de llamadas a métodos de clases distintas utilizando como parámetros el retorno de las llamadas anteriores, como A.getB().getC().getD().getTheNeededData(), que dejan entrever un acoplamiento excesivo de la primera clase con la última.• Cualquier cambio en las relaciones intermedias causa cambios en el cliente.• No se refiere a las API’s fluidas.POSIBLE SOLUCIÓN• Mover los métodos a niveles anteriores o esconder el uso del delegado para minimizar la cadena de llamadas.
  23. 23. #16 IntermediarioMiddle man• Este es quien se ocupa de delegar las llamadas, y simplemente hace eso.• Exploras la clase, y ves que solamente esta llamando a un método y delegando la llamada.• Sin intermediarios y burocracia se vive mucho mejor.• Cuestiona la necesidad de tener clases cuyo único objetivo es actuar de intermediaria entre otras dos clases.POSIBLE SOLUCIÓN• Saltarte al intermediario y usar la clase que implementa la acción directamente. Usar “Inline Method” para unos pocos métodos o convertir el intermediario en una subclase del objeto real.
  24. 24. #17 Intimidad inapropiadaInappropriate intimacy• Se produce cuando dos clases comienzan a conocer demasiados detalles una de otra.POSIBLE SOLUCIÓN• Mover métodos y propiedades de una clase a otra para eliminar la intimidad.• Cambiar la comunicación bidireccional por unidireccionar.• Con clases con intereses comunes, extraer dichos intereses comunes a una clase externa.
  25. 25. #18 Clases alternativas con diferentes interfacesAlternative Classes with Different Interfaces• Indica la ausencia de interfaces comunes entre clases similares.• También aplicable a métodos.• Por ejemplo: CalcularFactura (); y FacturaCalcula(). Es probable que hagan lo mismo, pero sin embargo como eliges uno u otro?.POSIBLE SOLUCIÓN• Esta muy claro que si el código es duplicado, debe ser eliminado y si no, podemos renombrar métodos o utilizar sobrecarga u otros mecanismos que nos ayuden a entenderlo mejor.
  26. 26. #19 Rechazo del legadoRefused bequest• Cuando una subclase rechaza métodos o propiedades heredadas, atentando directamente contra la POO.• Las clases que heredan de otra, heredan sus campos y sus métodos, pero ¿Qué ocurre si no quieren o no necesitan todo lo que se les da?• No importa negar implementaciones, pero si interfaz legada.POSIBLE SOLUCIÓN• Baja los métodos no comunes del padre al hijo que lo necesite para que el padre sólo tenga los métodos comunes.• Elimina la herencia y haz que las clases colaboren.
  27. 27. #20 ComentariosComments• Hay que tener un poco de cuidado al interpretar estas palabras, los comentarios son útiles, pero usados con sabiduría, no como un desodorante para tapar algo que no esta bien hecho (código malo).• En cuanto hayamos mejorado nuestro código y hayamos localizado los olores de nuestro código y los hayamos refactorizado, nos daremos cuenta que muchos de ellos sobran.• TIP: Cuando sientes la necesidad de escribir un comentario, primero trata de refactorizarlo para que cualquier comentario resulte superfluo.POSIBLE SOLUCIÓN• Extraer el trozo de código comentado a un método y darle un buen nombre.• Usa comentarios en zonas que no estés seguro del código o que quieras recordar algo para futuras modificaciones.
  28. 28. Referencias• Refactoring: Improving the Design of Existing Code• Refactoring to Patterns• xUnit Test Patterns: Refactoring Test Code• Smells to refactoring• http://www.refactoring.com

×