SlideShare una empresa de Scribd logo
1 de 71
Descargar para leer sin conexión
Empowering innovation through collaboration
Código Escalable
Manteniendo buen código
• CTO @ MagmaLabs
• Evangelista de OpenSource
• Conferencista
• Programador por mas de 15 años
• Ha tirado producción
• Trabajado en sitios de alto desempeño y equipos multidisciplinarios, para
clientes tipo: Google, GE, GoPro.
• @softr8 everywhere!
¿Quién soy?
Startups that prioritize feature
velocity over quality tend to survive.
This is deeply offensive to many
software developers.
https://mailchi.mp/railsspeed/on-quality-and-performance-at-early-stage-startups
Que es calidad de código
– Todos los programadores en algún punto
“Mi código es lo mejor del mundo”
• Facilmente extendible
• Pruebas unitarias
• Escrito para humanos, no para computadoras
• Auto-descriptivo
• Fácilmente transferible a otra persona
• Sin mensajes ocultos
Cualidades de un buen código
¿Se puede medir la calidad cuantitativamente?
Claro! Hay herramientas que te ayudan
• Incidentes en Producción
• Tiempo de ideación a liberación
• Código real necesario
• Código ejecutado por las pruebas automatizadas
Métricas para medir calidad del código
• Complejidad ciclomática
• Cuantos caminos de ejecución se crean, mayor numero menor calidad
• Complejidad esencial
• Que tanto código se puede reescribir para eliminar multiples caminos de
ejecución
• Densidad ciclomática
• Radio del numero total de lineas de código entre el numero de puntos de
desiciones lógicas
Métricas para medir calidad del código
• Numero de clases, hasta 6 niveles de herencia
• Número de métodos por clase, no más de 20
• Número de lineas de código por método, no más de 10
• Número de desiciones por método, no más de 2
• Responsabilidades por objeto, solo deben hacer una sola cosa
• Formato de código
Métricas para medir calidad del código
¿Cómo podemos mantener un proyecto en buena
salud?
Mundo real
Readable, maintainable and extendable code
Goal
http://manifesto.softwarecraftsmanship.org/
Técnicas comprobadas.
Code smells
–Martin Fowler
“A code smell is a surface indication that usually
corresponds to deeper problem in the system.”
– Kent Beck
“A code smell is a hint that something has gone wrong
somewhere in your code. Use the smell to track down
the problem.”
• No necesariamente son Bugs
• El código tecnicamente está correcto
• No previenen al código actual de hacer su función
• Síntoma de que pudiera existir areas que generan preocupaciones
Code Smell
“Code smells simplemente indican fallas en el diseño que
pueden alentar el desarrollo y mantenimiento de software.”
• No legible
• Duplicado
• Complejo
• Difícil de modificar
Código Malo
• Facil de:
• Leer
• Entender
• Modificar
Código bueno
Code Smells más comunes
• Una sola clase tratando de hacer demasiado
• Muy general, no aplican el principio de responsabilidad única
• Solución:
• Extraer la clase en funcionalidades aisladas
• Extraer a subclases con polimorfismo
Large Class
Large Classes
• Heredado de programación procedural, utiliza todos los que ocupes!
• Con POO, se reduce la necesidad
• Solución
• Pasar objetos en vez de parámetros
• El objeto pasado es quien tiene toda información
• Quien lo recibe usa solo la información necesaria
Long Parameter List
Long Parameter List
• Una clase cambia en diferentes maneras por diferentes razones
• ¿Pareciera dos objetos en una sola clase?
• Todos los cambios parecen ir a una sola clase?
• Solución:
• Extraer a otra clase
Divergent Change
• Objetos deben empaquetar solo información usada por si mismos
• Objetos muy interesados en datos o métodos de una clase externa en
específico
• Solución:
• Mover metodos
• Regresar objetos en vez de primitivos
Feature Envy
Feature Envy
class Warehouse
def sale_price(item)
item.final_price * @vat
end
end
class Item
def final_price
price - rebate
end
end
• Algunos datos parecen ‘siempre ir’ juntos
• Ejemplos:
• Propiedades en clases
• Mismos parametros en diferentes funciones
• Solución
• Extraer datos comunes en objetos
• Objetos en parametros
• Enviar el objeto completo en vez de dus propiedades
Data Clumps
Data Clumbs
class Dummy
attr_reader :x1, :y1
def initialize(x1, y1)
@x1 = x1
@y1 = y1
end
def x ; x1 * y1 end
def y ; x1 / y1 end
def z ; x1 - y1 end
end
• Codigo muy parecido en multiples lugares
• Externamente no se parece, pero internamente si
• Solución:
• Utility classes
• Herencia
Duplicated Code
• Duplicated Code
• No es código ‘orientado a objetos”
• Se debería usar polimorfismo en su lugar
• Solución:
• Switches representan un ‘tipo’ de código
• Cada ‘tipo’ debería corresponder a una clase
• Factory Pattern
Switch statements
• ¿Pareciera que la clase no tiene porque estar ahi?
• Se planearon cambios a esa clase pero no se necesitaron
• Se encoge cuando se hace refactor
• No pareciera valer la pena
• Solución
• ¿Utility class?
Lazy Class
• No siempre son mala señal
• No se usen como desodorante!
• Refactor este tipo de smell generalmente termina en removiendo el código
• Revisar si el comentario es necesario, si no, removerlo
• Solución:
• Comentar usando formatos estándar de documentación en linea
• Agregar un TODO con criterios cuando se removera
Comments
• Algo anda mal
• No se parece en nada, totalmente fuera de contexto
• Solución:
• Utility Class
Black Sheep
• Generalmente se mezclan abstracciones y llamadas
• Ejecución de código procedural y llamadas a funciones
• Solución
• Estandarizar llamadas a funciones o código procedural
Mixed levels of abstraction
Mixed levels of abstraction
• Una nueva implementación involucra muchas modificaciones en diferentes
lugares
• Firmas de funciones se necesitan ser actualizadas
• Difícil saber que tanto se necesita modificar
• Solución
• Abstraer llamadas en objetos
• Si no se encuentra un buen lugar para mover los objetos, a crearlos!
Shotgun Surgery
• Como su nombre lo indica, se usan boleanos como parámetros
• Solución, eliminarlos desde la llamada
Boolean Parameter
Boolean Parameter
• Variables de uso global
• Difícil encontrar donde se inicializa el valor
• Solución
• Config classes
• Singletons
Class Variable
• Misma condicional usada en multiples lugares
• Causa de una mala implementación de polimorfismo
• Solución:
• Abstracción
• Mejor Polimorfismo
Repeated Conditional
• Acarreándose de diseño original
• No se actualizaron firmas de las funciones
• Solución
• Remover el parametro y todas sus llamadas
• Usar una convención para denotar los parámetros no usados _noUsado
Unused parameters
• Se crearon metodos privados que ya no se utilizan
• Generan carga cognitiva
• Causa de clases grandes
• Solución
• Eliminarlos
Unused Private Methods
• Una función utilitaria es aquella que no necesita almacenar estados para
generar resultados
• Solución
• Crear métodos estáticos
Utility Function
• Escribir código
• Asegurar pruebas verdes
• Pedir revision
• Aceptar comentarios y mejorar el código
• Escoger el área más grave
• Aplicar refactor
Que debemos hacer
¿Como saber por donde empezar?
“Complejidad vs Claridad”
• Presupuesto
• Si no se hace desde un inicio, esta pidiendo un préstamo pagando lo mínimo
• Refactor es abonar pagos al préstamo y bajar la tasa de interés
• No invertir en refactor es aceptar irse al buró de crédito
Se necesita tiempo para mantener buen código
• Linters
• CI
• Pruebas
Tomemos ventaja de más código
CI
magmalabs.io
Gracias!
careers@magmalabs.io
¿Preguntas?
@softr8

