<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: JaviCoronas</title>
    <description>The latest articles on DEV Community by JaviCoronas (@javcor).</description>
    <link>https://dev.to/javcor</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F735474%2F0300dac3-337b-423c-8d68-4e2374c062e2.png</url>
      <title>DEV Community: JaviCoronas</title>
      <link>https://dev.to/javcor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/javcor"/>
    <language>en</language>
    <item>
      <title>Cómo hacer un merge y no morir en el intento</title>
      <dc:creator>JaviCoronas</dc:creator>
      <pubDate>Sat, 26 Aug 2023 11:56:38 +0000</pubDate>
      <link>https://dev.to/javcor/como-hacer-un-merge-y-no-morir-en-el-intento-4dpe</link>
      <guid>https://dev.to/javcor/como-hacer-un-merge-y-no-morir-en-el-intento-4dpe</guid>
      <description>&lt;p&gt;Si trabajamos en el mundo del desarrollo de software pronto descubriremos que es proceso colaborativo y dinámico que implica la constante evolución de un proyecto a medida que se agregan nuevas funcionalidades y se corrigen errores. Durante este proceso tendremos que afrontar diferentes merges, proceso por el cual se combinan los cambios realizados en diferentes ramas del repositorio en una única versión consolidada. &lt;/p&gt;

&lt;p&gt;Aunque los merges son esenciales para mantener un código base coherente, pueden volverse complicados y desafiantes, especialmente cuando trabajamos en proyectos complejos o nos enfrentamos ante una divergencia entre las ramas.&lt;/p&gt;

&lt;p&gt;En este post, intentaré transmitir el cómo afrontar un difícil merge entre ramas y superar los desafíos asociados. Desde la planificación inicial hasta la resolución de conflictos y las pruebas exhaustivas, todo esto para garantizar que el proceso de merge sea lo más fluido y eficiente posible.&lt;/p&gt;

&lt;p&gt;Afrontar un merge complejo puede parecer un desafío abrumador, pero con las estrategias y consejos adecuados, cualquier equipo de desarrollo puede enfrentar esta tarea con confianza y obtener resultados satisfactorios. ¡Acompáñame en este recorrido para poder afrontar de una mejor manera los infernales merges que a veces nos tocan!&lt;/p&gt;

&lt;h2&gt;
  
  
  Planificación y Comunicación: Preparándonos para un Merge exitoso
&lt;/h2&gt;

&lt;p&gt;Imagina el merge como un proyecto de construcción. Antes de ponernos los cascos, tomar las herramientas y empezar a trabajar... ¡necesitamos un plan sólido y buena comunicación para evitar que todo se convierta en un enredo de piezas!&lt;/p&gt;

&lt;h3&gt;
  
  
  Diseñando nuestro plan de ataque
&lt;/h3&gt;

&lt;p&gt;Es vital tomarnos un momento para planificar. Esto es como trazar un mapa antes de un emocionante viaje: nos ayuda a identificar rutas, puntos de referencia y posibles baches en el camino.&lt;/p&gt;

&lt;p&gt;Pongámonos en contexto: cada rama tiene sus propias adiciones y ajustes. Planificar con anticipación el contexto de cada rama, nos permite comprender qué cambios se están realizando en cada rama, su funcionalidad raiz y cómo interactuaran entre sí cuando se fusionen.&lt;/p&gt;

&lt;h3&gt;
  
  
  El poder de comunicarse
&lt;/h3&gt;

&lt;p&gt;La comunicación es la clave para cualquier relación exitosa. Antes de hacer cualquier movimiento, asegúrate de sincronizar con tus compañeros de equipo. Por suerte en proyectos de software solemos tener un registro completo sobre las diferentes funcionalidades desarrolladas, por quien y cuando se han realizado, pero si hay alguna duda, comunícate. Esto no solo evita sorpresas desagradables, sino que también fomenta un sentido de colaboración y trabajo en equipo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/ulOopdZL6JQ7mB6pTN/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/ulOopdZL6JQ7mB6pTN/giphy.gif" alt="communication" width="364" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  El poder está en tus manos
&lt;/h2&gt;

&lt;p&gt;Entonces, antes de pulsar ese botón de merge, asegúrate de haber trazado un plan, charlado con tus compañeros de equipo y organizado una pequeña fiesta de intercambio de conocimientos. En los cuales tendrás más localizadas las clases implicadas, funcionalidades clave que probar y además al hacerlo, estarás sentando las bases para un merge exitoso y sin estrés (espero).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/aihuG1Li9YrnXkJhpv/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/aihuG1Li9YrnXkJhpv/giphy.gif" alt="button" width="420" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En la próxima sección, exploraremos cómo enfrentar los temidos conflictos que pueden surgir durante un merge y cómo resolverlos como verdaderos héroes del desarrollo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resolución de conflictos: Navegando las aguas turbulentas del Merge
&lt;/h2&gt;

&lt;p&gt;¡Ah, los conflictos! Son como los giros de guión en una película: pueden añadir intriga, pero también pueden generar un dolor de cabeza. Pero no te preocupes, conserva la calma y ten confianza confianza, sabías que iba a pasar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identificando los conflictos de la fiesta del merge
&lt;/h3&gt;

