Jekyll2017-11-21T09:31:27-05:00http://blog.nicolaswebdev.com/NicolasWebDev BlogBlog de un francés viviendo en Quito, Ecuador. Escribo sobre todo lo que encuentro en mi camino como desarrollador web y como consultor.
Migrar una aplicación monolítica a una arquitectura de microservicios2017-11-21T00:00:00-05:002017-11-21T00:00:00-05:00http://blog.nicolaswebdev.com/2017/11/21/migrate-from-monolith-to-microservices<h2 id="introducción">Introducción</h2>
<p>Para seguir con mi serie de artículos sobre la arquitectura de microservicios, hoy te voy a presentar como puedes migrar una aplicación monolítica a una arquitectura de microservicios.</p>
<p>Lo más importante es saber reconocer los <em>contextos limitados</em> de tu aplicación. Una vez que definiste uno, puedes empezar a migrarlo a un microservicio.</p>
<h2 id="la-importancia-de-los-contextos-limitados">La importancia de los <em>contextos limitados</em></h2>
<p>Una diferencia importante entre la arquitectura de microservicios y las arquitecturas orientadas a servicios (<a href="https://es.wikipedia.org/wiki/Arquitectura_orientada_a_servicios">SOA</a>) tradicionales, es que la frontera entre los diferentes servicios tienen que respetar los <em>contextos limitados</em> (<a href="https://martinfowler.com/bliki/BoundedContext.html"><em>Bounded Contexts</em></a>). La idea de los <em>contextos limitados</em> es que cada servicio tenga una responsabilidad del mundo real y tenga una interfaz explicita.</p>
<p>Si en lugar de separar tus servicios por <em>contextos limitados</em> decides separar por <em>contextos tecnológicos</em>, seguramente vas a tener problemas. Por ejemplo separar el <em>backend</em>, el <em>frontend</em> y la base de datos de tu aplicación y tener un equipo para cada uno requiere para cada cambio comunicación entre los equipos, lo que hace perder tiempo a todo el mundo.<br />
En la arquitectura de microservicios en cambio, cada servicio está responsable de toda una funcionalidad, desde la base de datos hasta el sitio web.</p>
<p>Es la diferencia entre un corte horizontal y un corte vertical. En lugar de tener un equipo de <em>frontend</em>, un equipo de <em>backend</em> y un equipo de base de datos, se trata de tener un equipo de un servicio inventario y un equipo de un servicio de ventas, cada equipo incluyendo personas de <em>frontend</em>, de <em>backend</em> y de base de datos.</p>
<p><img src="/assets/snowman_vs_traditional.png" alt="Comparación entre los dos cortes" /></p>
<p><img src="/assets/traditional_architecture.png" alt="Corte horizontal" style="width: 50%; float: left;" /></p>
<p><img src="/assets/snowman_architecture.png" alt="Corte vertical" style="width: 50%;" /></p>
<div style="text-align: center;">
<small><a href="http://simplearchitectures.blogspot.com/2012/09/snowman-architecture-part-one-overview.html">Comparación entre los cortes vertical y horizontal.</a></small>
</div>
<p>Pero saber reconocer estos <em>contextos limitados</em> es un arte difícil que viene con la experiencia.</p>
<h2 id="con-cual-primer-microservicio-empezar">Con cual primer microservicio empezar</h2>
<p>Netflix empezó su primer microservicio con una funcionalidad que no era critica para el sistema: su <a href="https://jobs.netflix.com/jobs">portal de empleo</a>. Es decir la página que tenían en su sitio web para proponer puestos de trabajo en Netflix. Esta funcionalidad no era critica en el sentido que si el portal no funciona durante una hora, es grave, pero no impacta Netflix en su actividad principal que es el <em>streaming</em> de vídeo.</p>
<p>Este patrón es muchas veces recomendado como una buena manera de empezar con los microservicios: escoger dentro de su aplicación monolítica una funcionalidad bien definida, chiquita y que no sea critica, y extraerle en su propio microservicio.</p>
<p>Una vez que el equipo ya tiene experiencia con su primer microservicio, se puede concentrar en buscar una segunda funcionalidad quizás un poco más importante y pasarla a un microservicio.</p>
<p>Repites este proceso hasta que tu aplicación ya no sea monolítica, pero más bien esté compuesta por microservicios.</p>
<p><img src="/assets/strangler_vines.jpg" alt="Vides estranguladoras" />
Este patrón se llama <em>the strangler pattern</em>, el patrón estrangulador, porque como vides estranguladoras que crecen y terminan matando al árbol huésped, los microservicios crecen poco a poco y reemplazan la aplicación monolítica. Puedes encontrar más detalles en <a href="https://www.ibm.com/developerworks/cloud/library/cl-strangler-application-pattern-microservices-apps-trs/index.html">este articulo (en inglés)</a>.</p>
<p>Lo peor que puedas decidir hacer es pasar tu aplicación monolítica a una arquitectura de microservicios en un solo paso, haciendo todo al mismo tiempo. Eso sin duda te va a dar muchos problemas y te va a costar mucho tiempo y trabajo. Siempre cuando sea posible, cualquier cambio a una aplicación que ya esté en producción se debería hacer de manera progresiva.</p>
<h2 id="conclusión">Conclusión</h2>
<p>Vimos como se debe abordar una migración de un sistema monolítico a una arquitectura de microservicios, para reducir lo más posible los riesgos relacionados a este proceso. Puedes intentar con un microservicio chiquito para darte cuenta de los esfuerzos necesarios y de allí decidir si decides seguir implementando esta arquitectura, o si en cambio los costos son demasiado altos para justificar este trabajo.</p>
<p>Si ya estás decidido a intentarlo, te recomiendo mucho el libro <a href="https://www.amazon.com/Building-Microservices-Designing-Fine-Grained-Systems/dp/1491950358"><em>Building Microservices: Designing Fine-Grained Systems</em></a>, de Sam Newman, que es la referencia sobre el tema.</p>
<p>¡Como siempre, si tienes una pregunta, déjame un comentario y intentaré ayudarte!</p>Introducción Para seguir con mi serie de artículos sobre la arquitectura de microservicios, hoy te voy a presentar como puedes migrar una aplicación monolítica a una arquitectura de microservicios.Beneficios y costos de la arquitectura de microservicios y en qué casos usarla2017-11-07T00:00:00-05:002017-11-07T00:00:00-05:00http://blog.nicolaswebdev.com/2017/11/07/when-to-use-microservices<h2 id="introducción">Introducción</h2>
<p>En mi último artículo hice una presentación muy rápida de lo que es la arquitectura de microservicios. En el artículo de hoy, vamos a entrar en más detalles.</p>
<p>Vamos en un primer paso enumerar los beneficios y los costos que tiene esta arquitectura, para analizar en qué contextos tiene sentido usarla.</p>
<h2 id="los-beneficios">Los beneficios</h2>
<p>Unos de los beneficios de la arquitectura de microservicios:</p>
<ul>
<li><strong>permite una programación políglota</strong>: los microservicios pueden estar escritos en diferentes lenguajes de programación según la necesidad. Si un microservicio necesita mucha velocidad, lo puedes escribir en <a href="https://es.wikipedia.org/wiki/Rust_(lenguaje_de_programaci%C3%B3n)">Rust</a> o en <a href="https://es.wikipedia.org/wiki/Go_(lenguaje_de_programaci%C3%B3n)">Go</a>, en caso contrario lo puedes escribir a un alto nivel de abstracción usando <a href="https://es.wikipedia.org/wiki/Ruby">Ruby</a>, <a href="https://es.wikipedia.org/wiki/Python">Python</a> o <a href="https://es.wikipedia.org/wiki/Node.js">Node.js</a>. Naturalmente, no es aconsejable usar diez lenguajes de programación diferentes para diez microservicios, porque va a agregar mucha complejidad en tu organización.</li>
<li><strong>más fácil de escalar la aplicación</strong>: porque se pueden escalar los microservicios más solicitados (que forman el cuello de botella) sin tener que escalar toda la aplicación. Por ejemplo cada microservicio podría usar una máquina virtual, mientras el más solicitado se puede escalar sobre más máquinas. Esto resulta en costos menores de alojamiento.</li>
<li><strong>más fácil de entender</strong>: los microservicios son más fáciles de entender individualmente, porque cada microservicio tiene una función precisa y es bastante independiente. Algunas personas aconsejan que un microservicio se debería poder reescribir desde cero en menos de dos semanas.</li>
<li><strong>más robustez</strong>: la aplicación puede seguir funcionando aunque un microservicio no critico haya fallado. Por ejemplo en la tienda de Amazon la funcionalidad de recomendaciones de otros productos está implementada usando un microservicio. En caso de que falle este microservicio, las recomendaciones no aparecen en el sitio web, pero la venta que es el corazón de Amazon sigue funcionando sin que muchos usuarios se den cuenta del problema.</li>
<li><strong>se acopla mejor con la estructura de la organización</strong>: en el contexto de empresas muy grandes, cada equipo se encarga totalmente de un microservicio: la arquitectura, el diseño, la operación, el despliegue etc. Esto ayuda mucho a tener más independencia entre los equipos y evitar tener que solicitar varios equipos diferentes para sacar una nueva funcionalidad, resultando en una empresa mucho más ágil. Según la <a href="https://es.wikipedia.org/wiki/Ley_de_Conway">Ley de Conway</a>, los microservicios permiten tener una mejor estructura en tu organización que facilita la comunicación.</li>
</ul>
<p>Últimamente la arquitectura de microservicios está muy de moda, porque la mayoría de las empresas grandes las están implementando. Podríamos pensar que todos esos beneficios y el hecho que las empresas lideres lo estén usando justifica que usemos esta arquitectura todo el tiempo, ¿no cierto?</p>
<h2 id="los-costos">Los costos</h2>
<p>Resulta que la arquitectura de microservicios también tiene muchos costos. Estos son unos de los más importantes:</p>
<ul>
<li><strong>mayor complejidad de operación</strong>: con un monolito, cada vez que despliegues, despliegues solamente un servicio. Ahora, imagina que tienes que desplegar 5 microservicios. Seguramente el esfuerzo necesario va a aumentar drásticamente. Si no tienes todos tus procesos de operación automatizados, desde el despliegue hasta la creación y el mantenimiento de tu infraestructura de alojamiento, vas a perder mucho tiempo configurando todos los servidores que necesitas y comprobar que siguen funcionando.</li>
<li><strong>difícil de cambiar las junturas entre los servicios</strong>: si usaste microservicios demasiado temprano en tu aplicación y te das cuenta que no definiste bien sus fronteras, puede resultar muy costoso arreglar este error. En algunos casos es aconsejable juntar todos los microservicios en un monolito, arreglar las cosas allí para después definir mejores microservicios una vez que sus responsabilidades estén mejor definidas.</li>
<li><strong>más difícil de depurar</strong>: si hay un defecto en tu microservicio de pagos, puede ser que esto resulte en un error en otro microservicio. Es mucho más difícil rastrear de dónde viene el problema cuando usas microservicios. ¿Cómo juntar los logs de los microservicios, para encontrar la causa de un error?</li>
<li><strong>problemas de sistemas distribuidos</strong>: varios de los puntos ya mencionados tienen que ver con la complejidad inherente al trabajar con sistemas distribuidos. Hasta ahora los sistemas distribuidos es un campo en lo cual se hace mucha investigación. ¿Qué pasa si un microservicio falla, hace fallar a los otros microservicios? ¿Cómo rastrear una transacción lógica que necesita varios microservicios? ¿Cómo hacer un <a href="https://es.wikipedia.org/wiki/Rollback"><em>rollback</em></a> a la misma? ¿Cómo saber si el microservicio falló, o si solamente se demora en responder? ¿Cómo setear los diferentes <em>timeouts</em>? ¿Cómo estar seguro que los datos de tus microservicios estén sincronizados?</li>
</ul>
<p>Por el hecho que la arquitectura de microservicios no sea una <a href="https://es.wikipedia.org/wiki/No_hay_balas_de_plata"><strong>bala de plata</strong></a>, es decir una solución a todos los problemas del desarrollo, veamos ahora en qué casos tiene sentido implementarla.</p>
<h2 id="cuando-usar-microservicios">Cuando usar microservicios</h2>
<p>Todos los beneficios presentados arriba se vuelven muy importantes cuando la aplicación tiene una complejidad alta. Si no, los costos resultan más importantes que los beneficios.<br />
El gráfico que sigue resume muy bien este concepto: la arquitectura de microservicios tiene sentido para proyectos avanzados y bastante complejos.</p>
<p><img src="/assets/graph_of_microservices_cost.png" alt="El costo de la arquitectura de microservicios según la complejidad del proyecto" />
<small>El costo de la arquitectura de microservicios según la complejidad del proyecto. <a href="https://martinfowler.com/bliki/MicroservicePremium.html">Del blog de Martin Fowler</a>.</small></p>
<p>Según el criterio de Martin Fowler, durante su charla en la <a href="https://xconf-la.com/">XConf Latinoamérica</a> en Quito este último 30 de septiembre, un equipo de desarrollo de menos de 12 personas seguramente no necesita una arquitectura de microservicios.</p>
<p>Es de mi opinión que en Ecuador pocas empresas desarrollan aplicaciones que tengan la complejidad necesaria para justificar el uso de una arquitectura de microservicios. Así que si estás trabajando en una empresa no muy grande y que están pensando en implementar microservicios, porque es un concepto que está de moda, ¡piénsenlo dos veces!</p>
<h2 id="tiene-sentido-empezar-un-nuevo-proyecto-con-microservicios">¿Tiene sentido empezar un nuevo proyecto con microservicios?</h2>
<p>Una pregunta que seguramente tienes, es si tiene sentido empezar un nuevo proyecto con microservicios desde un principio.</p>
<p>Primer punto, como vimos arriba, si la aplicación nunca va a tener la complejidad necesaria o el equipo va a ser muy grande, entonces no debería ser interesante usar la arquitectura de microservicios.</p>
<p>¿Pero qué pasa si sabes que en el futuro vas a necesitarlo, porque tienes requerimientos precisos de pasar a escala o que sabes que la aplicación va a ser muy complicada? ¿En este caso no deberías empezar desde un principio usando la arquitectura de microservicios?</p>
<p>De todo lo que leí hasta ahora, es <strong>aconsejado siempre empezar con un monolito</strong>.</p>
<p><strong>La primera razón</strong> es que al principio del proyecto y siguiendo la metodología ágil, quieres sacar un <em>MVP</em> (Producto Mínimo Viable) al mercado lo <strong>más rápidamente posible</strong>. Empezar implementando una arquitectura de microservicios tiene un costo de operación alto que va a atrasar tu avance, atrasando el <em>TTM</em> (<em>Time To Market</em>, el plazo de lanzamiento).</p>
<p><strong>La segunda razón</strong> y quizás la más importante, es que si te equivocas en dónde separar tus microservicios, arreglarlo va a ser muy costoso. Por esta razón se aconseja crear un microservicio solamente cuando tienes una idea muy precisa de cual va a ser su <em>contexto limitado</em> (<a href="https://martinfowler.com/bliki/BoundedContext.html"><em>Bounded Context</em></a>). La idea de los <em>contextos limitados</em> es que cada servicio tenga una responsabilidad del mundo real y una interfaz explicita.
<strong>Una vez que tus microservicios están definidos, pasar código del uno al otro es algo muy complicado</strong>, mucho más complicado si quieres pasar código de un lado al otro dentro de un monolito.</p>
<p><img src="/assets/bounded_contexts.jpeg" alt="Un ejemplo de *contextos limitados*" />
<small>Un ejemplo de <em>contextos limitados</em>. <a href="https://hackernoon.com/microservices-bounded-context-cohesion-what-do-they-have-in-common-1107b70342b3">Referencia</a>.</small></p>
<p>Para más detalles sobre los argumentos de empezar con un monolito, te aconsejo leer este <a href="https://martinfowler.com/bliki/MonolithFirst.html">excelente artículo de Martin Fowler</a>.</p>
<h2 id="conclusión">Conclusión</h2>
<p>La arquitectura de microservicios sin duda tiene muchas ventajas en algunos contextos y se volvió muy famosa por el hecho que una mayoría de las empresas grandes de Norte-América estén migrando a ella. En particular permite a un producto escalar a totalmente otros niveles, lo que es una ventaja muy importante en la <a href="https://es.wikipedia.org/wiki/Silicon_Valley">Sillicon Valley</a> donde cualquier <em>startup</em> se puede volver el próximo Facebook en pocos meses.</p>
<p>Sin embargo es importante resistir al efecto de moda y interesarse de cerca a la viabilidad de una arquitectura de microservicios en el contexto de tu empresa para no terminar en más problemas.</p>
<p>A pesar de esta advertencia, la arquitectura de microservicios es algo muy interesante y usa muchos conceptos que pueden traerte muchos beneficios si les implementas individualmente.</p>Introducción En mi último artículo hice una presentación muy rápida de lo que es la arquitectura de microservicios. En el artículo de hoy, vamos a entrar en más detalles.Presentación de la arquitectura de microservicios2017-10-24T00:00:00-05:002017-10-24T00:00:00-05:00http://blog.nicolaswebdev.com/2017/10/24/presentation-of-microservices-arquitecture<h2 id="introducción">Introducción</h2>
<p>Justo empecé a trabajar en la empresa <a href="http://www.ziembra.com/">Ziembra</a>, para crear una versión 2 de la plataforma <a href="http://kudert.com/site-kudert/index-kudert.html">Kudert</a> desde cero, usando el <em>stack</em> <a href="https://www.mongodb.com/blog/post/the-modern-application-stack-part-1-introducing-the-mean-stack">MERN</a> (Mongodb/Express/React/Node), es decir todo en Javascript.</p>
<p>Una de las preguntas al principio del proyecto, era decidir si íbamos a crear la arquitectura del proyecto usando <a href="https://es.wikipedia.org/wiki/Arquitectura_de_microservicios">microservicios</a> o no. La arquitectura de microservicios ya está muy de moda y muchas empresas quieren implementarla.</p>
<p>Ahora que investigue bastante el tema, te voy a presentar en este post qué es la arquitectura de microservicios.</p>
<h2 id="qué-es-la-arquitectura-de-microservicios">Qué es la arquitectura de microservicios</h2>
<p>Tradicionalmente, la arquitectura de las aplicaciones es monolítica, es decir que nuestra aplicación está compuesta por un solo programa que usa una base de datos.</p>
<p>La arquitectura de microservicios en cambio, se caracteriza por modularizar las aplicaciones en muchos programas diferentes que comunican entre sí, para en conjunto cumplir con los requerimientos del sistema. Cada microservicio se encarga de implementar un componente de la aplicación entera. Se llaman microservicios, para comunicar la idea que son muchos servicios pequeños que conversan. Usualmente la comunicación se hace con <a href="https://es.wikipedia.org/wiki/Transferencia_de_Estado_Representacional">REST</a>.</p>
<p><img src="/assets/microservices.png" alt="Diferencia monolito/microservicios" /></p>
<p><small>Cada color representa una funcionalidad diferente. En la arquitectura de microservicios, cada funcionalidad está implementada por un microservicio.</small></p>
<p><strong>La regla de oro de los microservicios</strong>, es que siempre sea posible hacer un cambio a un microservicio y desplegarlo de <strong>manera independiente</strong>, sin afectar el resto de la aplicación (los otros microservicios). Si ese no es el caso y que los microservicios no son independientes en su ciclo de vida, quiere decir que están acoplados entre sí y la mayoría de los beneficios de la arquitectura se pierden.</p>
<h2 id="un-ejemplo-de-uso-de-microservicios">Un ejemplo de uso de microservicios</h2>
<p>Tomando Netflix como ejemplo, podríamos imaginar que tengan un microservicio diferente para:</p>
<ul>
<li>el sistema de recomendación según lo que miras</li>
<li>manejar los pagos</li>
<li>comprimir el vídeo</li>
<li>encontrar subtítulos según el lenguaje</li>
<li>etc</li>
</ul>
<p>¡Algunas empresas tienen hasta más microservicios que empleados!</p>
<h2 id="unas-de-las-empresas-que-usan-microservicios">Unas de las empresas que usan microservicios</h2>
<p>Netflix es la empresa que más popularizó la arquitectura de microservicios. Ahora tienen miles de servicios que trabajan juntos para que puedas mirar la última serie en <em>streaming</em>.</p>
<p>Pero también Ebay, Amazon, Facebook, Uber y muchas empresas más están usando microservicios. Muchas más están migrando su monolito a una arquitectura de microservicios.</p>
<p><img src="https://www.appcentrica.com/wp-content/uploads/2016/11/Microservices-Architecture-1.png" alt="Uso de microservicios en Amazon y Netflix" /></p>
<p><small>Diagrama de la arquitectura de microservicios de Amazon y de Netflix</small></p>
<h2 id="la-diferencia-entre-la-arquitectura-de-microservicios-y-soa">La diferencia entre la arquitectura de microservicios y SOA</h2>
<p>La arquitectura de microservicios es una forma específica de realizar una arquitectura <a href="https://es.wikipedia.org/wiki/Arquitectura_orientada_a_servicios">SOA</a> (<em>Service-Oriented Architecture</em>, Arquitectura Orientada a Servicios).</p>
<p>La idea de SOA, es solamente romper un monolito en servicios que colaboran, con el beneficio teórico que se pueda reemplazar la implementación de un servicio de manera transparente para el resto de la aplicación. Aunque SOA sea un concepto que exista desde mucho tiempo, la industria nunca llegó a estandarizar una manera de implementar SOA <strong>bien</strong>. Muchos de los problemas relacionados con SOA vienen de los protocolos de comunicación (SOAP) y de una falta de consenso sobre la granularidad de los servicios o sobre dónde cortar el sistema.</p>
<p>En cambio, la arquitectura de microservicios surgió de uso real, como una manera bien definida de implementar SOA <strong>bien</strong> que permite evitar sus desventajas más comunes.</p>
<h2 id="conclusión">Conclusión</h2>
<p>Espero que este artículo haya sido una buena introducción sobre el tema. En mi próximo articulo te hablaré de los beneficios y de los costos asociados con esta arquitectura para analizar cuando tiene sentido usarla.</p>
<p>¡Cómo siempre si te quedaste con dudas estoy aquí para contestarlas!</p>Introducción Justo empecé a trabajar en la empresa Ziembra, para crear una versión 2 de la plataforma Kudert desde cero, usando el stack MERN (Mongodb/Express/React/Node), es decir todo en Javascript.Los beneficios del testeo automatizado2017-09-04T00:00:00-05:002017-09-04T00:00:00-05:00http://blog.nicolaswebdev.com/2017/09/04/pros-of-testing<p>Para seguir con el artículo anterior sobre las pruebas unitarias, en este artículo voy a resumir los beneficios que puedes esperar al implementar pruebas automatizadas en tu sistema.</p>
<h2 id="1-menos-defectos">1. Menos defectos</h2>
<p>La ventaja principal, es que las pruebas automáticas permiten <strong>limitar mucho la cantidad de defectos</strong> que se introducen en el sistema.</p>
<p>Si usas pruebas de aceptación y que escribes tus pruebas unitarias usando TDD (<em>Test-Driven Development</em>, Desarrollo Guiado por Pruebas), entonces tienes mucha más seguridad de la validez de la nueva funcionalidad que estás implementando.</p>
<p>Además, todas las pruebas que ya están escritas, sirven de <a href="https://es.wikipedia.org/wiki/Pruebas_de_regresi%C3%B3n"><strong>pruebas de regresión</strong></a>, es decir, que te permiten detectar al instante si una parte del sistema que funcionaba anteriormente no se dañó con los últimos cambios introducidos.</p>
<h2 id="2-menos-tiempo-a-probar-manualmente">2. Menos tiempo a probar manualmente</h2>
<p>Si tienes una prueba automática para probar una nueva funcionalidad que estás desarrollando, no perderás tanto tiempo probando manualmente usando la interfaz gráfica. No tendrás que crear los datos necesarios para todo el flujo y dar los veinte clics necesarios cada vez que haces cualquier cambio al código.</p>
<h2 id="3-menos-tiempo-a-depurar-defectos">3. Menos tiempo a depurar defectos</h2>
<p>Si eres un desarrollador, ya sabes cómo las sesiones de depuración pueden resultar frustrante. Una ventaja de las pruebas automáticas, es que <strong>limitan mucho la frecuencia y la duración de las sesiones de depuración</strong>. Eso es debido a que te ayudan a localizar el problema más precisamente y rápidamente (unos pocos minutos después de haber introducido el defecto).</p>
<h2 id="4-encontrar-pronto-los-problemas">4. Encontrar pronto los problemas</h2>
<p>Las pruebas unitarias, especialmente las escritas con TDD, <strong>permiten reducir al máximo el bucle de retro-alimentación (<em>feedback loop</em>).</strong> Mientras más corto el tiempo entre la introducción de un defecto y su detección, más barato va a resultar resolver este defecto. Esto se puede ilustrar de esta manera: ¿cuál sería el costo para el desarrollador arreglar un defecto que agregó hace cinco minutos, comparado con el costo de un defecto que apareció a un cliente?</p>
<p>Esa es una de las mayores razones de la popularidad de las metodologías ágiles, que intentan reducir lo más posible el bucle de retro-alimentación.</p>
<h2 id="5-ayuda-a-desarrollar-la-cosa-correcta">5. Ayuda a desarrollar la cosa correcta</h2>
<p>Cuando las pruebas unitarias se escriben usando la metodología TDD, permite al desarrollador concentrarse en lo que tiene que hacer el sistema (la especificación), antes de pensar en detalles de implementación. Muchas veces, por preferir empezar rápidamente con la implementación, el desarrollador se olvida que quizás no sea esa la funcionalidad que se necesita. <strong>TDD ayuda a construir la cosa correcta</strong>, en lugar de solamente construir la cosa correctamente.</p>
<h2 id="6-un-mejor-diseño">6. Un mejor diseño</h2>
<p>Escribir pruebas automáticas puede ayudar a tener un mejor diseño por múltiples razones.</p>
<p>La primera razón, es que <strong>TDD fuerza a empezar con lo más sencillo</strong>, en lugar de usar la solución más complicada. Eso resulta en general en un mejor diseño, sin reinventar la rueda tibia o hacer sobre-ingeniería.</p>
<p>Segundo, escribir pruebas es mucho más fácil cuando el sistema está modularizado y no tiene mucho acoplamiento entre sus diferentes componentes. Por lo tanto si escribes pruebas todo el tiempo, naturalmente tu código de implementación tendrá un mejor diseño.</p>
<h2 id="7-una-implementación-más-limpia">7. Una implementación más limpia</h2>
<p>Las pruebas permiten el proceso de refactorización, que consiste en cambiar la estructura de un componente sin cambiar su comportamiento, para que sea más fácil de entender y de leer. Sin pruebas, este proceso es demasiado peligroso. Las pruebas te dan algún nivel de seguridad de que el comportamiento realmente no cambió. A veces se comparan las pruebas automáticas a una red de seguridad.</p>
<p>¿Cuantas veces te dijiste: “Tendría que cambiar esto, pero mejor dejarlo así, sino voy a dañar algo.”?</p>
<h2 id="8-las-pruebas-sirven-de-documentación">8. Las pruebas sirven de documentación</h2>
<p>¿Escribes documentación en tu programa? Si es así, entonces seguramente te diste cuenta que a medida que avanza el proyecto, la documentación no se actualiza al mismo tiempo que el sistema y muchas veces termina siendo obsoleta. Y aunque solamente una parte de la documentación esté obsoleta, los trabajadores ya no tienen confianza en la misma, lo que hace que pierda su propósito.</p>
<p>En cambio, las pruebas automáticas forman <strong>las especificaciones</strong> de lo que tiene que hacer el sistema, sin ninguna ambigüedad. Y si todas pasan (¡lo que siempre debería suceder!), entonces estás seguro que no están obsoletas.</p>
<p>Esto sigue el manifiesto ágil: <a href="http://agilemanifesto.org/iso/es/manifesto.html"><q><strong>Software funcionando</strong> sobre documentación extensiva</q></a>.</p>
<h2 id="9-costos-de-mantenimiento-drásticamente-reducidos">9. Costos de mantenimiento drásticamente reducidos</h2>
<p>Una consecuencia de todos los beneficios anteriores, es que <strong>los costos de mantenimiento son drásticamente reducidos</strong> gracias a las pruebas automatizadas. Es mucho más rápido, más seguro y más barato mantener un producto que tiene pruebas.</p>
<h2 id="10-un-producto-más-adaptable">10. Un producto más adaptable</h2>
<p>Gracias a la seguridad otorgada por las pruebas, <strong>cambiar el programa es muy facilitado</strong>, lo que permite por ejemplo adaptar el producto a un nuevo mercado o a un nuevo contexto.</p>
<p>En este mundo que se vuelve tan competitivo y tan veloz, ese es un beneficio vital para tu empresa.</p>
<h2 id="11-un-trabajo-más-agradable">11. Un trabajo más agradable</h2>
<p>Una consecuencia de los otros beneficios, es que las pruebas automáticas suelen aliviar el estrés de los programadores y del resto de la organización, por el hecho que todas las personas involucradas tienen más control. Los trabajadores no tienen que apagar tantos fuegos con urgencia, en cambio pueden concentrarse en hacer un trabajo más interesante y agregar valor al producto y a la empresa.</p>
<p>También los programadores van a tener más orgullo de trabajar sobre un producto de calidad, lo que resulta en un <strong>mejor desempeño</strong> de los mismos.</p>
<h2 id="conclusión">Conclusión</h2>
<p>Todos esos beneficios se potencian a lo largo de la vida del producto, lo que hace que las pruebas automáticas representen una inversión muy importante en el futuro.</p>
<p>Lo más importante de todos los beneficios, es que el producto va a ser más reconocido por tus clientes como siendo un producto de calidad, adaptado a sus necesidades.<br />
Las pruebas automatizadas te pueden dar una ventaja competitiva muy importante.</p>
<p>En mi próximo artículo, te presentaré los costos de las pruebas automatizadas, ya que a pesar de que tengan muchos beneficios, también tienen costos altos; sin embargo lo importante, es que los beneficios sean mayores que los costos.</p>
<p>Si te interesó este artículo y estás pensando en introducir pruebas automáticas en tu empresa, yo les puedo asesorar y acompañar en este proceso, para potenciar esos beneficios y disminuir los costos. ¡No hesites en contactarme!</p>Para seguir con el artículo anterior sobre las pruebas unitarias, en este artículo voy a resumir los beneficios que puedes esperar al implementar pruebas automatizadas en tu sistema.¿Qué son las pruebas unitarias y por qué son importantes?2017-08-14T00:00:00-05:002017-08-14T00:00:00-05:00http://blog.nicolaswebdev.com/2017/08/14/unit-tests<p>En el artículo de hoy, les voy a presentar qué son las pruebas unitarias (<em>unit tests</em> en inglés) y cuáles son los beneficios que pueden traer al proceso de desarrollo.</p>
<h2 id="una-definición">Una definición</h2>
<p>Son pruebas automáticas, escritas por el desarrollador a medida que vaya programando.</p>
<p>Se llaman pruebas unitarias, porque cada prueba unitaria tiene como responsabilidad de testear el buen funcionamiento de una unidad aislada del sistema. La idea es guardar la <strong>especificación</strong> de esa unidad, pero como código fuente, para que la computadora misma pueda comprobar que esa <strong>especificación</strong> sea cumplida por el sistema.</p>
<p>Lo ideal, es correr las pruebas unitarias lo más frecuentemente posible, para que sirvan de guía al momento de desarrollar. Tengo las mías configuradas para que se corren automáticamente cada vez que salvo un archivo de código, es decir varias veces por minuto.</p>
<h2 id="un-ejemplo">Un ejemplo</h2>
<p>Aquí está un ejemplo de la prueba unitaria de una función que suma sus dos parámetros, llamada <em>my_sum</em>. Este ejemplo es en <a href="https://www.ruby-lang.org/es" target="_blank">ruby</a>, usando la librería de pruebas <em>minitest</em>.</p>
<div class="language-ruby highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="nf">test_my_sum</span>
<span class="n">my_sum</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">).</span><span class="nf">must_equal</span> <span class="mi">4</span>
<span class="n">my_sum</span><span class="p">(</span><span class="mi">5</span><span class="o">.</span><span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">).</span><span class="nf">must_equal</span> <span class="mi">11</span><span class="o">.</span><span class="mi">4</span>
<span class="n">my_sum</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">).</span><span class="nf">must_equal</span> <span class="mi">0</span>
<span class="n">my_sum</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">).</span><span class="nf">must_equal</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">end</span>
</code></pre>
</div>
<p>Si hay un defecto en la implementación de la función <em>my_sum</em>, esta prueba lo detectará, permitiendo al desarrollador encontrar y arreglar el defecto.</p>
<p>Naturalmente un método que sume sus parámetros no es muy complicado, pero si uno quiere estar seguro que no tiene error, entonces sí se necesita una prueba unitaria.</p>
<h2 id="las-pruebas-unitarias-quizás-el-tipo-de-pruebas-más-importante">Las pruebas unitarias, quizás el tipo de pruebas más importante</h2>
<p><img src="/assets/testing_pyramid.png" alt="Pirámide de las pruebas" /></p>
<p>Esta es la pirámide de las pruebas. Es una manera de visualizar cómo los diferentes tipos de pruebas se relacionan los unos con los otros. En este gráfico, la base son pruebas que conocen mucho del sistema. Más se sube al tope de la pirámide y más las pruebas se hacen del punto de vista de un usuario, sin tener que conocer o preocuparse con los detalles técnicos del sistema.</p>
<p>Las pruebas automáticas forman la base de la pirámide: es decir que son las más importantes para la estabilidad del sistema y son las más numerosas.</p>
<h2 id="las-características-de-las-pruebas-unitarias">Las características de las pruebas unitarias</h2>
<p>Las pruebas unitarias son el tipo de prueba que más lineas de código necesitan.</p>
<p>Si uno quiere tener una gran parte de su sistema testeado con pruebas unitarias, entonces es común tener <strong>la misma cantidad de líneas de código de pruebas unitarias que de de líneas de implementación</strong>. Aunque esta cifra pueda parecer aterradora, tener pruebas permite tener <strong>mucho menos líneas de implementación</strong>, gracias al proceso de refactorización.</p>
<p>Podemos resumir eso en la siguiente tabla:</p>
<table>
<thead>
<tr>
<th>Cantidad en Código de Implementación</th>
<th>Relación</th>
<th>Cantidad en Pruebas Unitarias</th>
</tr>
</thead>
<tbody>
<tr>
<td>líneas de código</td>
<td>~=</td>
<td>líneas de código</td>
</tr>
<tr>
<td>clases</td>
<td>=</td>
<td>clases</td>
</tr>
<tr>
<td>métodos/funciones públicas</td>
<td>=</td>
<td>métodos</td>
</tr>
</tbody>
</table>
<p>(El símbolo ~= quiere decir más o menos igual)</p>
<p>Lo más frecuente en las pruebas unitarias, es tener una clase de prueba por cada clase de implementación. Y para cada método/función pública de esa clase, tener un método de prueba correspondiente.</p>
<p>Por el hecho que sean las pruebas más cercanas a la aplicación, es muy común que estén escritas en el mismo lenguaje de programación que el programa. Todos los lenguajes de programación un poco conocidos tienen uno o varios <em>frameworks</em> de pruebas.</p>
<p>Unos ejemplos:</p>
<ul>
<li>python: pyunit</li>
<li>java: junit</li>
<li>ruby: minitest, rspec</li>
<li>javascript: jest, test double</li>
</ul>
<h2 id="personas-implicadas-con-las-pruebas-unitarias">Personas implicadas con las pruebas unitarias</h2>
<p>Primeramente, son los programadores que más están involucrados con las pruebas unitarias. De hecho, es el programador que tiene que escribir sus propias pruebas unitarias, cada vez que agregue una nueva unidad lógica al programa (cada vez que agrega un método).</p>
<p>Pero no son los únicos que tienen que interactuar con las pruebas unitarias.</p>
<p>Otro departamento que siempre está involucrado en todas las pruebas, es el departamento de QA (Quality Analysis). La responsabilidad de ellos es escribir las pruebas de integración (automáticas), las pruebas funcionales (también automáticas) y hacer pruebas exploratorias manuales. Aunque no tengan que escribir las pruebas unitarias ellos mismos, es importante para la empresa que puedan al menos leerlas.</p>
<p>También es importante que los jefes del departamento de tecnología tengan un buen conocimiento de las pruebas unitarias y que entiendan sus costos y sus beneficios, para tomar las decisiones sobre qué parte del sistema testear y para hacer que los desarrolladores cumplen con esa tarea.</p>
<h2 id="es-difícil-escribirlas">Es difícil escribirlas</h2>
<p>A pesar de los numerosos beneficios de las pruebas unitarias, aprender a escribirlas es como aprender a programar de nuevo, porque se necesita tener otra mentalidad al momento de escribir las pruebas, saber estructurarles, poder tener pruebas resistentes al cambio, pruebas comprensible, etc. También es muy importante saber qué partes del sistema se tienen que probar y hasta qué punto, es decir, siempre quedarse pragmático.</p>
<p>También se necesita aprender la librería de pruebas, saber cómo trabajar con datos de prueba, saber abstraer/simplificar unas partes del sistema para poder escribir las pruebas (¿qué pasa si el método que quiero probar tiene que comunicarse con el Servicio de Rentas Internas?).</p>
<p>Como todo, es algo que necesita tiempo y experiencia, para poder aplicarlo mejor. Es muy importante pensar cómo introducirlo en tu empresa, porque si no se hace bien, las desventajas se pueden hacer más evidentes que los beneficios, más aún por el hecho de que esos beneficios se perciban más a largo plazo.</p>
<h2 id="conclusión">Conclusión</h2>
<p>Escribir pruebas automáticas es seguramente el pilar más importante sobre el cual se apoyan las otras prácticas, que juntas van a permitir mejorar mucho el proceso de desarrollo y la calidad del sistema.</p>
<p>La base de las pruebas automáticas está formada por las pruebas unitarias, que deberían ser parte integrante del trabajo de los desarrolladores.</p>
<p>En un futuro post te presentaré cuáles son los beneficios, pero también cuáles son los costos que puedes esperar al escribir pruebas automatizadas.</p>En el artículo de hoy, les voy a presentar qué son las pruebas unitarias (unit tests en inglés) y cuáles son los beneficios que pueden traer al proceso de desarrollo.Club de lectura: “Javascript and JQuery: Interactive Front-End Web Development”2017-07-14T00:00:00-05:002017-07-14T00:00:00-05:00http://blog.nicolaswebdev.com/2017/07/14/book-club-javascript-and-jquery<h2 id="introducción">Introducción</h2>
<p>Para seguir con el Club de Lectura anterior, <a href="/2017/06/12/book-club-html-and-css-design-and-build-websites.html"><cite>HTML and CSS: Design and Build Websites</cite></a>, decidí leer el otro libro de Jon Duckett que le completa: <cite><a href="https://www.amazon.com/JavaScript-JQuery-Interactive-Front-End-Development/dp/1118531647/" target="_blank">Javascript and JQuery: Interactive Front-End Web Development</a></cite>.</p>
<p>Ya había hecho varios tutoriales en linea sobre Javascript, el lenguaje de programación de la web. Así que ya sabía manejar el lenguaje, que en sí no es muy complicado para empezar.</p>
<p>El problema que tenía, es que quería tener una introducción de Javascript, pero en el <strong>contexto de la web</strong>. El lenguaje Javascript es una cosa, pero cómo se usa en la Web para agregar interactividad a las páginas, es un tema bastante diferente.<br />
Para cumplir con esta necesidad, ¡este libro resultó ser perfecto!</p>
<h2 id="contenido-del-libro">Contenido del libro</h2>
<p>Esta publicación trata de Javascript en el navegador, no habla de <a href="https://es.wikipedia.org/wiki/Node.js">Node.js</a> (Javascript que se ejecute del lado del servidor).</p>
<p>El libro presupone un conocimiento previo de HTML y de CSS. Por esa razón, es perfecto leerlo justo después de <a href="/2017/06/12/book-club-html-and-css-design-and-build-websites.html"><cite>HTML and CSS: Design and Build Websites</cite></a>.</p>
<p>Aparte de esas dos tecnologías, el autor no requiere ningún otro conocimiento de su lector. Es decir que el lenguaje Javascript está introducido en los cuatro primeros capítulos, de manera que una persona sin conocimiento de programación pueda seguir. Por esa razón, pasé rápidamente los primeros capítulos, pero aunque uno ya sepa programar, esos capítulos son importantes porque explican unas nociones particulares a Javascript que son importantes (los IIFE, las varias maneras de declarar funciones, la creación de objetos etc).<br />
Esa introducción del lenguaje es superficial, es decir que es suficiente para empezar a usar Javascript en la Web, sin embargo, muchos conceptos más complicados del lenguaje no están introducidos. Para eso hará falta buscar un libro que se concentre sobre Javascript como lenguaje.</p>
<p>En los capítulos siguientes están introducidos los <em>events</em>, el API de los navegadores, qué es AJAX y cómo usarlo, una presentación rápida de jQuery, qué son las APIs y cómo manejar errores y depurar código Javascript.</p>
<p>Para terminar, se presentan unos ejemplos completos sobre cómo implementar elementos de diseño u operaciones comunes (como la validación de formularios).</p>
<h2 id="mi-opinión">Mi opinión</h2>
<p>La edición es la misma que <a href="/2017/06/12/book-club-html-and-css-design-and-build-websites.html"><cite>HTML and CSS: Design and Build Websites</cite></a>, es decir con muchas imágenes y esquemas para entender mejor las diferentes nociones.</p>
<p>Por el hecho que el libro no requiere conocimiento de programación, los primeros capítulos me parecieron un poco largos. A pesar de eso, todo me pareció bastante bien explicado.<br />
De la misma manera, durante la presentación de jQuery, me interesé más en los conceptos que en la referencia de los métodos presentados. Si quiero saber cómo hacer algo en jQuery, leo la documentación de jQuery.
Por esas dos razones, leí el libro bastante rápidamente.</p>
<p>Algo que siempre me costó, era tener ejemplos prácticos y útiles de lo que se podía hacer con Javascript. Para eso, este libro fue muy bueno, porque tiene muchos ejemplos con todo el código necesario.</p>
<p>Hay que tener en cuenta que este libro fue publicado en 2014, por lo tanto el Javascript que está presentado es el Javascript <em>tradicional</em>, es decir sin las nuevas funcionalidades agregadas estos últimos años (no habla de ES6).</p>
<p>Lo que me gustó mucho de este libro, como el otro libro sobre HTML y CSS del mismo autor, es que es muy exhaustivo. Es decir que no solamente habla de Javascript, sino más bien es una presentación general de todos los aspectos y las tecnologías necesarias para empezar a usar Javascript en el navegador. Después de este libro, el lector puede profundizar temas particulares con libros más enfocados.</p>
<p>Actualmente Javascript está cambiando a una velocidad impresionante. También por las mejoras que incluyen los nuevos navegadores y por la popularidad de los <em>frameworks</em> Javascript, el uso de jQuery se está volviendo menos necesario cada día.</p>
<p>A pesar de eso y afuera de la <em>Silicon Valley</em>, la programación en Javascript sigue siendo más tradicional, con el uso de jQuery. Por eso, me parece muy importante tener un buen conocimiento de esas varias técnologías. Para cumplir esta meta, este libro resultó ser muy muy bueno, así que lo recomendaría a todo el mundo que quiera empezar con el desarrollo web.</p>Club de lectura: “HTML and CSS: Design and Build Websites”2017-06-12T00:00:00-05:002017-06-12T00:00:00-05:00http://blog.nicolaswebdev.com/2017/06/12/book-club-html-and-css-design-and-build-websites<h2 id="introducción">Introducción</h2>
<p>¿En serio, se necesita un libro para aprender HTML y CSS? ¡Ni siquiera son lenguajes de programación! ¿Qué tan complicado puede ser?</p>
<p>Hace ya muchos años que aprendí las bases de HTML y de CSS. En toda la web se encuentran muchos tutoriales o introducciones a esas dos tecnologías.<br />
Pero hasta ahora, nunca había leído algo que sea completo sobre el tema, lo que me llevó a perder mucho tiempo en varios proyectos, por ejemplo, cuando tuve que hacer el diseño de páginas web. Más que nada estaba buscando un libro que me enseñe las bases del <em>webdesign</em>.</p>
<p>Aprender los lenguajes HTML y CSS es bastante sencillo, pero saber manejarlos bien, es algo que puede tomar años. Además, el desarrollo web es un mundo muy complicado para entrar por su amplitud y su tendencia a cambiar a una velocidad impresionante.</p>
<p>Después de buscar por bastante tiempo los mejores libros sobre el tema, encontré <cite><a href="https://www.amazon.com/HTML-CSS-Websites-Paperback/dp/B01FRZ1FXI/" target="_blank">HTML and CSS: Design and Build Websites</a></cite>, de Jon Duckett, que era uno de los más mencionados en la web.</p>
<h2 id="contenido-del-libro">Contenido del libro</h2>
<p>Este libro presenta dos de los tres lenguajes de la web:</p>
<ul>
<li><strong><a href="https://es.wikipedia.org/wiki/HTML">HTML</a></strong>: HyperText Markup Language, creado en el 1990, es el lenguaje de <strong>contenido</strong> de la web desde sus principios. A su creación, el estilo se definía adentro del mismo HTML, hasta que CSS aparezca.</li>
<li><strong><a href="https://es.wikipedia.org/wiki/Hoja_de_estilos_en_cascada">CSS</a></strong>: Cascading Style Sheets, creado en el 1996, se usa para describir la <strong>presentación</strong> (el <strong>estilo</strong>) de una página web.</li>
</ul>
<p>Además de estas dos tecnologías, el libro presenta todas las nociones necesarias para poder empezar con el desarrollo web.</p>
<p>El elemento clave que falta es el Javascript, el lenguaje de programación de la web, que se está volviendo poco a poco el lenguaje más usado en el mundo. El autor le dedica un libro aparte, <cite><a href="https://www.amazon.com/JavaScript-JQuery-Interactive-Front-End-Development/dp/1118531647/">JavaScript and JQuery: Interactive Front-End Web Development</a></cite>, que estoy actualmente terminando de leer.</p>
<p>Durante los nueve primeros capítulos, tenemos una introducción a todos los elementos básicos de HTML: las listas, los enlaces, las tablas, los formularios, etc. En el capítulo 10 llega CSS y los elementos de diseño, como los colores, la tipografía y el <em>layout</em> de las páginas.</p>
<h2 id="mi-opinión">Mi opinión</h2>
<p>La edición es buena, aunque personalmente no me guste el <em>layout</em> que escogieron para el contenido, que está dispuesto como si fuera una página web en lugar de un libro, porque me toma más tiempo para leer. Hay un montón de imágenes y todos los temas son bien explicados.</p>
<p>Ahora hablemos del contenido. Durante una buena parte del libro, no estaba aprendiendo nada de nuevo, porque empieza desde el principio, para alguien que no sepa nada del desarrollo web.<br />
Pero después de haber terminado con la introducción de los elementos del HTML y del CSS, me parece que los temas adicionales como los colores y las bases de diseño forman un todo muy coherente, de forma bien introductoria para programadores que no saben nada de diseño. Después de este libro, podré profundizar algunos temas si me interesa (por ejemplo la tipografía).</p>
<p>Hasta en los temas “sencillos”, como las tablas y los formularios HTML, aprendí cosas nuevas porque es muy completo. En definitiva, este libro representa una buena referencia a tener siempre al lado, más aún por el hecho que no haya una documentación “oficial” de la web, sino más bien varias, de calidad y de exhaustividad variable (<a href="https://developer.mozilla.org/en-US/">MDN</a>, <a href="https://www.w3schools.com">W3Schools</a>, <a href="http://reference.sitepoint.com/html">SitePoint</a>, etc).</p>
<p>En conclusión un referente para quien quiera aprender desde cero el desarrollo web, pero también muy recomendable para cualquier desarrollador web, por la exhaustividad del contenido.</p>Introducción ¿En serio, se necesita un libro para aprender HTML y CSS? ¡Ni siquiera son lenguajes de programación! ¿Qué tan complicado puede ser?Club de lectura: libros que leí2017-05-29T00:00:00-05:002017-05-29T00:00:00-05:00http://blog.nicolaswebdev.com/2017/05/29/books-list<p>Aquí están listados todos los libros técnicos que leí hasta ahora, relacionados con la programación o los sistemas.</p>
<p>Si estás interesado en leer alguno de estos libros, me puedes preguntar para que te aconseje. También si estás por aquí, ¡te los podría prestar de alguna manera!</p>
<h3 id="en-2017">En 2017</h3>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780321604811" target="_blank">Rails Antipatterns: Best Practice Ruby on Rails Refactoring</a></cite></strong><br />
Publicado en 2010 por Chad Pytel & Tammer Saleh<br />
★★★★☆</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9781617292392" target="_blank">Soft Skills: The Software Developer’s Life Manual</a></cite></strong><br />
Publicado en 2014 por John Z. Sonmez<br />
★★★★★</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780321984135" target="_blank">Refactoring: Ruby Edition: Ruby Edition (Addison-Wesley Professional Ruby)</a></cite></strong><br />
Publicado en 2009 por Jay Fields & Shane Harvie & Martin Fowler<br />
★★★★☆<br />
<a href="/2017/04/25/book-club-refactoring-ruby-edition.html">Mi reseña del libro</a></p>
<h3 id="en-2016">En 2016</h3>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9781937785567" target="_blank">Agile Web Development With Rails 4</a></cite></strong><br />
Publicado en 2013 por Sam Ruby & David Thomas & David Heinemeier Hansson<br />
★★★★☆</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780201616224" target="_blank">The Pragmatic Programmer: From Journeyman to Master</a></cite></strong><br />
Publicado en 1999 por Andrew Hunt<br />
★★★★☆</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780321721334" target="_blank">Practical Object-Oriented Design in Ruby: An Agile Primer</a></cite></strong><br />
Publicado en 2012 por Sandi Metz<br />
★★★★★</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780596518387" target="_blank">Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman</a></cite></strong><br />
Publicado en 2009 por Dave Hoover & Adewale Oshineye<br />
★★★★☆</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9781593272838" target="_blank">Learn You a Haskell for Great Good!: A Beginner’s Guide</a></cite></strong><br />
Publicado en 2011 por Miran Lipovača<br />
★★★★★</p>
<h3 id="en-2015">En 2015</h3>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780201835953" target="_blank">The Mythical Man-Month: Essays on Software Engineering</a></cite></strong><br />
Publicado en 1995 por Frederick Phillips Brooks<br />
★★★★☆</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780201485677" target="_blank">Refactoring: Improving the Design of Existing Code</a></cite></strong><br />
Publicado en 1999 por Martin Fowler & Kent Beck<br />
★★★★★</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780321146533" target="_blank">Test-Driven Development: By Example</a></cite></strong><br />
Publicado en 2003 por Kent Beck<br />
★★★★★</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780321278654" target="_blank">Extreme Programming Explained: Embrace Change</a></cite></strong><br />
Publicado en 2004 por Kent Beck & Cynthia Andres<br />
★★★★★</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780131177055" target="_blank">Working Effectively With Legacy Code</a></cite></strong><br />
Publicado en 2004 por Michael C. Feathers<br />
★★★★☆</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780321680563" target="_blank">Programming in Python 3: A Complete Introduction to the Python Language</a></cite></strong><br />
Publicado en 2009 por Mark Summerfield<br />
★★★★★</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780596515171" target="_blank">Masterminds of Programming: Conversations With the Creators of Major Programming Languages (Theory in Practice (O’Reilly))</a></cite></strong><br />
Publicado en 2009 por Federico Biancuzzi & Chromatic<br />
★★★★☆</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9781617291692" target="_blank">The Well-Grounded Rubyist</a></cite></strong><br />
Publicado en 2014 por David A. Black<br />
★★★★★</p>
<p><strong><cite><a href="https://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-isbn=9780137043293" target="_blank">Essential Scrum: A Practical Guide to the Most Popular Agile Process</a></cite></strong><br />
Publicado en 2012 por Kenneth S. Rubin<br />
★★★★☆</p>Aquí están listados todos los libros técnicos que leí hasta ahora, relacionados con la programación o los sistemas.¿Cómo contratar a un buen programador? - El anuncio2017-05-16T00:00:00-05:002017-05-16T00:00:00-05:00http://blog.nicolaswebdev.com/2017/05/16/how-to-hire-a-good-programmer-ad<p>¿Qué es lo más importante en una empresa? ¡Seguramente son los trabajadores!</p>
<p>Por mi experiencia como programador y por haberme encargado varias veces del proceso de selección, me parece importante compartir contigo algunos elementos clave sobre cómo contratar al programador que tu empresa necesita.<br />
Estos consejos son por experiencia propia, pero también son consejos que escuché muchas veces repetidos en la industria (en EEUU).</p>
<h2 id="por-qué-escoger-un-buen-programador-estan-importante">¿Por qué escoger un buen programador es tan importante?</h2>
<p>En el mundo del desarrollo el talento o el profesionalismo del candidato es más importante aún, por la diferencia de rendimiento que puede haber entre dos programadores. De hecho, se habla del “Programador 10X”, es decir, que algunos programadores logran ser más de diez veces más productivos que otros. Hubieron varios estudios sobre este tema (<a href="https://softwareengineering.stackexchange.com/questions/179616/a-good-programmer-can-be-as-10x-times-more-productive-than-a-mediocre-one">este <em>post</em></a> en Stackoverflow lo resume bien).</p>
<p>En mi experiencia, pude ver programadores que eran más un freno al proyecto que una ayuda.</p>
<p>Si el proceso de entrevista a los programadores no es de un nivel satisfactorio, entonces la empresa nunca va a poder lograr sus metas. Por esta razón, si tienes una empresa que tiene un equipo de desarrollo, uno de los elementos clave del éxito de la organización es contratar a buenos programadores.</p>
<h2 id="en-el-anuncio">En el anuncio</h2>
<p>Empecemos con la primera etapa del proceso de selección, que va a definir qué perfiles van a poder aplicar.</p>
<h3 id="consejo-1-no-te-limites-a-un-lenguaje-de-programación-o-a-una-tecnología-precisa">Consejo 1: no te limites a un lenguaje de programación o a una tecnología precisa</h3>
<p>Ese es el primer problema que encontré. Por ejemplo, una empresa que busca un desarrollador Javascript, que pide conocimiento de Javascript como requerimiento para aplicar.</p>
<p>La verdad es que <strong>es mucho más importante encontrar alguien talentoso que alguien que ya conozca el lenguaje de programación/<em>framework</em>/tecnologías con las cuales va a tener que trabajar</strong>.</p>
<p>Es mucho más fácil enseñar un nuevo lenguaje de programación/<em>framework</em>/tecnología a alguien curioso/interesado, que trabajar con alguien que ya los conoce pero que trabaja mal.<br />
En el anuncio puedes indicar con qué tecnologías se va a trabajar en este puesto, pero es importante que <strong>no sea un requerimiento</strong>. Sino vas a perder muchas oportunidades muy buenas.</p>
<p>Algo que sí puede ser importante, es que el candidato sepa un lenguaje de programación que pertenezca al mismo <a href="https://es.wikipedia.org/wiki/Paradigma_de_programaci%C3%B3n">paradigma de programación</a> (principalmente Orientado a Objetos o Funcional). Por ejemplo si el puesto va a ser para trabajar con un lenguaje orientado a objetos, digamos Java, entonces el candidato debería conocer al menos un lenguaje orientado a objetos, por ejemplo C# (.NET). Esto se debe a que aprender un nuevo paradigma es bastante más complicado que aprender un nuevo lenguaje.</p>
<p>Como siempre, depende de tu contexto: si necesitas alguien para un proyecto muy rápidamente, entonces puede ser que no tengas tiempo para que esta persona aprenda. Pero si tu idea es que este trabajador se quede más de tres meses, entonces no tiene que ser un criterio importante. Mejor pensar a largo plazo.</p>
<h3 id="consejo-2-no-busques-solamente-a-un-desarrollador-senior">Consejo 2: no busques solamente a un Desarrollador Senior</h3>
<p>Esta denominación de Desarrollador Junior/Middle/Senior se usa mucho, a nivel internacional. En muchos de los casos, hace referencia a los años de experiencia del programador.</p>
<p>En realidad, <strong>los años de experiencia es un indicador muy malo del valor de un programador</strong>.</p>
<p>La programación y la tecnología es la industria que cambia más rápidamente en el mundo. Todos los cinco años, hay una revolución, ya sea en herramientas, metodologías de trabajo o lenguajes de programación. Lo más importante es que el programador <strong>se actualice todo el tiempo</strong>.</p>
<p>Los años de trabajo no reflejan en nada los conocimientos de una persona. Es mucho mejor tener un joven curioso y talentoso que una persona con más años, pero que no continuó aprendiendo después de la universidad.</p>
<p>Inclusive para puestos de jefatura, puede resultar muy interesante tener la visión más moderna/fresca de una persona joven, que tener la de alguien con más “experiencia”, pero que ya está acostumbrada a una manera precisa de trabajar y le cuesta adaptarse.</p>
<h3 id="consejo-3-el-inglés-importa-más-de-lo-que-piensas">Consejo 3: el inglés importa más de lo que piensas</h3>
<p>¿Cuál es una de las habilidades más importante de un programador? Diría sin hesitar buscar en Google.</p>
<p>Hoy en día trabajamos en un entorno en el cual se necesita hacer búsquedas todo el tiempo. Porque independientemente de nuestra capacidad intelectual, estamos trabajando con <strong>herramientas creadas por otras personas</strong>, por lo tanto necesitamos buscar ayuda a diario.</p>
<p><strong>Una insuficiencia de comprehensión del inglés puede hacer este proceso de búsqueda de respuestas mucho más complicado</strong>. Para cualquier pregunta que puedas tener, si buscas en inglés, vas a encontrar muchísimos más resultados.</p>
<p>Para que tengas una idea de las cifras de las búsquedas en Google según el idioma:</p>
<table>
<thead>
<tr>
<th>Búsqueda</th>
<th style="text-align: right"># resultados en inglés</th>
<th style="text-align: right"># resultados en español</th>
<th style="text-align: right"># resultados en inglés / # resultados en español</th>
</tr>
</thead>
<tbody>
<tr>
<td>ruby on rails</td>
<td style="text-align: right">23 600 000</td>
<td style="text-align: right">392 000</td>
<td style="text-align: right">60</td>
</tr>
<tr>
<td>java</td>
<td style="text-align: right">526 000 000</td>
<td style="text-align: right">12 300 000</td>
<td style="text-align: right">42</td>
</tr>
<tr>
<td>javascript</td>
<td style="text-align: right">1 990 000 000</td>
<td style="text-align: right">65 900 000</td>
<td style="text-align: right">30</td>
</tr>
<tr>
<td>react</td>
<td style="text-align: right">237 000 000</td>
<td style="text-align: right">830 000</td>
<td style="text-align: right">285</td>
</tr>
</tbody>
</table>
<p>Muchas veces se necesita hacer búsquedas sobre un error que casi nadie más tiene o buscar algo muy especifico e inclusive en inglés muchas veces no se encuentran resultados. La búsqueda en español limita mucho la probabilidad de encontrar la respuesta.</p>
<p>Además de búsquedas en Google, la documentación oficial de los lenguajes/<em>frameworks</em>/herramientas, que es <strong>indispensable para trabajar</strong>, pocas veces está en otro idioma que en inglés o está bastante mal traducida o incompleta.</p>
<p>Por esta razón, creo que una comprehensión escrita del inglés es muy importante. Para pedir ayuda en los foros, la escritura también es necesaria. Además, recomiendo que el equipo siempre escriba el código fuente en inglés, por lo que el conocimiento del idioma es más importante aún, ya que permite escoger bien los nombres de variables, de métodos y de clases.</p>
<h2 id="el-proceso-de-selección-de-las-candidaturas">El proceso de selección de las candidaturas</h2>
<p>Una vez publicado tu anuncio y teniendo en mente los puntos que te acabo de presentar, llega el momento de escoger dentro de las candidaturas que recibiste para el puesto.</p>
<p>Te aconsejo mucho no ser demasiado exigente con las hojas de vida, porque como te decía, la experiencia de un programador es solamente un elemento dentro de todos los aspectos que forman un buen profesional. Si te limitas mucho a esto, ¡podrías perder muy buenas oportunidades!</p>
<p>En una segunda publicación, te presentaré los elementos importantes para el proceso de entrevista.</p>
<h2 id="necesitas-ayuda-con-tu-proceso-de-selección">¿Necesitas ayuda con tu proceso de selección?</h2>
<p>¿Quieres estar seguro de contratar a los mejores, pero no sabes bien qué aspectos considerar y cómo evitar contratar a la persona equivocada?<br />
¿Sabes que esto podría tener consecuencias importantes a largo plazo?</p>
<p>Estoy a dispocisión para ayudar a tu empresa con esto. Brindo asesoría sobre cómo mejorar su proceso de selección o ayudándolos a realizar las entrevistas personalmente, asegurándome del nivel técnico y profesional de los candidatos.</p>
<p>Si estás interesado, ¡escríbeme!</p>¿Qué es lo más importante en una empresa? ¡Seguramente son los trabajadores!Club de lectura: “Refactoring: Ruby Edition”2017-04-25T00:00:00-05:002017-04-25T00:00:00-05:00http://blog.nicolaswebdev.com/2017/04/25/book-club-refactoring-ruby-edition<h2 id="introducción-al-club-de-lectura">Introducción al club de lectura</h2>
<p>Hace ya un tiempo que tomé la costumbre de anotar todos los libros que leo, con la fecha en la cual lo terminé, poniéndole una nota y un comentario. Esto me permite acordarme después de varios años cuáles fueron los libros que leí y cuál fue mi opinión sobre ellos.</p>
<p>Ahora que empecé con mi blog, creo que es mejor que comparta mi experiencia por este medio.</p>
<p>Así que arrancamos con este primer libro que acabo de terminar, <cite><a href="https://www.amazon.com/Refactoring-Ruby-Addison-Wesley-Professional/dp/0321984137" target="_blank">Refactoring: Ruby Edition</a></cite>, de Jay Fields, Shane Harvie, Martin Fowler y Kent Beck.</p>
<h2 id="el-original-refactoring-improving-the-design-of-existing-code">El original: “Refactoring: Improving the Design of Existing Code”</h2>
<p>No sé si escuchaste del libro <cite><a href="https://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672">Refactoring: Improving the Design of Existing Code</a></cite>, de Martin Fowler y Kent Beck. Este libro es uno de los clásicos de la ingeniería de software.<br />
Fue publicado en 1999 y revolucionó la industria. Es el libro que popularizó la noción de <a href="https://es.wikipedia.org/wiki/Refactorizaci%C3%B3n">refactorización</a> del código. Ya lo leí hace unos años atrás.</p>
<p>Martin Fowler define la refactorización de la siguiente manera (traducción mía):</p>
<blockquote>
Refactorización: Un cambio hecho en la estructura interna del software para hacerlo más fácil de entender y más barato de modificar, sin cambiar su comportamiento observable.
</blockquote>
<blockquote>
Refactorizar: reestructurar un software aplicándole una serie de refactorizaciones, sin cambiar su comportamiento observable.
</blockquote>
<p>Por ejemplo, cambiar el nombre de un método para que sea más claro, es una refactorización. Martin Fowler presenta en su primer libro lo que es la noción de refactorización, por qué es tan importante y también ofrece al lector un catálogo de refactorizaciones.</p>
<p>Aunque este libro sea muy muy muy bueno y recomendable, todos los ejemplos están escritos en Java. Por la naturaleza de Java (lenguaje fuertemente tipado), algunas refactorizaciones no tienen sentido en un lenguaje dinámico (como Python, Javascript, PHP y Ruby). También lenguajes dinámicos pueden necesitar otros tipos de refactorizaciones.</p>
<p>Por esas razones, Jay Fields decidió con los otros autores que iba a adaptar el clásico, en una nueva versión adaptada a los lenguajes dinámicos y más particularmente a Ruby.</p>
<h2 id="refactoring-ruby-edition">“Refactoring: Ruby Edition”</h2>
<p>Así que este libro es un tipo de nueva edición del anterior. Martin Fowler está dentro de los autores, no porque fue involucrado en este libro, pero porque escribió el original.</p>
<p>No note muchas diferencias entre el libro original y la edición Ruby, por el hecho de que ya había leído el original hace un tiempo atrás y que muchas partes son idénticas.</p>
<p>Se podría decir que esta nueva versión no es tan perfecta como la original (por ejemplo, la edición ya que hay algunos errores en los ejemplos), pero nada que perjudique la comprensión general.</p>
<p>Recomendaría este libro a todos las personas que trabajan con Ruby, sin duda, porque hay mucha información interesante y refactorizaciones particulares al lenguaje.<br />
Pero también creo que puede ayudarte bastante si trabajas con otros lenguajes dinámicos, tales como Javascript, Python y PHP.</p>
<p>Para concluir, un buen libro, aunque quizás un poco particular para merecer que te lo leas primero.</p>Introducción al club de lectura Hace ya un tiempo que tomé la costumbre de anotar todos los libros que leo, con la fecha en la cual lo terminé, poniéndole una nota y un comentario. Esto me permite acordarme después de varios años cuáles fueron los libros que leí y cuál fue mi opinión sobre ellos.