Más contenido relacionado

Similar a Codigo Escalable WDT

.NET UY Meetup 4 - AOP & PostSharp by Bruno Bologna & Fabian Fernandez
.NET UY Meetup 4 - AOP & PostSharp by Bruno Bologna & Fabian Fernandez.NET UY Meetup 4 - AOP & PostSharp by Bruno Bologna & Fabian Fernandez
.NET UY Meetup 4 - AOP & PostSharp by Bruno Bologna & Fabian Fernandez
.NET UY Meetup
 
DeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - SpanishDeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - Spanish
Jordi Llonch
 
DeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - SpanishDeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - Spanish
Jordi Llonch
 
DeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - SpanishDeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - Spanish
Akamon Engineering
 
20180313 Keep Calm And Test Your Code RiojaDotNet
20180313 Keep Calm And Test Your Code RiojaDotNet20180313 Keep Calm And Test Your Code RiojaDotNet
20180313 Keep Calm And Test Your Code RiojaDotNet
albertortizcape
 
Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
Alfredo Chavez
 
Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
Retos en la Adopción del Refactoring -  Junta General del MexALN 28/06/2012Retos en la Adopción del Refactoring -  Junta General del MexALN 28/06/2012
Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
Alfredo Chavez
 

Similar a Codigo Escalable WDT (20)