&lt;p&gt;Imagina que estás en una fiesta y dos personas llegan luciendo la misma camisa. ¡Ups! Eso es un conflicto de moda. Del mismo modo, durante un merge, los conflictos pueden surgir cuando dos o más cambios compiten por el mismo pedazo de código. Normalemnte, nos entrentaremos a:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conflictos de código:&lt;/strong&gt; Cuando el mismo fragmento de código ha sido modificado en diferentes ramas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conflictos de archivos:&lt;/strong&gt; Cuando dos ramas han modificado el mismo archivo y es necesario decidir cuál versión mantener.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conflictos de dependencias:&lt;/strong&gt; Cambios que afectan a las mismas dependencias, causando incompatibilidades.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolver como un profesional del Merge
&lt;/h3&gt;

&lt;p&gt;Una vez que has identificado a los invitados no deseados (los conflictos), es hora de actuar. Aquí tienes dos enfoques principales:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resolución manual:&lt;/strong&gt; Este enfoque es como ser un mediador en la fiesta del merge. Revisas cada conflicto uno por uno, tomando decisiones sabias y manteniendo lo mejor de ambas partes. Asegúrate de entender el contexto y el propósito de cada cambio antes de tomar una decisión.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Herramientas de comparación y fusión:&lt;/strong&gt; Sigamos con nuestra metáfora sobre moda. Piensa en esto como tener un asistente que te ayuda a decidir qué atuendo se ve mejor. Herramientas como diff y merge permiten comparar las diferencias entre versiones de código y combinar cambios de manera eficiente. Son especialmente útiles para cambios extensos o cuando los conflictos son difíciles de identificar manualmente. Los propios IDE traen potentes herramientas para facilitarnos esta labor. Úsalas a discreción, pa eso están, Manuel!&lt;/p&gt;

&lt;h3&gt;
  
  
  Tomando decisiones con sensatez
&lt;/h3&gt;

&lt;p&gt;La resolución de conflictos es como un juego de ajedrez: cada movimiento debe ser estratégico. Aquí tienes algunos consejos para tomar decisiones informadas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comprender el propósito:&lt;/strong&gt; Asegúrate de entender el propósito de cada cambio y cómo encaja en el panorama general del proyecto. Si has hecho un estudio previo de las funcionalidades que entran, que salen o que cambian, esto será trabajo de niños.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Considerar el impacto:&lt;/strong&gt; Evalúa cómo cada decisión afectará a otras partes del código y a las funcionalidades existentes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solicitar opiniones:&lt;/strong&gt; Puede que te encuentres con partes del código que no sepas de dónde vienen o para que sirven. No tengas miedo de pedir consejo a compañeros de equipo que han desarrollado esa parte.&lt;/p&gt;

&lt;p&gt;Al abordar los conflictos con paciencia y estrategia, te conviertes en el director de la película, en la que el código se une sin problemas y todos los protagonistas (los cambios) encuentran su lugar perfecto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Realiza todas las pruebas
&lt;/h2&gt;

&lt;p&gt;Estamos deacuerdo en que cualquier proyecto de software implica que debemos trabajar en un pool de pruebas que sea capaz de probar todas nuestras piezas desarrolladas de forma individual (test unitarios) y también seamos capaces de probar funcionalidades completas (test integración).&lt;/p&gt;

&lt;p&gt;En nuestro caso, durante el merge hemos tenido que ajustar estas pruebas. Hemos decidido qué partes pueden quedar obsoletas por los cambios al unir ambas partes y qué partes hay que conservar. Tras esto, no podemos lanzar nuestra película a los espectadores. Debemos repasar cada una de nuestras escenas (funcionalidades) para ser capaces de localizar/arreglar cualquier problema de última hora. Éste proceso es nuestro salvoconducto para que todo funcione como se espera.&lt;/p&gt;

&lt;p&gt;Por lo tanto, con pruebas antes y después del merge, aseguramos que nuestro código y proyecto funcione como se espera.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión: Encarando los Merges con Confianza
&lt;/h2&gt;

&lt;p&gt;Y así, cerramos esta exploración de cómo enfrentar los desafíos de los merges.&lt;/p&gt;

&lt;p&gt;Hemos aprendido que un enfoque planificado y comunicativo es la base para un merge exitoso. La importancia de la planificación detallada y la comunicación destaca que, al trabajar juntos, los equipos pueden convertir incluso los merges más difíciles en un simple avance de nuestro proyecto.&lt;/p&gt;

&lt;p&gt;Compartir es clave. Te animo a compartir tus experiencias y consejos en los comentarios, gracias por leerme!&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>beginners</category>
      <category>programming</category>
      <category>git</category>
    </item>
    <item>
      <title>Usando cache en Springboot</title>
      <dc:creator>JaviCoronas</dc:creator>
      <pubDate>Wed, 27 Jul 2022 12:51:00 +0000</pubDate>
      <link>https://dev.to/javcor/usando-cache-en-springboot-561o</link>
      <guid>https://dev.to/javcor/usando-cache-en-springboot-561o</guid>
      <description>&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;Para ponernos en contexto, a veces en un proyecto necesitamos realizar una serie de llamadas hacia nuestro backend de manera muy recurrente. Además de ello, esta llamada apenas tiene cambios a nivel de base de datos. Es decir, realizamos la llamada y consultamos a la base de datos o a un servicio externo prácticamente lo mismo siempre y por consiguiente recibimos la respuesta una y otra vez. &lt;/p&gt;

