<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>método</title><link>https://devtia.com/</link><description>Llevamos empresas a la nueva era digital. Te ayudamos a mejorar tus procesos a través de las métricas.</description><language>es</language><pubDate>Tue, 26 May 2026 05:53:43 +0200</pubDate><lastBuildDate>Tue, 26 May 2026 05:53:43 +0200</lastBuildDate><generator>DEVTIA</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><ttl>3600</ttl><item><title>Nuestra garantía</title><link>https://devtia.com/post/nuestra-garantia</link><description><![CDATA[<p><strong>Ofrecer una buena garant&iacute;a </strong>en nuestro productos, el cual se convertir&aacute; en una importante pieza para la empresa que nos contrat&oacute; y que, probablemente acabar&aacute; siendo el eje central de numerosos procesos internos y externos, se hace <strong>vital para ofrecer una confianza extra a nuestros clientes</strong>.</p><p>Nuestra m&aacute;xima es ofrecer el mejor producto posible a un precio m&aacute;s que razonable. Para que el proyecto triunfe, tal y como explicamos en nuestra metodolog&iacute;a de trabajo, necesitaremos la mayor implicaci&oacute;n por parte del cliente en el proceso que acompa&ntilde;a al desarrollo del software.</p><p><strong>Nuestra garant&iacute;a es un fiel reflejo de esta implicaci&oacute;n exigida al cliente.</strong></p><div class="row mt-5"><div class="col-sm-3 pt-3"><img alt="Seguridad - Devtia" loading="lazy" src="/cache/thumb_1200_0800/uploads/content/image/image/e3443d8c4d4bdeb8c1a4288237a602571040177b.png" title="Seguridad - Devtia"></div><div class="col-sm-9"><h2 class="mt-0">INCLUIDO</h2><p>Nuestra garant&iacute;a incluye la <strong>correcci&oacute;n de todos aquellos defectos que puedan detectarse</strong> dentro del plazo incluido en la garant&iacute;a.</p><p>Nuestra garant&iacute;a cubre solamente los errores, no incluye modificaciones procesos a los que el cliente deber&iacute;a de haber prestado una atenci&oacute;n mayor y que no son derivados de nuestra actividad.</p></div><div class="row mt-0"><div class="col-sm-9 mt-5"><h2 class="mt-0">NO INCLUIDO</h2><p>Tampoco incluye <strong>modificaciones de textos ni nuevos requisitos o necesidades</strong> que aparecen despu&eacute;s de la entrega.</p></div><div class="col-sm-3 pt-3"><p><img alt="modificaciones de textos" loading="lazy" src="/cache/thumb_1200_0800/uploads/content/image/image/a8108be4ab65338c49f90c19111a48bbc1f7a7c4.png" title="Errores"></p></div></div><div class="row pt-3"><div class="col-sm-3 pt-5"><p><img alt="garant&iacute;a de correcci&oacute;n" class="d-none d-sm-block" loading="lazy" src="/cache/thumb_1200_0800/uploads/content/image/image/7eff5c351ed56de568ff636fe3df57d9430ba04f.png" title="garant&iacute;a de correcci&oacute;n"></p></div><div class="col-sm-9 pt-3"><h2 class="mt-0">DURACI&Oacute;N</h2><p>La garant&iacute;a ofrecida por DEVTIA es bastante simple, <strong>ofrecemos una garant&iacute;a de correcci&oacute;n de errores de tres meses en todos nuestros proyectos</strong> que comenzar&aacute; a contar tras la finalizaci&oacute;n del mismo. El cliente debe comprometerse a revisar en profundidad el funcionamiento de su proyecto en este plazo.</p><p>En caso de que por cualquier motivo, el cliente no pueda realizar estas comprobaciones para recurrir a la garant&iacute;a, no pasar&aacute; nada, no hay ning&uacute;n problema, <strong>queremos que nuestro producto funcione a la perfecci&oacute;n y vamos a encargarnos de reparar lo que debamos</strong>. Eso s&iacute;, en caso de recurrir a la garant&iacute;a fuera de plazo, el cliente tendr&aacute; que pagar por el tiempo adicional que dedicaremos a su proyecto.</p><p>Nuestra recomendaci&oacute;n es que, en la medida de lo posible, exprimas al m&aacute;ximo el funcionamiento de la herramienta durante estos tres meses para que no se escape ning&uacute;n posible error y no tengas que pagar ni un euro de m&aacute;s.</p></div></div></div>
]]></description><guid>https://devtia.com/post/nuestra-garantia</guid><pubDate>Tue, 28 Apr 2020 12:24:48 +0200</pubDate></item><item><title>Buenas prácticas</title><link>https://devtia.com/post/buenas-practicas</link><description><![CDATA[<p>Para la ejecuci&oacute;n de un buen proyecto de desarrollo de software es necesario que el equipo de desarrollo se preocupe por implementar una serie de buenas pr&aacute;cticas de trabajo.</p><p>En esta entrada queremos explicarte algunas de las buenas pr&aacute;cticas que implementamos en el equipo.</p><h2>C&Oacute;DIGO LIMPIO</h2><p>Cuando hablamos de c&oacute;digo limpio nos referimos a buenas pr&aacute;cticas en el desarrollo de software descritos por <strong>Robert C Martin</strong> en su libro <strong>&ldquo;C&oacute;digo Limpio&rdquo;</strong>, del que puedes encontrar mucha informaci&oacute;n en esta serie de entradas que hemos publicado.</p><p>El seguimiento de las indicaciones que se aportan genera proyectos que son m&aacute;s f&aacute;ciles de mantener en el tiempo.</p><h2>PROGRAMACI&Oacute;N EN PAREJAS</h2><p>La programaci&oacute;n en parejas es un <strong>concepto propuesto por Ken Beck</strong> en su libro &ldquo;<strong>Programaci&oacute;n extrema&rdquo;</strong>. La idea que subyace detr&aacute;s de su propuesta es que si bien, dos programadores que trabajan juntos van a producir menos l&iacute;neas de c&oacute;digo, el que generen ser&aacute; de mayor calidad, por lo que de forma efectiva el equipo va m&aacute;s r&aacute;pido.</p><p>Nosotros implementamos una versi&oacute;n de lo que &eacute;l propone. Cada programador trabaja de forma independiente la mayor&iacute;a del tiempo, pero programamos por parejas cuando alguien necesita ayuda o est&aacute; tocando algo muy delicado.</p><h2>PRUEBAS AUTOM&Aacute;TICAS</h2><p>Las pruebas autom&aacute;ticas es un software dise&ntilde;ado para probar el software, valga la redundancia, en el que se est&aacute; trabajando.</p><p>El uso de pruebas autom&aacute;ticas a&ntilde;ade muchas ventajas al desarrollo, pero sobre todo la principal ventaja desde el punto de vista del cliente es un <strong>producto digital con menos errores y con mayor facilidad para ser modificado.</strong></p><h2>INTEGRACI&Oacute;N CONTINUA</h2><p><strong>Integraci&oacute;n continua es una pr&aacute;ctica muy relacionada con el desarrollo &aacute;gil</strong>, seg&uacute;n la cual la bater&iacute;a de pruebas se ejecuta de manera autom&aacute;tica en un servidor remoto con cada cambio en el c&oacute;digo.</p><h2>RESUMEN</h2><div class="row"><div class="col-sm-4"><p>No hay una <strong>f&oacute;rmula m&aacute;gica que garantice el &eacute;xito de un proyecto</strong>, sin embargo si que hay un <strong>conjunto de buenas pr&aacute;cticas</strong> que nos sirvan para no perder el rumbo. Por nuestra parte, nuestra f&oacute;rmula del &eacute;xito es la siguiente resprsentaci&oacute;n.</p></div><div class="col-sm-8"><p><img alt="Happy Client" loading="lazy" src="/cache/thumb_1200_0800/uploads/content/image/image/a1a510f96d01e92b04994195a3216e4ea5d3033d.png" title="Nuestra f&oacute;rmula para ser un Cliente Feliz"></p></div></div>
]]></description><guid>https://devtia.com/post/buenas-practicas</guid><pubDate>Thu, 11 Mar 2021 10:36:04 +0100</pubDate></item><item><title>Nuestro proceso de selección</title><link>https://devtia.com/post/nuestro-proceso-de-seleccion</link><description><![CDATA[<p>Contar con un personal capacitado y comprometido con el trabajo de tu empresa es esencial para poder triunfar en cualquier sector que se precie. La b&uacute;squeda del candidato o candidata perfecta no es para nada una tarea f&aacute;cil. Intentamos que nuestros procesos de selecci&oacute;n sean sencillos y faciliten el trabajo a nuestros reclutadores, simplificando en la medida de lo posible el proceso y haci&eacute;ndolo lo m&aacute;s din&aacute;mico posible.</p><p>Ciertas empresas suelen considerar que el candidato m&aacute;s cualificado para ocupar un puesto vacante es aquel que cumple con todos los requisitos y cuyas expectativas salariales son lo m&aacute;s bajas posibles, nosotros consideramos que enfocar as&iacute; la busqueda es un error que puede traer consecuencias a larga. Pensamos que para que un empleado pueda exprimir sus capacidades en nuestra empresa, <strong>ha de existir una estrecha relaci&oacute;n entre los requisitos que exigimos por su parte y las expectativas de trabajo que el candidato espera que la compa&ntilde;&iacute;a ofrezca.</strong></p><p>A lo largo de este art&iacute;culo te contaremos c&oacute;mo es nuestro proceso de selecci&oacute;n con todo lujo de detalles.</p><h2>La preselecci&oacute;n</h2><p><img alt="selecci&oacute;n" loading="lazy" src="/cache/thumb_1200_0400/uploads/content/image/image/b0f80e8cbbf8691cf700c44f4cd69afc80292969.jpg" title="selecci&oacute;n"></p><p>Solemos recibir candidaturas a trav&eacute;s de dos canales:</p><ol><li>A trav&eacute;s de portales de empleo.</li><li>Nos contactan de manera directa al haber visto la oferta publicada a trav&eacute;s de nuestra p&aacute;gina web o de alguna redes sociales.</li></ol><p>No nos gusta tener que depender de una plataforma o herramienta de terceros para comunicarnos, por lo que a partir de la toma de contacto <strong>nos comunicamos siempre de manera externa a ellas.</strong> Creamos en nuestro CRM una ficha con los datos relevantes del candidato y comprobamos si cumple los principales requisitos, aunque no los cumpla al 100%, pueden existir detalles que nos motiven a incluirlo en el proceso de selecci&oacute;n como por ejemplo, una buena carta de presentaci&oacute;n o una buena actitud.</p><p><strong>Somos una empresa que trabaja 100% en remoto</strong> por lo que da igual en qu&eacute; punto del globo se encuentren los candidatos, siempre que se conecten con nuestro hor&aacute;rio y hablen nuestro idioma ;)</p><h2>Llamada telef&oacute;nica</h2><p><img alt="telefono" loading="lazy" src="/cache/thumb_1200_0200/uploads/content/image/image/4cc464a39863e432ed6abec4a065d09de24ed91b.jpg" title="telefono"></p><p>Lanzamos a trav&eacute;s de redes sociales los puestos que necesitamos cubrir y adjuntamos una encuesta que nos ayudar&aacute; como primera criba, es importante para nosotros contar con un punto de partida &oacute;ptimo que garantice conocimientos o estandares fijados as&iacute; como conocer si el candidato o candidato est&aacute;n familiarizados con metodolog&iacute;as &aacute;giles. Por lo general los primeros descartes se realizan por expectativas econ&oacute;micas que no van a acordes a lo que el candidato puede ofrecernos, por ejemplo, si buscamos a alguien que tenga experiencia en symfony, y el candidato tiene unos conocimientos m&iacute;nimos, no vamos a poder ofrecer los 40k que nos exija, no podemos pagar esa cantidad para acabar ense&ntilde;ando a utilizar una herramienta que exigimos como esencial.</p><h2>Entrevista personal</h2><p><img alt="entrevista-personal" loading="lazy" src="/cache/thumb_1200_0200/uploads/content/image/image/551291c75cb2045ac4ceca6460080ad8fca5953f.jpg" title="entrevista-personal"></p><p>Es el plato fuerte de cualquier proceso de selecci&oacute;n, es realizada por todo el equipo y se divide en dos partes:</p><p>El objetivo de <strong>la primera parte</strong> es buscar la sinton&iacute;a entre lo que el candidato busca y lo que podemos ofrecerle entendiendo, entre otras cosas:</p><ul><li>Qu&eacute; tipo de candidato es.</li><li>Cu&aacute;les son sus motivaciones.</li><li>Cu&aacute;l ser&iacute;a su trabajo, pretendemos conocer si el desempe&ntilde;o deseado por el entrevistado se aproxima a lo que hacemos en nuestro d&iacute;a a d&iacute;a.</li></ul><p><strong>En la segunda parte</strong> dejamos preguntar al candidato y mostramos qu&eacute; es lo que hacemos, esta parte de la entrevista es la m&aacute;s libre y abierta, suelen surgir preguntas de todo tipo y que dependen &uacute;nicamente de la curiosidad del entrevistado. Intentamos mostrar la mayor transparencia posible sea cu&aacute;l sea la pregunta.</p><p>La tasa de descartes en esta fase suele ser del <strong>50%.</strong></p><h2>Prueba t&eacute;cnica</h2><p><img alt="prueba-t&eacute;cnica" loading="lazy" src="/cache/thumb_1200_0200/uploads/content/image/image/23648606d956dc8db057777e9edd51b8cec6a77b.jpg" title="prueba-t&eacute;cnica"></p><p>La prueba t&eacute;cnica nos sirve para saber si el candidato posee los conocimientos t&eacute;cnicos adecuados. No es una prueba complicada y aunque existan algunas partes en las que no se disponga de un conocimiento adecuado, se podr&aacute; superar poniendo un poco de empe&ntilde;o.</p><p><strong>Se puede resolver de diversas formas</strong>. La forma en la que se resuelva nos dar&aacute; las claves para saber con qu&eacute; tipo de programador hemos topado. <strong>No solemos descartar a casi nadie en esta fase ya que evaluamos seg&uacute;n factores que nos ha contado el candidato anteriormente.</strong></p><h2>Reuni&oacute;n del equipo</h2><p>Todo el proceso esta dise&ntilde;ado para que al final llegue un peque&ntilde;o grupo de personas a las que, tras una reuni&oacute;n de equipo, ordenaremos de mayor a menor <strong>teniendo en cuenta una ponderaci&oacute;n realizada a trav&eacute;s de los siguientes factores:</strong></p><ol><li>Feeling personal / soft skills.</li><li>Objetivos a medio-largo plazo.</li><li>Conocimientos t&eacute;cnicos requeridos.</li><li>Conocimientos t&eacute;cnicos adicionales del candidato.</li><li>Expectativas salariales.</li></ol><p>Cada parte de nuestro equipo tiene opiniones diferentes al resto, por ello esta especie de ranking ponderado nos aporta una visi&oacute;n general de los entrevistados teniendo en cuenta las opiniones subjetivas de todo el equipo.</p><h2>Oferta al candidato</h2><p><img alt="correo" loading="lazy" src="/cache/thumb_1200_0400/uploads/content/image/image/1a9ea944d457eb2593b576b6208a499393b42d64.jpg" title="correo"></p><p>Una vez ordenados de mayor a menor seg&uacute;n la preferencia del equipo, nos ponemos en contacto con el candidato que m&aacute;s nos ha gustado para hacerle la oferta final y recordarle las condiciones pactadas. Le enviaremos la oferta por correo.</p><p><strong>Normalmente aceptan la oferta</strong>. Si han llegado hasta aqu&iacute; es porque existe &ldquo;buen feeling&rdquo; entre ambas partes. En caso de no aceptar, pasar&iacute;amos al siguiente candidato, llevando a cabo el mismo proceso.</p><h2>&iquest;Y los no seleccionados?</h2><p>Todos los candidatos que no han superado alguna de las pruebas como podr&iacute;a ser la entrevista personal y la t&eacute;cnica, no se convierten en candidatos descartados, simplemente no han sido seleccionados y se lo comunicaremos explicando el motivo. <strong>De esta manera podemos ayudarle a mejorar en futuros procesos de reclutamiento.</strong></p>
]]></description><guid>https://devtia.com/post/nuestro-proceso-de-seleccion</guid><pubDate>Fri, 01 May 2020 11:12:44 +0200</pubDate></item><item><title>Maneja Intellij IDEA como una bestia: refactoring</title><link>https://devtia.com/post/maneja-intellij-idea-como-una-bestia-refactoring</link><description><![CDATA[<div class="alert alert-warning mt-5 mb-5" role="alert">En esta entrada mostramos los atajos por defecto de teclado disponibles para WINDOWS / LINUX. Consulta en la web de Jetbrains los atajos correspondientes a OSX.</div><p><strong>Intellij IDEA</strong> junto con el resto de "sabores" del mismo como es <strong>PHPStorm</strong>, <strong>PyCharm</strong>, <strong>WebStorm</strong> es considerado por muchos <strong>el mejor entorno de desarrollo integrado que existe en la actualidad</strong>.</p><p>Esta entrada forma parte de una serie en la que vamos a aprender a usar este editor de forma profesional, a trav&eacute;s del conocimiento de los diferentes atajos de teclado disponibles, as&iacute; como de otras funcionalidades muy &uacute;tiles para el d&iacute;a a d&iacute;a.</p><p>En esta entrada vamos a centrarnos en una de las caracter&iacute;sticas m&aacute;s potentes del IDE <strong>la refactorizaci&oacute;n</strong>.</p><h2>Recomendaciones previas</h2><p><strong>No es necesario que te aprendas todos el primer d&iacute;a.</strong> Te recomendamos elegir dos o tres atajos de teclado. Los que te parezcan m&aacute;s &uacute;tiles y los apuntes en un posit junto a la pantalla para que no se te olviden. Practica con ellos durante algunos d&iacute;as y una vez que los tengas dominados, contin&uacute;es tu aprendizaje con otro grupo de dos o tres.</p><p>El primer atajo de teclado que vamos a recomendarte en cada una de las entradas, es encontrar una acci&oacute;n.</p><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Encontrar una acci&oacute;n</h3><p><kbd>ALT</kbd> + <kbd>SHIFT</kbd> + <kbd>A</kbd></p><p>Con este atajo podemos lanzar el men&uacute; de selecci&oacute;n de acci&oacute;n. Este atajo es de los m&aacute;s &uacute;tiles ya que te muestra el atajo de la acci&oacute;n que est&aacute;s buscando por lo que puedes utilizarlo cuando no te acuerdes del atajo que quieres lanzar de forma que vas a poder aprenderlos poco a poco.</p></div><div class="col-sm-4"><img alt="encontrar una acci&oacute;n" class="img-fluid" loading="lazy" src="/uploads/content/image/image/d9cc3c9f067bd8216717c701ade184884bede663.gif"></div></div><h2>Refactorizaci&oacute;n con Intellij IDEA</h2><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Renombrar variable, funci&oacute;n, m&eacute;todo o clase</h3><p><kbd>SHIFT</kbd> + <kbd>F6</kbd></p><p>Con este atajo podemos renombrar una variable, una funci&oacute;n o m&eacute;todo o una clase. El entorno de desarrollo buscar&aacute; todas las apariciones de dicho elemento y los actualizar&aacute;. Si se trata de una clase cambiar&aacute; el nombre del fichero que lo contiene.</p></div><div class="col-sm-4"><img alt="renombrar variable, funci&oacute;n, m&eacute;todo o clase" class="img-fluid" loading="lazy" src="/uploads/content/image/image/c4e615b53f8a8c639453f093aabb7c205e8b27d2.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Extraer constante</h3><p><kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>C</kbd></p><p>Con este atajo podemos extraer un valor a una constante de la clase.</p></div><div class="col-sm-4"><img alt="extraer constante" class="img-fluid" loading="lazy" src="/uploads/content/image/image/e840c4447b04571a32c26d5696e5a35aa99d3708.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Extraer propiedad</h3><p><kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>F</kbd></p><p>Con este atajo podemos extraer un valor a una propiedad de la clase.</p></div><div class="col-sm-4"><img alt="extraer propiedad" class="img-fluid" loading="lazy" src="/uploads/content/image/image/59447d269e1d10833af7b01c2b04434c61272fc8.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Extraer variable</h3><p><kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>V</kbd></p><p>Con este atajo podemos extraer un valor a una variable del m&eacute;todo.</p></div><div class="col-sm-4"><img alt="extraer variable" class="img-fluid" loading="lazy" src="/uploads/content/image/image/e2548704fe27c86eb6653f59f89ad908726b54d6.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Extraer parametro</h3><p><kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>P</kbd></p><p>Con este atajo podemos extraer un valor a un par&aacute;metro del m&eacute;todo.</p></div><div class="col-sm-4"><img alt="extraer parametro" class="img-fluid" loading="lazy" src="/uploads/content/image/image/5c3804d89ebb582dea37ff8343c79864495d9779.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Extraer m&eacute;todo</h3><p><kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>M</kbd></p><p>Con este atajo podemos extraer un bloque de c&oacute;digo a un m&eacute;todo de la clase. El entorno de desarrollo buscar&aacute; coincidencias del mismo fragmento de c&oacute;digo y nos ofrecer&aacute; reemplazarlas por el nuevo m&eacute;todo.</p></div><div class="col-sm-4"><img alt="extraer m&eacute;todo" class="img-fluid" loading="lazy" src="/uploads/content/image/image/40dcdc71ccdbc0dd74ebc15cbb4423c3e6cee0b4.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Cambiar la firma de un m&eacute;todo</h3><p><kbd>CTRL</kbd> + <kbd>F6</kbd></p><p>Con este atajo podemos cambiar la firma de un m&eacute;todo. El entorno de desarrollo buscar&aacute; todas las llamadas a ese m&eacute;todo y actualizar&aacute; el c&oacute;digo con la nueva firma.</p></div><div class="col-sm-4"><img alt="cambiar la firma de un m&eacute;todo" class="img-fluid" loading="lazy" src="/uploads/content/image/image/f90e90f2fd7bd0cb2d7d3c4ac7a33113ec7de473.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Mover una clase</h3><p><kbd>F6</kbd></p><p>Este atajo nos va a permitir mover una clase a otro directorio. El entorno de desarrollo actualizar&aacute; el namespace y buscar&aacute; todas las referencias y las actualizar&aacute; tambi&eacute;n.</p></div><div class="col-sm-4"><img alt="mover una clase" class="img-fluid" loading="lazy" src="/uploads/content/image/image/63acca6bd89952ba6f1721cee62d639f33520904.gif"></div></div><p class="mt2"></p>
]]></description><guid>https://devtia.com/post/maneja-intellij-idea-como-una-bestia-refactoring</guid><pubDate>Tue, 27 Oct 2020 12:44:27 +0100</pubDate></item><item><title>Maneja Intellij IDEA como una bestia: navegación</title><link>https://devtia.com/post/maneja-intellij-idea-como-una-bestia-navegacion</link><description><![CDATA[<div class="alert alert-warning mt-5 mb-5" role="alert">En esta entrada mostramos los atajos por defecto de teclado disponibles para WINDOWS / LINUX. Consulta en la web de Jetbrains los atajos correspondientes a OSX.</div><p>En esta entrada vamos a centrarnos en como <strong>navegar de la forma m&aacute;s productiva posible</strong> es decir llegar en el menor tiempo posible al lugar al que queremos llegar, tanto si es a otro fichero como si es a una zona diferente del fichero en el que nos encontramos.</p><h2>Recomendaciones previas</h2><p><strong>No es necesario que te aprendas todos el primer d&iacute;a.</strong> Te recomendamos elegir dos o tres atajos de teclado. Los que te parezcan m&aacute;s &uacute;tiles y los apuntes en un posit junto a la pantalla para que no se te olviden. Practica con ellos durante algunos d&iacute;as y una vez que los tengas dominados, contin&uacute;es tu aprendizaje con otro grupo de dos o tres.</p><p>El primer atajo de teclado que vamos a recomendarte en cada una de las entradas, es encontrar una acci&oacute;n.</p><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Encontrar una acci&oacute;n</h3><p><kbd>ALT</kbd> + <kbd>SHIFT</kbd> + <kbd>A</kbd></p><p>Con este atajo podemos lanzar el men&uacute; de selecci&oacute;n de acci&oacute;n. Este atajo es de los m&aacute;s &uacute;tiles ya que te muestra el atajo de la acci&oacute;n que est&aacute;s buscando por lo que puedes utilizarlo cuando no te acuerdes del atajo que quieres lanzar de forma que vas a poder aprenderlos poco a poco.</p></div><div class="col-sm-4"><img alt="encontrar una acci&oacute;n" class="img-fluid" loading="lazy" src="/uploads/content/image/image/d9cc3c9f067bd8216717c701ade184884bede663.gif"></div></div><h2>Navegaci&oacute;n entre ficheros</h2><p>En el primer bloque vamos a aprender como desplazarnos entre diferentes ficheros para llegar lo antes posible al documento que queremos llegar.</p><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Buscar la clase o archivo</h3><p><kbd>CTRL</kbd> + <kbd>N</kbd> / <kbd>CTRL</kbd> + <kbd>SHIFT</kbd> + <kbd>N</kbd></p><p>Con este atajo podemos buscar la clase o el archivo al que queremos ir respectivamente. El buscador de archivos funciona incluso si el editor est&aacute; indexando el proyecto.</p></div><div class="col-sm-4"><img alt="abrir y cerrar la vista de proyecto" class="img-fluid" loading="lazy" src="/uploads/content/image/image/d1eb67a1f11274b0560499ee808491bdde9e2d43.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Navegar a la referencia</h3><p><kbd>CTRL</kbd> + <kbd>B</kbd> / <kbd>CTRL</kbd> + <kbd>CLICK</kbd></p><p>Con este atajo podemos navegar hacia la definici&oacute;n de una clase o m&eacute;todo. Si existen varias disponibles, nos mostrar&aacute; todas las opciones. Si tienes instalado y configurado el plugin de symfony te permite navegar entre rutas o definiciones de plantillas.</p></div><div class="col-sm-4"><img alt="navegar a la referencia" class="img-fluid" loading="lazy" src="/uploads/content/image/image/3329cd0a5c84db70cf2cecc5ba214c17161deda4.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Navegar a hacia delante o hacia atr&aacute;s</h3><p><kbd>ALT</kbd> + <kbd>SHIFT</kbd> + <kbd>LEFT</kbd> / <kbd>ALT</kbd> + <kbd>SHIFT</kbd> + <kbd>RIGHT</kbd></p><p>Con este atajo podemos navegar hacia delante o hacia atr&aacute;s en la navegaci&oacute;n que hemos realizado.</p></div><div class="col-sm-4"><img alt="navegar a hacia delante o hacia atr&aacute;s" class="img-fluid" loading="lazy" src="/uploads/content/image/image/1d6ec26aadce4e6dc64f994ab18a305c7396cf55.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Ver ficheros visitados recientemente</h3><p><kbd>CTRL</kbd> + <kbd>E</kbd></p><p>Con este atajo podemos navegar entre los ficheros que hemos visitado recientemente.</p></div><div class="col-sm-4"><img alt="ver ficheros abiertos recientemente" class="img-fluid" loading="lazy" src="/uploads/content/image/image/3b981d74b3804e511a3bfee4167a445d31223182.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Ver localizaciones visitadas recientemente</h3><p><kbd>CTRL</kbd> + <kbd>SHIFT</kbd> + <kbd>E</kbd></p><p>Con este atajo podemos navegar entre los bloques de c&oacute;digo que hemos visitado recientemente.</p></div><div class="col-sm-4"><img alt="ver localizaciones visitadas recientemente" class="img-fluid" loading="lazy" src="/uploads/content/image/image/f208e93171b0c93bfc0cf7fa8bfc2960dfa3a2b4.gif"></div></div><h2>Navegaci&oacute;n dentro de un fichero</h2><p>A continuaci&oacute;n vamos a ver los atajos que consideramos m&aacute;s interesantes y que nos van a permitir navegar dentro de un mismo fichero muy r&aacute;pidamente y sin utilizar el rat&oacute;n.</p><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Ver estructura</h3><p><kbd>CTRL</kbd> + <kbd>F12</kbd></p><p>Con este atajo nos abre la vista de estructura para poder navegar f&aacute;cilmente entre los diferentes m&eacute;todos de una clase.</p></div><div class="col-sm-4"><img alt="ver estructura" class="img-fluid" loading="lazy" src="/uploads/content/image/image/64982115b681a1ffc44f28c0755503d6a299c9ce.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">M&eacute;todo anterior o siguiente</h3><p><kbd>ALT</kbd> + <kbd>UP</kbd> / <kbd>ALT</kbd> + <kbd>DOWN</kbd></p><p>Con este atajo podemos desplazarnos entre los diferentes m&eacute;todos de la clase.</p></div><div class="col-sm-4"><img alt="m&eacute;todo anterior o siguiente" class="img-fluid" loading="lazy" src="/uploads/content/image/image/4e54af804744ecae1d58c316a245eaf67c9dd981.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Ir al siguiente error</h3><p><kbd>F2</kbd></p><p>Con este atajo podemos desplazarnos al siguiente error dentro de un fichero.</p></div><div class="col-sm-4"><img alt="ir al siguiente error" class="img-fluid" loading="lazy" src="/uploads/content/image/image/97b5f7df8dba8f16032d8cfa9787f216f5eca48b.gif"></div></div><div class="row mt-5"><div class="col-sm-8"><h3 class="mt-0">Saltar a la l&iacute;nea</h3><p><kbd>CTRL</kbd> + <kbd>G</kbd></p><p>Con este atajo podemos desplazarnos directamente a la l&iacute;nea a la que nos queremos mover.</p></div><div class="col-sm-4"><img alt="saltar a la l&iacute;nea" class="img-fluid" loading="lazy" src="/uploads/content/image/image/1398eb9077ccadb35492a8dcc5e52ac880e0aab6.gif"></div></div><p class="mt-5">Te recomendamos que leas todos los atajos disponibles tanto en la web de jetbrains como en la configuraci&oacute;n de atajos de teclado de tu editor para que descubras por t&iacute; mismo todos los atajos disponibles.</p><p>Si te gustar&iacute;a recibir una entrada como esta cada semana en tu bandeja de entrada: ap&uacute;ntate a nuestra academia.</p>
]]></description><guid>https://devtia.com/post/maneja-intellij-idea-como-una-bestia-navegacion</guid><pubDate>Sun, 25 Oct 2020 18:00:38 +0100</pubDate></item><item><title>Código limpio: Organiza tus clases</title><link>https://devtia.com/post/codigo-limpio-organiza-tus-clases</link><description><![CDATA[<p>En la &uacute;ltima entrada realizamos una introducci&oacute;n a las <a href="/post/codigo-limpio-pruebas-automaticas">pruebas autom&aacute;ticas</a>. En esta entrada vamos a ver las reglas que utilizamos nosotros para mantener organizadas las clases que escribimos.</p><h2>Elige tu estilo</h2><p>En mi opini&oacute;n no tan importante que reglas utilices para organizar tus clases. Lo que s&iacute; es muy importante, es que <strong>elijas unas y te comprometas con ellas</strong>. Tambi&eacute;n es muy importante que <strong>no seas dogm&aacute;tico</strong> y que <strong>est&eacute;s dispuesto a a&ntilde;adir o modificar tus reglas si es que aparecen otras mejores</strong>.</p><p>No hay nada m&aacute;s frustrante que tratar de explicar a un desarrollador una forma mejor de hacer las cosas, y que no sea capaz de salir de sus trece, pero que tampoco sea capaz de argumentar un motivo.</p><p>Dentro de las reglas que elijas ten en cuenta <strong>que nada debe quedar al azar</strong>, si no que se note que <strong>todo est&aacute; de una forma determinada por un motivo determinado</strong> y no simplemente por que ha quedado as&iacute;.</p><h2>Nuestro estilo</h2><p>Nosotros utilizamos la <a href="https://symfony.com/doc/current/contributing/code/standards.html">guia de estilo</a> oficial para symfony ya que es el framework con el que trabajamos. Adem&aacute;s es muy sencillo configurar el editor para que las aplique autom&aacute;ticamente.</p><p>A continuaci&oacute;n vamos a explicar el resto de reglas que utilizamos nosotros y que no son exactamente iguales a las que describe el autor en el libro. Pero que vamos a argumentarte los motivos que hemos tenido en cuenta para elegirlas.</p><p>Para ello vamos a analizar la clase <code>Rectangle</code> que ya conocemos de entradas anteriores.</p><p>Casi todo lo que vamos a ver son esos peque&ntilde;os detalles que forman parte de nuestra pol&iacute;tica de no dejar nada al azar, y que probablemente <strong>no supongan una gran diferencia por s&iacute; s&oacute;los</strong>, pero que <strong>en conjunto y adoptadas por todo el equipo</strong>, nos permiten <strong>generar una base de c&oacute;digo de calidad</strong> en todos nuestros proyectos.</p><p>Vamos a describir las reglas leyendo la clase de arriba a abajo.</p><h3>Cabecera</h3><p>La cabecera es normalmente un fragmento de c&oacute;digo comentado que se pone encima de cada fichero. Deber&iacute;a indicar a que proyecto pertenece, que tipo de licencia aplica y que personas han intervenido en ella.</p><p>Lo m&aacute;s habitual es utilizar alguna herramienta para <strong>asegurar que todos los ficheros tienen la cabecera correcta</strong> y esta est&aacute; actualizada a la &uacute;ltima versi&oacute;n.</p><pre><code class="php">/*
 * This file is part of the clean code example package.
 *
 * Copyright (c) 2016-2020 Devtia Soluciones.
 * All rights reserved.
 *
 * @author Daniel Gonz&aacute;lez &lt;daniel@devtia.com&gt;
 */