Trabajando con código heredado y ser feliz
Trabajando con código heredado y ser felizTrabajando con código heredado y ser feliz
Trabajando con código heredado y ser feliz
 
Buenas practicas desarrollando software
Buenas practicas desarrollando softwareBuenas practicas desarrollando software
Buenas practicas desarrollando software
 
Python
PythonPython
Python
 
¿A qué huele tu código? Afinando nuestro olfato
¿A qué huele tu código? Afinando nuestro olfato¿A qué huele tu código? Afinando nuestro olfato
¿A qué huele tu código? Afinando nuestro olfato
 
.NET UY Meetup 4 - AOP & PostSharp by Bruno Bologna & Fabian Fernandez
.NET UY Meetup 4 - AOP & PostSharp by Bruno Bologna & Fabian Fernandez.NET UY Meetup 4 - AOP & PostSharp by Bruno Bologna & Fabian Fernandez
.NET UY Meetup 4 - AOP & PostSharp by Bruno Bologna & Fabian Fernandez
 
Probando aplicaciones AngularJS
Probando aplicaciones AngularJSProbando aplicaciones AngularJS
Probando aplicaciones AngularJS
 
DeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - SpanishDeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - Spanish
 
DeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - SpanishDeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - Spanish
 
DeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - SpanishDeSymfonyDay 2014 - To mock or not to mock - Spanish
DeSymfonyDay 2014 - To mock or not to mock - Spanish
 
"Al rico" PHP
"Al rico" PHP"Al rico" PHP
"Al rico" PHP
 
Docker_K8S_lecciones_netcoreconf_2022.pdf
Docker_K8S_lecciones_netcoreconf_2022.pdfDocker_K8S_lecciones_netcoreconf_2022.pdf
Docker_K8S_lecciones_netcoreconf_2022.pdf
 
Principios de diseño de código orientado a objetos SOLID
Principios de diseño de código orientado a objetos SOLIDPrincipios de diseño de código orientado a objetos SOLID
Principios de diseño de código orientado a objetos SOLID
 
Tdd desde las trincheras
Tdd desde las trincherasTdd desde las trincheras
Tdd desde las trincheras
 
20180313 Keep Calm And Test Your Code RiojaDotNet
20180313 Keep Calm And Test Your Code RiojaDotNet20180313 Keep Calm And Test Your Code RiojaDotNet
20180313 Keep Calm And Test Your Code RiojaDotNet
 
Esto es ingeniería inversa
Esto es ingeniería inversaEsto es ingeniería inversa
Esto es ingeniería inversa
 
Inyección de Dependencias: Como inyectar código sin morir de sobre dosis…
Inyección de Dependencias: Como inyectar código sin morir de sobre dosis…Inyección de Dependencias: Como inyectar código sin morir de sobre dosis…
Inyección de Dependencias: Como inyectar código sin morir de sobre dosis…
 
Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
 
Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
Retos en la Adopción del Refactoring -  Junta General del MexALN 28/06/2012Retos en la Adopción del Refactoring -  Junta General del MexALN 28/06/2012
Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
 
Código Limpio
Código LimpioCódigo Limpio
Código Limpio
 
Código Limpio
Código LimpioCódigo Limpio
Código Limpio
 

Más de Edwin Cruz

SGCE 2015 - eCommerce platforms
SGCE 2015 - eCommerce platformsSGCE 2015 - eCommerce platforms
SGCE 2015 - eCommerce platforms
Edwin Cruz
 
Presentacion programador apasionado
Presentacion programador apasionadoPresentacion programador apasionado
Presentacion programador apasionado
Edwin Cruz
 

Más de Edwin Cruz (12)

SGCE 2015 - eCommerce platforms
SGCE 2015 - eCommerce platformsSGCE 2015 - eCommerce platforms
SGCE 2015 - eCommerce platforms
 
Devops with ansible
Devops with ansibleDevops with ansible
Devops with ansible
 
Containers in 5... 9 minutes
Containers in 5... 9 minutesContainers in 5... 9 minutes
Containers in 5... 9 minutes
 
Chilango Rails Ecommerce Lightning talk
Chilango Rails Ecommerce Lightning talkChilango Rails Ecommerce Lightning talk
Chilango Rails Ecommerce Lightning talk
 
