Explicando la refactorización: Mejor código a menor coste

18 Apr 2024 10 min (0) Comentarios

Hoy vamos a hablar de uno de los elementos más importantes dentro del ciclo de vida del software, hacer refactorizaciones.

 

 

 

1 - ¿Qué es refactorizar? 

Refactorizar no es más que el proceso de cambiar el código interno de una aplicación sin cambiar su funcionamiento externo, es decir, con los mismos datos de entrada, recibimos los mismos datos de salida. 

 

2 - Por qué debemos refactorizar? 

No debemos refactorizar código simplemente por el hecho de refactorizar, sino que, el objetivo principal es hacer el código más limpio y fácil de mantener. 

Aunque por supuestos podemos tener otros objetivos como son una mejora de rendimiento o costes económicos, que en el entorno de producción real, van a ser los motivos principales.

 

Por poner un ejemplo claro sobre este punto, imagina que tu tenias un endpoint en una API  la cual recibe 10 llamadas por minuto, por el motivo que sea tu aplicación se hace popular, vende más, y ahora son 1000 llamadas por minuto, y ves que dicho endpoint va mucho más lento que antes.

Una de las soluciones aquí es asignar más recursos a la máquina que ejecuta dicha aplicación, y por norma general esto suele funcionar, pero llega un momento en el que mantener la aplicación corriendo puede llegar a costar miles de euros al mes. Así que en ese momento, podemos pasar a refactorizar el código. 

 

Investigando te das cuenta que desde tu microservicio recibes todos los productos (el ID únicamente)  de un carrito de la compra y luego uno por uno consultas en el microservicio de productos; Cuando tenías 10 llamadas por minuto esto no era un problema, pero ahora que tienes 1000 si lo es:

 

Si te fijas, esto es únicamente por cada llamada a nuestro servicio, lo que quiere decir que cada llamada a nosotros realiza 3 en el otro microservicio, con 10 llamdas por minuto estamos realizando 30, pero con 1000 estamos realizando 3000.

Depende como tengas implementada la solucion, este escenario es posible que no tengas hilos suficientes por lo que algunas llamadas se queden esperando, en otras palabras, tengas thread pool starvation del que hablamos en otro post.

 

Una de las posibles soluciones de refactorizar aquí es cambiar ese  bucle for que consulta los productos uno por uno, a simplemente una llamada que pida todos los productos de una sola vez en el microservicio de productos. 

 

Obviamente debemos cambiar el microservicio de productos para que tenga un endpoint disponible para recibir todos los productos y debemos actualizar nuestro código para llamar al nuevo endpoint. 

El cambio, aunque parezca mínimo no lo es, porque estamos quitando carga a dos microservicios y a la red, ya que al cambiar todas las llamadas por una sola, únicamente estamos estableciendo una conexión HTTP entre ambas aplicaciones. 

 

 

3 - Cuándo y cómo refactorizar? 

Lo ideal sería decir que debemos refactorizar siempre, pero la realidad es que dicha afirmación no es realista, y mucho menos es realista en el entorno empresarial donde debemos sacar valor a la empresa.

 

Algo a tener en cuenta es que refactorizar no cambia la salida o la entrada, por lo que es muy difícil vender a nuestros superiores que debemos refactorizar cuando un proyecto ya está corriendo en producción, sobre todo si no tienen conocimientos técnicos, para el director de la emrpesa o los clientes si funciona fnciona, le da igual que sea la última versión de .NET o .NET Framework 1.0

 

Cuando un proyecto ya está en producción, un motivo para refactorizar puede ser cortar costes de ejecución, si nuestra app cuesta 2000€ al mes y después de hacer un análisis evaluamos que va a costar 100€ al mes, es posible que en ese caso sea rentable refactorizar, depende del tiempo que vayamos a tardar.

 

 

Similar a este punto son las migraciones; Depende que tipo de migración estés haciendo puede ser que caigas en tener mucho código duplicado o código muerto (que no se usa después de la migración) lo ideal es planear de antes y crear tareas que tengan que ver con ello, ya que serán aprobadas, pero si cuando todo está terminado dices “ah, podríamos cambiar esto y esto otro y esto otro” lo más probable  es que no suceda nunca.

 

 

También tenemos los casos donde necesitamos una refactorización mientras estamos haciendo la programación, escenarios comunes de estos casos es utilizar nombres de variables que tienen sentido, si tenemos clases o métodos muy largos que hacen demasiadas cosas también podemos intentar re-estructurarlos un poco si es posible.