final class Rectangle
{
    //..
}</code></pre><h3>La definici&oacute;n de la clase</h3><p>Nosotros <strong>intentamos por defecto ser lo m&aacute;s restrictivos posible</strong>, y luego ir abriendo la visibilidad seg&uacute;n sea necesario. Por eso siempre declaramos nuestras clases por defecto como <code>final</code>. Una palabra reservada que nos permite indicar que la clase no puede extenderse.</p><h3>Las constantes de clase</h3><p>Nosotros habitualmente <strong>separamos las constantes en clases independientes</strong>. Por ejemplo, si quisi&eacute;ramos poner los colores como constantes, es mejor crear una clase diferente para contenerlos. De esta forma mejoramos la sem&aacute;ntica del dominio.</p><pre><code class="php">final class Color
{
    const WHITE = 'FFFFFF';
    const BLACK = '000000';
}</code></pre><h3>Atributos</h3><p>Como norma general declaramos todos atributos como <code>private</code>. Si fuera necesario cuando realizamos un dise&ntilde;o, algunos de estos los declaramos como <code>protected</code> y evitamos siempre los atributos <code>public</code> salvo cuando se trata de DTOs.</p><p>Si tenemos atributos de diferente visibilidad dentro de una clase los agrupamos seg&uacute;n su visibilidad.</p><p>Dentro de cada grupo, <strong>ordenamos los atributos por orden de importancia</strong>. Los m&aacute;s importantes arriba. <strong>Tambi&eacute;n tratamos de agruparlos por tipo</strong>, para que est&eacute;n todas las fechas juntas, todos las colecciones juntas, ...</p><pre><code class="php">final class Rectangle
{
    /* @var Point */
    private $topLeft;

    /** @var Color */
    private $backgroundColor;

    /** @var Color */
    private $borderColor;

    /* @var float */
    private $border;

    /* @var float */
    private $height;

    /* @var float */
    private $width;

    //..
}</code></pre><h3>El constructor y el resto m&eacute;todos m&aacute;gicos</h3><p>A continuaci&oacute;n de los atributos <strong>escribimos el constructor de la clase</strong>. <strong>Una clase no deber&iacute;a encontrarse en una situaci&oacute;n inconsistente</strong>. Por eso <strong>el constructor deber&iacute;a recibir todo aquello que la clase necesita para existir</strong>. De esta forma evitamos por ejemplo la existencia de un <code>Rectangle</code> cuya altura est&aacute; sin definir.</p><pre><code class="php">final class Rectangle
{
    //..
    public function __construct(Point $topLeft, float $height, float $width)
    {
        $this-&gt;topLeft = $topLeft;
        $this-&gt;height = $height;
        $this-&gt;width = $width;
    }
    //..
}</code></pre><p>Los metodos m&aacute;gicos son m&eacute;todos que est&aacute;n definidos para todas las clases en php, y que son invocados cuando ocurre una circustancia concreta. Nosotros los definimos por orden alfab&eacute;tico despu&eacute;s del constructor.</p><h3>Los m&eacute;todos p&uacute;blicos</h3><p>Nosotros ordenamos los m&eacute;todos agrup&aacute;ndolos por visibilidad. Arriba del todos los m&eacute;todos <code>public</code> luego todos los <code>protected</code> y finalmente todos los <code>private</code>.</p><p>El autor nos indica que se deber&iacute;an ordenar seg&uacute;n su importancia y mantener los m&eacute;todos relacionados cerca entre s&iacute;. Nosotros creemos que esto podr&iacute;a tener sentido en el momento de publicar el libro, pero es una regla dificil de aplicar, cuando por ejemplo un mismo m&eacute;todo se llama desde diferentes m&eacute;todos, &iquest;junto a cual lo pones?</p><p>Los editores modernos nos permiten navegar con facilidad entre m&eacute;todos a&uacute;nque no est&eacute;n cercanos entre s&iacute;, asi que nosotros <strong>simplemente los ordenamos alfabeticamente</strong> y <strong>configuramos el editor para que haga esto autom&aacute;ticamente</strong> por nosotros.</p><h3>El resto de m&eacute;todos</h3><p>Los m&eacute;todos que no son <code>public</code> deber&iacute;an declararse <code>private</code> a menos que exista una buena raz&oacute;n para ello. Los ordenamos tambi&eacute;n por orden alfab&eacute;tico y dejamos que el editor se encarge de esta tarea.</p><h3>Bloques de c&oacute;digo</h3><p>Para explicar esto es necesario traer un ejemplo un poco m&aacute;s complejo. Veamos un ejemplo real de uno de nuestros proyectos.</p><pre><code class="php">final class ProposalController extends AbstractProposalController
{
    //..
    public function copyAction(Project $proposal)
    {
        $this-&gt;throwNotFoundExceptionIfNotIsPublicProposal($proposal);

        $copyManager = $this-&gt;get('app.service.project_copy_manager');
        $publicProposal = $copyManager-&gt;generatePublicProposal(
            $proposal,
            null,
            \AppBundle\Entity\Project\Type::PUBLIC_PROPOSAL_CLIENT_VERSION
        );

        $manager = $this-&gt;get('app.service.project_manager');
        $manager-&gt;update($publicProposal);

        $this-&gt;addFlash('success', 'proposal successfully updated');

        return $this-&gt;redirectToRoute('_public.proposal.view', ['hash' =&gt; $publicProposal-&gt;getHash()]);
    }
    //..
}</code></pre><p>Si ves el ejemplo anterior puedes ver que <strong>cada concepto est&aacute; separado por un salto de l&iacute;nea</strong>. Lo primero que hacemos es la validaci&oacute;n o cl&aacute;usulas de guarda, de las que hablaremos en otra entrada m&aacute;s adelante.</p><p>Lo siguiente que hacemos es obtener una copia de la propuesta a trav&eacute;s del servicio correspondiente. Despu&eacute;s actualizamos esa copia, mensaje de &eacute;xito y redirecci&oacute;n a la nueva propuesta.</p><p>Cada concepto est&aacute; separado por un salto de l&iacute;nea facilitando su entendimiento al lector.</p><h3>Ni un salto de l&iacute;nea de m&aacute;s</h3><p>El &uacute;ltimo detalle. Ya hemos visto donde s&iacute; debemos poner un salto de l&iacute;nea. En nuestra opini&oacute;n <strong>no se deben a&ntilde;adir saltos de l&iacute;nea adicionales</strong>, porque dan la sensaci&oacute;n de estar ah&iacute; por que s&iacute;, en lugar de porque tienen que estar.</p>
]]></description><guid>https://devtia.com/post/codigo-limpio-organiza-tus-clases</guid><pubDate>Thu, 24 Sep 2020 13:45:45 +0200</pubDate></item><item><title>Código limpio: No hables con extraños</title><link>https://devtia.com/post/codigo-limpio-no-hables-con-extranos</link><description><![CDATA[<p>En la &uacute;ltima entrada repasamos qu&eacute; son <a href="/post/codigo-limpio-estructuras-vs-objetos">las estructuras de datos</a>, en que se diferencian de los objetos y cu&aacute;ndo conviene m&aacute;s utilizar una aproximaci&oacute;n u otra. En esta entrada vamos a explicar cual es la ley de demeter, que problemas puedes tener si es que no la cumples y que opciones tienes para cumplirla.</p><p>Empezemos describiendo los motivos por los que <strong>no deber&iacute;as hablar con extra&ntilde;os:</strong> muchas veces cuando tenemos una clase que a su vez est&aacute; formada por objetos de otras clases y estas a su vez por otras, tenemos una estructura de clases. Hasta aqu&iacute; todo bien, pero: &iquest;qu&eacute; ocurre cuando estas estructuras se vuelven complejas? Veamos un ejemplo que podr&iacute;a darse en un comando de symfony.</p><pre><code class="php">class CustomCommand extends Command
{
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $this-&gt;getApplication()-&gt;getKernel()-&gt;getContainer()-&gt;getCustomService()-&gt;getManager()-&gt;execute();

        return 1;
    }
}</code></pre><p>Como puedes ver, estamos <strong>acoplando de forma innecesaria</strong> nuestro c&oacute;digo a todas las clases que aparecen en la cadena de llamadas. Cualquier cambio en estas clases o en las relaciones entre ellas podr&iacute;a suponer que nuestro c&oacute;digo dejase de funcionar. Para que esto no suceda viene al rescate la ley de demeter.</p><h2>La ley de demeter</h2><p><img alt="La ley de demeter" loading="lazy" src="/cache/thumb_1200_0200/uploads/content/image/image/f0a9a0fb4bc402545242cec37f8a0821462dce05.jpg"></p><p>La ley de demeter fue descrita por primera vez dentro del proyecto demeter en 1987. Como curiosidad quiero contarte que Demeter, hace referencia a la diosa griega de la agricultura. Querian hacer referencia a algo as&iacute; como "cultivar" software en contraposici&oacute;n a "construir" el software.</p><p>La ley indica que desde un m&eacute;todo <strong>solo deber&iacute;as "hablar" con aquellos a quien conozcas bien</strong>. Y estos son:</p><ul><li>M&eacute;todos de la misma clase.</li><li>M&eacute;todos de los objetos de la clase.</li><li>M&eacute;todos de los objetos creados en la misma funci&oacute;n.</li><li>M&eacute;todos de los objetos pasados como argumento a la funci&oacute;n.</li></ul><h2>&iquest;Y c&oacute;mo lo soluciono?</h2><p>Ya hemos detectado que es lo que no debes hacer, te voy a proponer ahora tres opciones a tener en cuenta cuando detectes este problema en tu c&oacute;digo.</p><h3>No hacer nada</h3><p>La primera es no hacer nada. Es la soluci&oacute;n m&aacute;s sencilla, y <strong>la peor de las tres</strong> que vamos a ver, pero como ya vimos en la entrada sobre <a href="/post/los-dogmas-en-el-desarrollo-de-software">los dogmas en el desarrollo de software</a>, si crees que las clases que est&aacute;s llamando y sus relaciones est&aacute;n muy consolidadas, podr&iacute;as permitirte el lujo de realizar este tipo de llamadas en cadena.</p><h3>Usar atajos</h3><p>La segunda consiste en hacer atajos que permitan evitar estas llamadas encadenadas. Esta es una soluci&oacute;n bastante r&aacute;pida, que te puede permitir salir del paso en alg&uacute;n momento.</p><p>Por ejemplo en <code>CustomService</code> podr&iacute;amos a&ntilde;adir el m&eacute;todo <code>executeManager</code>.</p><pre><code class="php">class CustomService
{
    public function executeManager(): void
    {
        $this-&gt;getManager()-&gt;execute();
    }
}</code></pre><p>Esta soluci&oacute;n como puedes imaginarte tampoco es la mejor. Te permite abstraer parte de esa cadena de llamadas y por lo tanto es una opci&oacute;n mejor que al principio, ya que si la relacion cambia s&oacute;lo tendr&aacute;s que cambiar en este punto las llamadas.</p><p>El problema de esta soluci&oacute;n es que puedes encontrarte con tu c&oacute;digo con un mont&oacute;n de estos m&eacute;todos atajos, que realmente por dise&ntilde;o no deber&iacute;an encontraser ah&iacute;, pero est&aacute;n simplemente para hacer cumplir la ley de demeter.</p><h3>Inyectar dependencias</h3><p>La soluci&oacute;n buena, como probablemente ya te ven&iacute;as imaginando es <strong>inyectar las dependencias</strong>. Veamos un ejemplo.</p><pre><code class="php">class CustomCommand extends Command
{
    public function setCustomManager(CustomManager $customManager)
    {
        $this-&gt;manager = $customManager;
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $this-&gt;manager-&gt;execute();
    }
}</code></pre><p>Hemos a&ntilde;adido como dependencia la clase <code>CustomManager</code> que era la que realmente necesitamos, y se la hemos inyectado a trav&eacute;s de un setter, pero hemos eliminado toda la cadena de dependencias y las relaciones entre s&iacute;.</p><p>Con este sencillo cambio hemos podido eliminar f&aacute;cilmente todas las dependencias sobrantes.</p>
]]></description><guid>https://devtia.com/post/codigo-limpio-no-hables-con-extranos</guid><pubDate>Sat, 29 Aug 2020 10:49:10 +0200</pubDate></item><item><title>Los dogmas en el desarrollo de software</title><link>https://devtia.com/post/los-dogmas-en-el-desarrollo-de-software</link><description><![CDATA[<p>Esta entrada es un alto en el camino, dentro de la serie que estamos realizando sobre <a href="/post/codigo-limpio-indice-de-contenidos">el libro Clean Code de Robert C Martin</a>.</p><p>La semana pasada publicamos una entrada sobre <a href="/post/codigo-limpio-deja-de-comentar">el uso de los comentarios</a>. En ella explic&aacute;bamos que siempre que puedas <strong>deber&iacute;as evitar el uso de comentarios</strong>.</p><p>Argument&aacute;bamos que cuando <strong>utilizas un comentario para explicar un c&oacute;digo que no se entiende con facilidad</strong>, no est&aacute;s mejorando tu c&oacute;digo, sino que <strong>est&aacute;s poniendo una piedra en tu camino</strong>. Tu c&oacute;digo sigue siendo igual de dif&iacute;cil de entender y adem&aacute;s ahora te tendr&aacute;s que ocupar de mantener esos comentarios actualizados. Lo cual no aporta valor a tu proyecto.</p><p>Muchas personas nos han escrito tanto por Linkedin, Twitter, Youtube y el grupo privado que tenemos en Telegram para tratar temas del canal.</p><p>Nos han indicado diferentes ejemplos en el que era muy dif&iacute;cil eliminar los comentarios o directamente no se pod&iacute;an. No quiero entrar aqu&iacute; a revisar cada uno de los ejemplos, pero tras revisarlo con el equipo, era evidente que eran buenos ejemplos. <strong>En esos casos, los comentarios si ayudaban a mejorar el c&oacute;digo</strong>.</p><p>Es por eso que quiero hablar un poco sobre los dogmas.</p><h2>Los dogmas en el desarrollo de software</h2><p><strong>Existen</strong> por supuesto <strong>muchos dogmas en el mundo del desarrollo de software</strong>, seguro que te suenan algunos de estos:</p><ol><li>Si no haces scrum estricto no haces scrum.</li><li>No se puede sacar adelante un proyecto sin pruebas autom&aacute;ticas.</li><li>En 2020 todo el mundo tiene que hacer DDD.</li></ol><p>Estas y otras muchas que se te ocurran las hemos escuchado todos cientos de veces.</p><h2>Poner un hombre en la luna</h2><p><img alt="Sin las mejores pr&aacute;cticas del momento actual fueron capaces de poner un hombre en la luna" loading="lazy" src="/cache/thumb_1200_0400/uploads/content/image/image/94e95d9b4b485726ede6d478ee0530679b4258dc.jpg" title="Sin las mejores pr&aacute;cticas del momento actual fueron capaces de poner un hombre en la luna"></p><p>Corr&iacute;a el a&ntilde;o 1957, estados unidos y la uni&oacute;n sovi&eacute;tica se encontraban enfrascados en mitad de la guerra fr&iacute;a, cuando los sovi&eacute;ticos pusieron por primera vez un sat&eacute;lite en &oacute;rbita, el sputnik. Esto supuso un gran varapalo para la sociedad americana, que crear&iacute;a la NASA. Hab&iacute;a comenzado la carrera espacial.</p><p>12 a&ntilde;os m&aacute;s tarde en cabo ca&ntilde;averal despega un cohete con tres astronautas y una misi&oacute;n: "poner un hombre en la luna". Los estados unidos tuvieron que hacer un gran esfuerzo en el desarrollo de la tecnolog&iacute;a inform&aacute;tica, ya que aquel cohete ten&iacute;a un computador capaz de guiarlo. Ese computador por supuesto ejecutaba software, y ese software fue programado 30 a&ntilde;os antes de que se publicara el manifiesto &aacute;gil.</p><p>Es decir que <strong>sin las consideradas mejores pr&aacute;cticas del momento actual, sin el framework de moda</strong>, este equipo de programadores <strong>fueron capaces de dise&ntilde;ar y programar un software que puso a un hombre en la luna</strong>.</p><h2>La flexibilidad y empat&iacute;a</h2><p><img alt="Lo m&aacute;s importante es tu capacidad para adaptarte a las necesidades de cada situaci&oacute;n" loading="lazy" src="/cache/thumb_1200_0400/uploads/content/image/image/018e8317157f988e9e8198640e24557ef4def4d5.jpg" title="Lo m&aacute;s importante es tu capacidad para adaptarte a las necesidades de cada situaci&oacute;n"></p><p><strong>Lo mejor es ser capaz de adaptarse a cada situaci&oacute;n</strong>, este es el &uacute;nico dogma que te tienes que grabar a fuego.</p><p><strong>Pensar que s&oacute;lo hay un camino</strong> para hacer las cosas bien es cuando menos <strong>una postura algo miope</strong>. Si alguien piensa que su metodolog&iacute;a / tecnolog&iacute;a / framework / loquesea es netamente superior a las todas las dem&aacute;s est&aacute; evidentemente equivocado.</p><p>Te voy a poner un ejemplo personal. La t&eacute;cnica del dise&ntilde;o dirigido por test (TDD) es una t&eacute;cnica que te ayuda a dise&ntilde;ar software escribiendo primero las pruebas y luego el c&oacute;digo de producci&oacute;n. Al hacerlo al rev&eacute;s, haciendo primero las pruebas, te ayuda a que pienses en tu dise&ntilde;o desde fuera hacia dentro, en lugar de como lo har&iacute;as habitualmente, desde dentro hacia afuera.</p><p>Yo estuve haciendo TDD durante aproximadamente un a&ntilde;o. Despu&eacute;s dej&eacute; de hacerlo. &iquest;Por qu&eacute;? Pues por dos motivos. Primero porque una vez que asimilas bien la metodolog&iacute;a, vas a ser capaz de pensar desde fuera hacia dentro sin necesidad de escribir primero el test y segundo porque en muchos proyectos el dise&ntilde;o no es algo crucial.</p><p>En mi opini&oacute;n <strong>tu criterio vale m&aacute;s que lo que alguien escribiera en un libro</strong> en la punta del mundo hace veinte a&ntilde;os.</p><h2>No dejes de aprender</h2><p>Que los dogmas no sean realmente dogmas, no es una excusa para no seguir aprendiendo o mejorando. En mi opini&oacute;n es tu responsabilidad como buen profesional ir mejorando cada vez tus capacidades.</p><p>Adem&aacute;s es una buena forma de disfrutar de nuestra profesi&oacute;n y por que no decirlo de ganar cada vez m&aacute;s dinero. No se paga igual de bien a alguien que programa en el lenguaje "a pelo" que a un "tope de gama" en la &uacute;ltima metodolog&iacute;a o framework de moda.</p><p>Te propongo algunos consejos para que no dejes de aprender.</p><p><strong>Busca un buen proyecto</strong> La forma m&aacute;s f&aacute;cil de seguir mejorando es dedicar ocho horas al d&iacute;a a mejorar, y para ello debes elegir tu puesto de trabajo en funci&oacute;n de donde m&aacute;s vayas a aprender. El dinero y otras ventajas deber&iacute;an pasar a un plano secundario. Da igual que ganes menos dinero el a&ntilde;o que viene, lo importante es cu&aacute;nto dinero vas a ganar el resto de tu vida.</p><p><strong>Sigue canales de youtube y podcast de la tem&aacute;tica</strong>. Una buena forma de seguir aprendiendo es este tipo de contenidos que suelen tener una alta calidad, y no requieren de demasiado esfuerzo, ya que puedes ver este video, mientras que vas en el tren de camino al trabajo o mientras esperas a un amigo.</p><p><strong>Asiste a conferencias y meetups</strong>. Es una forma f&aacute;cil de aprender y de conocer gente. Nunca vas a aprender sobre todo, pero si tienes el tel&eacute;fono del que sabe, tambi&eacute;n puede servir.</p><p><strong>Lee libros</strong> En comparaci&oacute;n con los anteriores es el que m&aacute;s esfuerzo o disciplina requiere, pero si no quieres que te den gato por liebre lo mejor es acudir a la fuente. Leer un libro al a&ntilde;o, puede marcar la diferencia.</p><p>No olvides apuntarte <a href="/academy/">a nuestra academia</a>, para recibir todas las semanas un nuevo video sobre desarrollo de software</p>
]]></description><guid>https://devtia.com/post/los-dogmas-en-el-desarrollo-de-software</guid><pubDate>Fri, 31 Jul 2020 15:08:18 +0200</pubDate></item><item><title>Código limpio: Deja de comentar</title><link>https://devtia.com/post/codigo-limpio-deja-de-comentar</link><description><![CDATA[<p>En esta entrada vamos a analizar cu&aacute;ndo y c&oacute;mo es conveniente el uso de comentarios durante la fase de desarrollo de software.</p><h2>bloques de c&oacute;digo</h2><p>Por regla general <strong>deber&iacute;as evitar el uso de comentarios</strong>. Los comentarios pueden parecer una herramienta muy &uacute;til ya que cuando estamos desarrollando puede que nos encontremos con que queremos explicar mejor c&oacute;mo funciona nuestro c&oacute;digo o por que hemos tomado una determinada decisi&oacute;n.</p><p>Pero cuando usamos un comentario de c&oacute;digo donde antes ten&iacute;amos un problema: que nuestro c&oacute;digo no era suficientemente sencillo de entender, ahora tenemos dos: nuestro c&oacute;digo sigue sin entenderse con facilidad, y ahora adem&aacute;s debo ocuparme de mantener los comentarios que he realizado.</p><p>Puedes pensar que mantener ese comentario no es mucho trabajo, pero que tal si esa energ&iacute;a qu&eacute; has gastado en mantener un comentario la hubieras gastado en <strong>hacer algo m&aacute;s productivo</strong>. &iquest;mejor, no?.</p><p>Vemos un ejemplo con el <code>TokenStorage</code> del componente <code>Security</code> de <code>Symfony</code>.</p><pre><code class="php">namespace Symfony\Component\Security\Core\Authentication\Token\Storage;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Contracts\Service\ResetInterface;