Home made ceviche
Home made cevicheHome made ceviche
Home made ceviche
 
Api's and ember js
Api's and ember jsApi's and ember js
Api's and ember js
 
FSL Vallarta, mejorando el rendimiento de las aplicaciones web
FSL Vallarta, mejorando el rendimiento de las aplicaciones webFSL Vallarta, mejorando el rendimiento de las aplicaciones web
FSL Vallarta, mejorando el rendimiento de las aplicaciones web
 
Presentacion Programador Apasionado
Presentacion Programador ApasionadoPresentacion Programador Apasionado
Presentacion Programador Apasionado
 
MagmaRails - Passionate Programmer
MagmaRails - Passionate ProgrammerMagmaRails - Passionate Programmer
MagmaRails - Passionate Programmer
 
Presentacion programador apasionado
Presentacion programador apasionadoPresentacion programador apasionado
Presentacion programador apasionado
 
Api development with rails
Api development with railsApi development with rails
Api development with rails
 
Migrando Rails Apps entre Cloud y Bare Metal Servers
Migrando Rails Apps entre Cloud y Bare Metal ServersMigrando Rails Apps entre Cloud y Bare Metal Servers
Migrando Rails Apps entre Cloud y Bare Metal Servers
 

Codigo Escalable WDT

  • 3.
  • 4. • CTO @ MagmaLabs • Evangelista de OpenSource • Conferencista • Programador por mas de 15 años • Ha tirado producción • Trabajado en sitios de alto desempeño y equipos multidisciplinarios, para clientes tipo: Google, GE, GoPro. • @softr8 everywhere! ¿Quién soy?
  • 5. Startups that prioritize feature velocity over quality tend to survive. This is deeply offensive to many software developers. https://mailchi.mp/railsspeed/on-quality-and-performance-at-early-stage-startups
  • 6. Que es calidad de código
  • 7. – Todos los programadores en algún punto “Mi código es lo mejor del mundo”
  • 8. • Facilmente extendible • Pruebas unitarias • Escrito para humanos, no para computadoras • Auto-descriptivo • Fácilmente transferible a otra persona • Sin mensajes ocultos Cualidades de un buen código
  • 9. ¿Se puede medir la calidad cuantitativamente? Claro! Hay herramientas que te ayudan
  • 10. • Incidentes en Producción • Tiempo de ideación a liberación • Código real necesario • Código ejecutado por las pruebas automatizadas Métricas para medir calidad del código
  • 11. • Complejidad ciclomática • Cuantos caminos de ejecución se crean, mayor numero menor calidad • Complejidad esencial • Que tanto código se puede reescribir para eliminar multiples caminos de ejecución • Densidad ciclomática • Radio del numero total de lineas de código entre el numero de puntos de desiciones lógicas Métricas para medir calidad del código
  • 12. • Numero de clases, hasta 6 niveles de herencia • Número de métodos por clase, no más de 20 • Número de lineas de código por método, no más de 10 • Número de desiciones por método, no más de 2 • Responsabilidades por objeto, solo deben hacer una sola cosa • Formato de código Métricas para medir calidad del código
  • 13.
  • 14.
  • 15.
  • 16.
  • 17. ¿Cómo podemos mantener un proyecto en buena salud?
  • 19. Readable, maintainable and extendable code Goal
  • 23. –Martin Fowler “A code smell is a surface indication that usually corresponds to deeper problem in the system.”
  • 24. – Kent Beck “A code smell is a hint that something has gone wrong somewhere in your code. Use the smell to track down the problem.”
  • 25. • No necesariamente son Bugs • El código tecnicamente está correcto • No previenen al código actual de hacer su función • Síntoma de que pudiera existir areas que generan preocupaciones Code Smell
  • 26. “Code smells simplemente indican fallas en el diseño que pueden alentar el desarrollo y mantenimiento de software.”
  • 27. • No legible • Duplicado • Complejo • Difícil de modificar Código Malo
  • 28. • Facil de: • Leer • Entender • Modificar Código bueno
  • 29. Code Smells más comunes
  • 30. • Una sola clase tratando de hacer demasiado • Muy general, no aplican el principio de responsabilidad única • Solución: • Extraer la clase en funcionalidades aisladas • Extraer a subclases con polimorfismo Large Class
  • 32. • Heredado de programación procedural, utiliza todos los que ocupes! • Con POO, se reduce la necesidad • Solución • Pasar objetos en vez de parámetros • El objeto pasado es quien tiene toda información • Quien lo recibe usa solo la información necesaria Long Parameter List
  • 34. • Una clase cambia en diferentes maneras por diferentes razones • ¿Pareciera dos objetos en una sola clase? • Todos los cambios parecen ir a una sola clase? • Solución: • Extraer a otra clase Divergent Change
  • 35. • Objetos deben empaquetar solo información usada por si mismos • Objetos muy interesados en datos o métodos de una clase externa en específico • Solución: • Mover metodos • Regresar objetos en vez de primitivos Feature Envy
  • 36. Feature Envy class Warehouse def sale_price(item) item.final_price * @vat end end class Item def final_price price - rebate end end
  • 37. • Algunos datos parecen ‘siempre ir’ juntos • Ejemplos: • Propiedades en clases • Mismos parametros en diferentes funciones • Solución • Extraer datos comunes en objetos • Objetos en parametros • Enviar el objeto completo en vez de dus propiedades Data Clumps
  • 38. Data Clumbs class Dummy attr_reader :x1, :y1 def initialize(x1, y1) @x1 = x1 @y1 = y1 end def x ; x1 * y1 end def y ; x1 / y1 end def z ; x1 - y1 end end
  • 39. • Codigo muy parecido en multiples lugares • Externamente no se parece, pero internamente si • Solución: • Utility classes • Herencia Duplicated Code
  • 41. • No es código ‘orientado a objetos” • Se debería usar polimorfismo en su lugar • Solución: • Switches representan un ‘tipo’ de código • Cada ‘tipo’ debería corresponder a una clase • Factory Pattern Switch statements
  • 42.
  • 43. • ¿Pareciera que la clase no tiene porque estar ahi? • Se planearon cambios a esa clase pero no se necesitaron • Se encoge cuando se hace refactor • No pareciera valer la pena • Solución • ¿Utility class? Lazy Class
  • 44. • No siempre son mala señal • No se usen como desodorante! • Refactor este tipo de smell generalmente termina en removiendo el código • Revisar si el comentario es necesario, si no, removerlo • Solución: • Comentar usando formatos estándar de documentación en linea • Agregar un TODO con criterios cuando se removera Comments
  • 45. • Algo anda mal • No se parece en nada, totalmente fuera de contexto • Solución: • Utility Class Black Sheep
  • 46.
  • 47. • Generalmente se mezclan abstracciones y llamadas • Ejecución de código procedural y llamadas a funciones • Solución • Estandarizar llamadas a funciones o código procedural Mixed levels of abstraction
  • 48. Mixed levels of abstraction
  • 49. • Una nueva implementación involucra muchas modificaciones en diferentes lugares • Firmas de funciones se necesitan ser actualizadas • Difícil saber que tanto se necesita modificar • Solución • Abstraer llamadas en objetos • Si no se encuentra un buen lugar para mover los objetos, a crearlos! Shotgun Surgery
  • 50. • Como su nombre lo indica, se usan boleanos como parámetros • Solución, eliminarlos desde la llamada Boolean Parameter
  • 52. • Variables de uso global • Difícil encontrar donde se inicializa el valor • Solución • Config classes • Singletons Class Variable
  • 53. • Misma condicional usada en multiples lugares • Causa de una mala implementación de polimorfismo • Solución: • Abstracción • Mejor Polimorfismo Repeated Conditional
  • 54. • Acarreándose de diseño original • No se actualizaron firmas de las funciones • Solución • Remover el parametro y todas sus llamadas • Usar una convención para denotar los parámetros no usados _noUsado Unused parameters
  • 55. • Se crearon metodos privados que ya no se utilizan • Generan carga cognitiva • Causa de clases grandes • Solución • Eliminarlos Unused Private Methods
  • 56. • Una función utilitaria es aquella que no necesita almacenar estados para generar resultados • Solución • Crear métodos estáticos Utility Function
  • 57. • Escribir código • Asegurar pruebas verdes • Pedir revision • Aceptar comentarios y mejorar el código • Escoger el área más grave • Aplicar refactor Que debemos hacer
  • 58. ¿Como saber por donde empezar?
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66. • Presupuesto • Si no se hace desde un inicio, esta pidiendo un préstamo pagando lo mínimo • Refactor es abonar pagos al préstamo y bajar la tasa de interés • No invertir en refactor es aceptar irse al buró de crédito Se necesita tiempo para mantener buen código
  • 67. • Linters • CI • Pruebas Tomemos ventaja de más código
  • 68. CI
  • 69.
  • 70.