&lt;p&gt;Con este contexto, entra en juego el uso de la cache en nuestro servicio, lo que facilita y ahorra de llamadas innecesarias, ganando en rendimiento de manera muy significativa. Por ejemplo, necesitamos el listado de provincias del país. Sabemos que este listado no va a cambiar  pero tampoco queremos ir a nuestra base de datos a pedir cada vez por ellos una vez llamemos a nuestro servicio.&lt;/p&gt;

&lt;p&gt;Por ello, el uso de la cache es un mecanismo para mejorar el rendimiento de nuestro servicio con el uso de la memoria temporal que tiene interna nuestro servicio desplegado. &lt;/p&gt;

&lt;h2&gt;
  
  
  Cache en Springboot
&lt;/h2&gt;

&lt;p&gt;El uso básico de cache en Springboot se puede implementar de manera muy sencilla. En este artículo voy a describir un uso muy sencillo, viendo ya en algo básico como esto un aumento del rendimiento de nuestra aplicación.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uso de la Cache
&lt;/h3&gt;

&lt;p&gt;Para poder empezar a implementar nuestra cache, la anotación que vamos a emplear es @Cacheable, y es la que utilizamos en Spring para marcar las funciones que queremos cachear en memoria. Esto hará que la primera vez invocadas guarden el resultado en memoria y las siguientes veces hagan uso de esa misma memoria.&lt;/p&gt;

&lt;p&gt;Normalmente esto lo desarrollaremos en la capa de Servicio aunque podríamos implementarlo en la capa de repositorio igualmente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    @Cacheable("books")
    override fun getBooks(): List&amp;lt;Book&amp;gt;? {
         println("Service layer. getBooks")
         Thread.sleep(2000L)
         return repo.findAll()
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El nombre que asignamos es importante, ya que es la clave con la que guardamos el resultado en memoria.&lt;/p&gt;

&lt;p&gt;De igual manera podríamos cachear la consulta a un libro específico de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    @Cacheable("book", key = "#id")
    override fun getBookById(id: Long): Book? {
        println("Service layer. getBookById")
        Thread.sleep(2000L)
        return repo.findById(id).orElseGet(null)
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En ambos ejemplos he puesto un sleep de 2 segundos para apreciar los resultados que luego muestro, ya que en un servicio tan básico, la diferencia entre cachear y no cachear seria de poquitos ms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdvoovussjewdz1i5ib3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdvoovussjewdz1i5ib3.gif" alt="GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez marcados nuestros métodos con @Cacheable, sólo habría que marcar nuestra aplicación con @EnableCaching para indicar a Spring que vamos a hacer uso del cache en la aplicación:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootApplication
@EnableCaching
class CacheServiceApplication : CommandLineRunner {
      ......
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y esto es todo... nada más! Así de sencillo quedaría nuestra cache implementada en nuestro servicio. Vamos con las pruebas.&lt;/p&gt;

&lt;p&gt;Realizamos nuestra primera llamada al listado de libros:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxytgsu8bjp2cyrxhgix.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxytgsu8bjp2cyrxhgix.png" alt="Primera llamada a getBooks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vemos como la respuesta la recibimos 2 segundos despues, pero si volvemos a hacerla...magia!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtvbpl6gmdjwl1pjwkbj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtvbpl6gmdjwl1pjwkbj.png" alt="Segunda llamada a getBooks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vemos que ha hecho uso de la cache y la respuesta nos llega en un volado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/fBEMsUeGHdpsClFsxM/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/fBEMsUeGHdpsClFsxM/giphy.gif" alt="Gif_minion"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lo mismo sucede con la llamada a getBookById:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8eeaw407bd9b6rxk2t2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8eeaw407bd9b6rxk2t2.png" alt="Segunda llamada a getBookById"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Y en la segunda llamada:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmmtl3f2ujdsyqarbw40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmmtl3f2ujdsyqarbw40.png" alt="Segunda llamada a getBookById"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;El potencial de esta herramienta es muy grande y hay muchas opciones de configuración con integraciones más complejas, pero ya veis con que poquitas líneas de código Spring nos permite crear una cache en nuestra aplicación que realmente funciona muy bien y con la que podremos ganar mucho rendimiento, aunque hay que saber explotarla y no abusar tampoco ;). &lt;/p&gt;

&lt;p&gt;El código del proyecto podéis encontrarlo &lt;a href="https://github.com/JaviCoronas/cache-spring.git" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hasta la próxima!&lt;/p&gt;

</description>
      <category>spring</category>
      <category>spanish</category>
      <category>kotlin</category>
    </item>
  </channel>
</rss>