/**
 * TokenStorage contains a TokenInterface.
 */
class TokenStorage implements TokenStorageInterface, ResetInterface
{
    // ..
    public function setToken(TokenInterface $token = null)
    {
        if ($token) {
            // ensure any initializer is called
            $this-&gt;getToken();
        }

        $this-&gt;initializer = null;
        $this-&gt;token = $token;
    }
    //..
}</code></pre><p>El autor de este c&oacute;digo necesitaba hacer algunas llamadas antes de configurar el token. Se dio cuenta que que no era sencillo de entender y que otra persona que viniera detr&aacute;s probablemente no entender&iacute;a el motivo de esa llamada, asi que utiliz&oacute; un comentario para aclararlo todo. &iquest;Pero que te parece si hubiera hecho esto?</p><pre><code class="php">namespace Symfony\Component\Security\Core\Authentication\Token\Storage;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Contracts\Service\ResetInterface;

/**
 * TokenStorage contains a TokenInterface.
 */
class TokenStorage implements TokenStorageInterface, ResetInterface
{
    // ..
    public function setToken(TokenInterface $token = null)
    {
        if ($token) {
            $this-&gt;callInitializer();
        }

        $this-&gt;initializer = null;
        $this-&gt;token = $token;
    }

    private function callInitializer(): void
    {
        $this-&gt;getToken();
    }
    //..
}</code></pre><p>Como ves <strong>hemos eliminado el comentario y hemos mantenido e incluso mejorado la expresividad</strong>, ya que el c&oacute;digo es igual de expl&iacute;cito. Por lo tanto siempre que nos veamos en la necesidad de a&ntilde;adir comentarios, debemos plantearnos si podr&iacute;amos mejorar la expresividad de nuestro c&oacute;digo mejorando los nombres que estamos utilizando o extrayendo m&eacute;todos como en el ejemplo.</p><h2>DocBlock y documentaci&oacute;n autogenerada</h2><p>Algunos editores de texto a&ntilde;aden documentaci&oacute;n de forma m&aacute;s o menos autom&aacute;tica que permite indicar los tipos de los argumentos y del valor devuelto, as&iacute; como informaci&oacute;n adicional.</p><p>Veamos un ejemplo</p><pre><code class="php">    /**
     * get movements
     *
     * @return array
     */
    public function getMovements()
    {
        return $this-&gt;movements;
    }</code></pre><p>Este tipo de documentaci&oacute;n <strong>no aporta ning&uacute;n valor adicional</strong> ya que simplemente est&aacute; repitiendo lo mismo que ya dice el nombre de la funci&oacute;n. Quiz&aacute; esto ten&iacute;a sentido antes de la versi&oacute;n 7, para ayudar al IDE en el autocompletado. Pero a partir de esta versi&oacute;n es mucho mejor eliminar estos comentarios y utilizar el tipado nativo del lenguaje.</p><pre><code class="php">   public function getMovements(): array
    {
        return $this-&gt;movements;
    }</code></pre><h2>Usos permitidos</h2><p>Por supuesto el autor contempla algunos casos en los que s&iacute; estar&iacute;a permitido y justificado el uso de comentarios.</p><h3>Licencias y textos legales</h3><p>Es un uso completamente justificado el incluir la licencia y otros textos legales en el encabezado de nuestros ficheros. Adem&aacute;s esto no supone ning&uacute;n trabajo adicional, por que es habitual utilizar sistemas que se encargan de a&ntilde;adir estos comentarios de forma autom&aacute;tica, y adem&aacute;s los IDE suelen ocultarlos por lo que no molestan.</p><h3>APIs</h3><p>Si est&aacute;s construyendo una api y probablemente quieras generar la documentaci&oacute;n a trav&eacute;s de alg&uacute;n sistema autom&aacute;tico, s&iacute; estar&iacute;a justificado el incluir toda esta informaci&oacute;n adicional en tu c&oacute;digo.</p>
]]></description><guid>https://devtia.com/post/codigo-limpio-deja-de-comentar</guid><pubDate>Fri, 17 Jul 2020 14:46:07 +0200</pubDate></item><item><title>Código limpio: Nombres</title><link>https://devtia.com/post/codigo-limpio-nombres</link><description><![CDATA[<p>En esta entrada vamos a entender y profundizar en la importancia de elegir buenos nombres. Es muy importante que te tomes el tiempo necesario para encontrar un buen nombre, y no debes tener ning&uacute;n miedo a cambiarlo si es que encuentras otro mejor.</p><h2>Evita el uso de contracciones</h2><p>Esta es la primera regla y la m&aacute;s sencilla de todas. Cuando programamos, podemos caer en la tentaci&oacute;n de crear peque&ntilde;as contracciones, dentro de la api de linux por ejemplo nos encontramos con un mont&oacute;n de ellas como por ejemplo <code>mv</code>, <code>cp</code>, <code>chmod</code> y muchas m&aacute;s.</p><p>Cuando escribes una contracci&oacute;n puede que en ese momento a t&iacute; te parezca obvia, pero es posible que para otra persona en otro contexto no lo sea tanto, as&iacute; que no merece la pena ahorrarse unos caracteres a cambio de los problemas que puedas generar en el futuro.</p><p>Adem&aacute;s esta regla te permitir&aacute; no entrar en conflicto con la siguiente que es la consistencia. Si usas una contracci&oacute;n en una variable o m&eacute;todo, &iquest;Por qu&eacute; no usarlo en todas las dem&aacute;s? &iquest;En cu&aacute;les s&iacute; y en cu&aacute;les no? Acabas de crear un problema donde no lo hab&iacute;a.</p><h2>S&eacute; consistente</h2><p><img alt="S&eacute; consistente" loading="lazy" src="/cache/thumb_1200_0400/uploads/content/image/image/17b93e4abdd2e6b2bed5b34fbe251abed368da8d.jpg" title="S&eacute; consistente"></p><p>Una de las caracter&iacute;sticas que vimos del c&oacute;digo limpio es que no es f&aacute;cil de mejorar. Eso significa que el c&oacute;digo es consistente. Si has decidido por ejemplo llamar <code>Lesson</code> a la entidad que representa a un profesor, una asignatura, una colecci&oacute;n de alumnos y un momento concreto en el tiempo, no deber&iacute;as utilizar ning&uacute;n tipo de sin&oacute;nimos.</p><p>Otro elemento que debes tener en cuenta a la hora de producir nombres consistentes es utilizar siempre los mismos verbos para una determinada tarea. Por ejemplo si has decidido que cuando accedas a un repositorio y recuperes un conjunto de lecciones vas a utilizar el verbo <code>get</code> generando nombres del tipo <code>getByUser()</code>, <code>getByState()</code>, <code>getByDate()</code> deber&iacute;as evitar usar sin&oacute;nimos del verbo <code>get</code>, como por ejemplo <code>fetchByUser()</code>, <code>findByState()</code>, <code>retrieveByDate()</code>.</p><h2>Utiliza el contexto</h2><p>Evita repetir conceptos que ya est&aacute;n claros a trav&eacute;s del contexto. Continuando con el ejemplo anterior, si est&aacute;s escribiendo un m&eacute;todo dentro de <code>LessonRepository</code> para buscar lecciones por su estado no necesitas indicar que est&aacute;s buscando lecciones <code>getLessonsByState</code>. Ya te encuentras dentro de <code>LessonRepository</code> as&iacute; que todos sus m&eacute;todos deber&iacute;an devolver por colecciones de lecciones. Debes evitar repetir "Lessons" en cada nombre, siendo <code>getByState()</code> m&aacute;s adecuado./p&gt;</p><p>Deber&iacute;as evitar usar nombres demasiado largos, as&iacute; como deber&iacute;as evitar usar nombres demasiado parecidos. Si te encuentras en una situaci&oacute;n en la que est&aacute;s escribiendo un nombre demasiado largo deber&iacute;as evaluar si puedes utilizar el contexto para generar un nombre m&aacute;s corto.</p><p>Por ejemplo si tienes la clase <code>UniversityLessonState</code> que contiene los estados posibles de una lecci&oacute;n de la universidad, podr&iacute;as generar un nuevo namespace del tipo <code>University\Lesson\State</code> obteniendo un nombre de clase mucho m&aacute;s corto y f&aacute;cil de leer, pero sin haber perdido ning&uacute;n tipo de informaci&oacute;n.</p><p>Si necesitas dos palabras para definir el nombre de una clase es probable que necesites crear un nuevo contexto, y si necesitas tres palabras definitivamente deber&iacute;as crear un contexto nuevo.</p><h2>Hace lo que dice que hace</h2><p><img alt="Hace lo que dice que hace" loading="lazy" src="/cache/thumb_1200_0400/uploads/content/image/image/6e032f2cbbc3defe991d6878c01e6298fa24ed2f.jpg" title="Hace lo que dice que hace"></p><p>Entramos en la parte final de las recomendaciones. Sin embargo estas dos &uacute;ltimas son las m&aacute;s importante de todas. Cuando eliges un nombre lo m&aacute;s importante es ser sincero. El nombre que est&aacute;s eligiendo tiene que servir para identificar qu&eacute; es lo que contiene.</p><p>En general debemos evitar nombres gen&eacute;ricos como <code>data</code>, <code>info</code>, <code>resume</code>, <code>items</code>. En algunos momentos muy concretos puede que tengan sentido, &iquest;pero que contienen exactamente?. Quiz&aacute; el autor no sab&iacute;a que nombre poner y eligi&oacute; uno de estos.</p><p>Si lo que quer&iacute;amos crear era por ejemplo un conjunto de lecciones filtradas por algunos criterios, podr&iacute;amos haber eleg&iacute;do <code>lessons</code> o <code>filteredLessons</code> al menos indica que contiene un conjunto de lecciones.</p><p>Debemos tambi&eacute;n evitar nombres que definan qu&eacute; es lo que necesita el autor en lugar de que es lo que hace un m&eacute;todo o clase. Por ejemplo <code>LessonRepository::getForDashboard</code>. Tenemos claro que el autor necesitaba una colecci&oacute;n de lecciones para mostrarlas en el dashboard, pero no tenemos ni idea de que criterios tiene en cuenta. Si el criterio para mostrar las lecciones en el dashboard fuera que pertenecieran a un determinado usuario, que estuvieran en un rango determinado de fechas, como por ejemplo los pr&oacute;ximos 15 d&iacute;as, y se encontraran en un determinado estado, podr&iacute;amos haber elegido <code>LessonRepository::getByUserFromToAndState</code>.</p><h2>Explica c&oacute;mo debe usarse</h2><p>Llegamos al &uacute;ltimo punto. Una vez que has encontrado el nombre adecuado que cumple todos los anteriores requisitos debes plantearte una &uacute;ltima pregunta.</p><p>&iquest;Explica mi nombre c&oacute;mo debe ser utilizado? Veamos un ejemplo supongamos que tenemos una clase que se encarga de realizar cambios sobre las lecciones <code>LessonManager::changeDate</code>, el contexto <code>LessonManager</code> nos indica que la entidad que va a modificar es una <code>Lesson</code> y el nombre nos revela que la va a cambiar de estado.</p><p>Por coherencia los argumentos deber&iacute;an ser <code>Lesson</code>, <code>Date</code> en este orden. Sin embargo podemos ayudar a evitar malentendidos, nombrando correctamente los argumentos. <code>LessonManager::changeDate($lesson, $toDate)</code> no deja lugar a ning&uacute;n tipo de equivocaci&oacute;n.</p><h2>Conclusiones</h2><p>Cuando escribimos c&oacute;digo limpio debemos tener en cuenta a la persona que lo va a leer, y cuando elegimos nombres debemos elegirlos pensando primero en esa persona en hacerle la vida lo m&aacute;s f&aacute;cil posible.</p>
]]></description><guid>https://devtia.com/post/codigo-limpio-nombres</guid><pubDate>Wed, 03 Jun 2020 10:39:13 +0200</pubDate></item></channel></rss>