La idea principal en este tipo de refactorización es la mantenibilidad del código en un futuro.

 

 

4 - Refactorizando mi blog

Refactorizar al final no es más que una parte del ciclo de vida del software; sabéis que a mi me gusta presentar todo con casos de usos reales, y para este escenario tenemos mi blog.

El estado actual de mi blog es el que creé hace unos 5 años y mi forma de ver y entender el software ha cambiado desde entonces.

 

En esta refactorización voy a cambiar dos elementos:

 

4.1 - Refactorizando la estructura

De aquella cree la aplicación del blog con la estructura que vimos en el post de “estructura de una aplicación”; Y si bien pienso que es una buena estructura ya que separa las capas de una forma muy elegante, cuando eres un único desarrollador que quiere sacar la mayor cantidad de funcionalidades posible pues no es la mas idonea. 

La imagen de la izquierda es una captura de pantalla de mi propio backend, donde claramente podemos comprimir la capa de servicios y la capa de serviciosDependencies en una sola; 

 

La capa de serviceDependencies es la que se carga de hablar con la base de datos o con el sistema de correo para enviar los correos con el libro “Guía completa de desarrollo Full stack con .NET” cuando un pago ha sido realizado con éxito.

 

Como digo, en una empresa con empleados puede tener sentido tener esta separación, en mi casa,  yo solo, lo único que hace es aumentar la carga de trabajo. 

 

4.2 - Migrar de Dapper a Entity Framework Core

La segunda parte es la base de datos, hace 5 años decidí utilizar Dapper en vez de Entity Framework Core, esa decisión fue bien al principio, pero en las últimas versiones de .NET entity framework ha mejroado un monton, así que debido a su simplicaidad es lo que voy a implementar, Dapper me gusta, y para ser sincero me va muy bien, pero tener que escribir las consultas de forma manual me cansa un poco y si bien este cambio no es completamente necesario, creo que ha llegado el momento.

Para aquellos interesados, voy a utilizar un enfoque de Database first a la hora de migrar, ya que ya tengo la base de datos creada. 

 

Ambos cambios van a permitir que el desarrollo sea más rápido, que es lo importante.

 

4.3 - Cómo afrontar la refactorización

Llevo dos años con la idea de cambiar esta estructura y por falta de tiempo no lo he hecho, creo que ha llegado el momento, eso si, no va a ser un big bang, voy a ir poco a poco. Migrar a entity framework no tiene mucho misterio, simplemente tengo que crear el DBcontext y los modelos los va a crear el designer automáticamente (más información en el post de database first).

Tanto mi implementación actual como la inclusión del dbcontext pueden correr en paralelo, que es lo que voy a hacer por ahora.

 

Para la migración de los casos de uso/escenarios/servicios, llamalo como quieras lo que voy a hacer es similar. Voy a trabajar con la nueva versión y con la vieja al mismo tiempo. La diferencia es que voy a crear un proyecto nuevo llamado “Workflows” y en este proyecto voy a poner las nuevas implementaciones. 

Esto me va a permitir ir migrando uno a uno cada uno de los escenarios sin la necesidad de hacerlo todos de golpe.

refactorizando código

La realidad es que posiblemente no migre nada o migre muy, muy despacio. Lo que se suele hacer es, si no lo tienes que tocar, no migras, mientras que si tienes que hacer un cambio aprovechas y migras esa sección.

Eso sí, todo lo nuevo que vaya creando lo voy a crear en la capa de casos de uso, y las dependencias como puede ser la base de datos o el servidor de correo los inyecte en dicho caso de uso y ya está.

 

 

Al final lo que busco es una mayor velocidad a la hora de desarrollar y sacar funcionalidades.

Uso del bloqueador de anuncios adblock

Hola!

Primero de todo bienvenido a la web de NetMentor donde podrás aprender programación en C# y .NET desde un nivel de principiante hasta más avanzado.


Yo entiendo que utilices un bloqueador de anuncios como AdBlock, Ublock o el propio navegador Brave. Pero te tengo que pedir por favor que desactives el bloqueador para esta web.


Intento personalmente no poner mucha publicidad, la justa para pagar el servidor y por supuesto que no sea intrusiva; Si pese a ello piensas que es intrusiva siempre me puedes escribir por privado o por Twitter a @NetMentorTW.


Si ya lo has desactivado, por favor recarga la página.


Un saludo y muchas gracias por tu colaboración

© copyright 2024 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café