Hace un tiempo tuve una reunión de trabajo en la que me crucé con alguien que empleaba un tono demasiado altisonante para lo que mis oidos están acostumbrados, hablando con una suficiencia técnica un poco insoportable, para ser sincero. Cuando se dirigía a mí, parecía que me estuviese examinando. Después me comentaron su trayectoria profesional y me llevé una gran decepción, con todos los respetos. Dos años atrás, me encontraba ante un proyecto bonito, interesante y en crecimiento, liderado por personas competentes, sin duda, pero que en su carrera profesional solo habían conocido... ese único proyecto bonito e interesante. De vez en cuando recibo currículums de ingenieros técnicos en informática cuya experiencia laboral se basa en demasiados años en la misma compañía y en el mismo departamento, haciendo exactamente lo mismo.

Cada uno hace lo que puede para progresar en su carrera profesional, claro está. En definitiva, cada uno es libre de hacer con su tiempo y vida lo que le dé la gana. No es ni bueno ni malo estarse años en una misma actividad, lo que quiero puntualizar aquí es que puede ser muy peligroso y que en ocasiones hay quienes venden demasiado humo aparentando una imagen profesional basada tan solo en sus años de experiencia o quienes incluso alardean de llevar muchos años cuando en realidad han pasado ese tiempo realizando tan solo un conjunto muy limitado de cosas en concreto.

Pero lo que me molesta un poco, y lo siento, es que cualquiera alce como bandera de competencia técnica o de gestión únicamente los años que lleva currando: solo eso, mucho tiempo, como si solo éste fuese suficiente para darle más credibilidad a tu currículum.

En mi opinión, no solo son importantes los años que lleves trabajando en un sector u otro, sino además el contenido con el que has llenado tantas horas de trabajo para una empresa u otra. No tiene nada que ver haber trabajado en dos o tres proyectos similares que en veinte totalmente diferentes, el profesional que sale de lo segundo cuenta con una visión y experiencia mucho mayor y mejor, aunque haya dedicado la mitad de tiempo que quienes llevan en lo mismo el doble.

Lo que no se aprecia con claridad es que puedes llevar muchos años trabajando pero, en realidad, tan solo cuentas con un único año de experiencia, porque el resto del tiempo has estado repitiendo exactamente la misma actividad. En cierto modo, llevas despertándote en el mismo lugar cada mañana como Bill Murray y Andy MacDowell en la película de El Día de la Marmota

Es posible que en software, después de trabajar en muchos proyectos totalmente diferentes, se termine cultivando cierto tipo de intuición a la hora de elegir una tecnología u otra, de tomar ciertas decisiones de diseño e incluso de oler cuándo alguien puede encajar mejor en un equipo o en otro. Cuando has tocado en profundidad cierto tipo de sistemas grandes, amplías, digamos, tu visión a la hora de afrontar nuevos.

Es cierto que a todo el mundo le gusta trabajar en cierta zona de confort donde lo tiene todo controlado, pero yo comprobé hace mucho que permanecer demasiado tiempo en ella es perjudicial para una profesión tan volátil como compleja: en menos tiempo del que te puedes dar cuenta, terminas convirtiéndote en un dinosaurio que, fuera de tu empresa, lo va a tener difícil para encajar.

Sí, puedes llevar quince años en una multinacional y al mismo tiempo ser un dinosaurio tecnológico. Y no hay nada de malo en ello, pero tenlo en cuenta cuando de un día para otro tengas que salir de esa zona de confort (la única) que has conocido durante tanto tiempo.

Esto es especialmente problemático para los perfiles técnicos que pasan a gestionar como única actividad y al cabo de uno o dos años, pierden rápidamente la mayoría de sus habilidades técnicas.

Nadie puede decir que tenga quince años de experiencia cuando te has pasado todo ese tiempo actualizando sistemas operativos, o manteniendo una aplicación hecha en cobol o C, o programando cierto tipo de dispositivos y, a continuación, decir con la boca llena los años que llevas en el sector, cuando éste es, para ti, en realidad, bastante pequeño.

En otras palabras: la cantidad (tiempo), importa, claro, pero la calidad (experiencia diversa), es mucho más importante y, lo ideal es que ambas coincidan a la vez: tiempo más experiencia real en muchos y diversos proyectos.

Si eres un dinosaurio tecnológico (tan solo es una metáfora), no hay nada de malo en ello, claro, pero sí resulta peligroso cuando en algún momento tienes que pivotar de lugar, te largan de un día para otro o te ves obligado a montártelo por tu cuenta.

También he comprobado cómo trabajando en diversas áreas muy diferentes eres capaz de enriquecer un nuevo proyecto que comienzas y del que aún no tienes ni idea de cómo desarrollar. Por ejemplo, el mecanismo de extensibilidad de Drupal u entornos similares, es un buen ejemplo de arquitectura que se puede replicar en otro tipo de sistemas; un módulo tan simple y útil como Squel, te puede mostrar lo útil que resulta encadenar llamadas cuando tienes que realizar el cliente de una API cuyo propósito es totalmente diferente; el conocer bien varios frameworks, te puede dar idea de cómo enfocarlo mejor cuando eres tú el que tiene que tomar decisiones de diseño al desarrollar uno nuevo.

Pero lo que no sirve es decir que llevas quince años desarrollando aplicaciones web basadas en Wordpress y poco más, o desarrollando firmware para remotas de control, o mucho tiempo desarrollando el mismo sistema para la misma compañía, o manteniendo un proyecto que lleva una eternidad funcionando para el mismo cliente, y a la vez indicarlo con cierto aire de autosuficiencia. No te engañes. Quizá no te des cuenta, pero tu experiencia entonces es bastante limitada, a pesar del tiempo que haya pasado.

Como parte de El Libro Práctico del Programador Ágil, he incluido un pequeño capítulo sobre un tema sobre el que he reflexionado mucho a lo largo de los años. En ocasiones, las cosas no son como parecen, y, sobre todo, en el desarrollo de software hay que hacer un gran trabajo de pedagogía a gestores de proyectos que no han programado lo suficiente, para hacerles comprender ciertos aspectos inherentes a la programación que no dejan de ser algo sutiles.

Las apreciaciones que voy a indicar a continuación, en un principio, pueden ir en contra de la intuición acerca de nuestra actividad como desarrolladores de software. Muchos de los errores que cometemos en nuestro desempeño profesional mientras programamos y diseñamos aplicaciones, derivan de no comprender ciertas sutilezas en relación a la producción de código de calidad.

Idea contraintuitiva #1

Es difícil hacer software simple

No podemos caer en el error de pensar que cuanto más complejo es algo, más difícil es, o peor aún, más y mejores habilidades tiene su autor. En software, la verdadera habilidad y excelencia consiste en encontrar una solución sencilla a un problema complejo. Es algo que para mí siempre me causó admiración comprobar cómo se encuentran soluciones entendibles y cómo resuelven problemas complejos. Nada peor que un sobrediseño innecesario, o añadir complejidad por no pararse unos minutos a buscar una solución más sencilla. Para ello, debemos tener siempre presente esta idea de la sencillez mientras programamos.

Idea contraintuitiva #2

El diseño de una solución también evoluciona y crece, así como su arquitectura

En desarrollo ágil (programar para que nuestra aplicación acepte cambios más fácilmente), se suele decir que el diseño emerge a medida que se implementan nuevos requisitos, y así es. Lo contrario es establecer un diseño al comienzo de la aplicación y tratar de mantenerlo rígido a toda costa. De ningún modo: el diseño hay que cambiarlo para ajustar a la nueva funcionalidad que se va incorporando. Se mejora la calidad del código de forma continua, también su diseño.

Idea contraintuitiva #3

Hacer tests aumenta la productividad

Cuántas veces he oído lo mismo: “no tengo tiempo para hacer tests”. Decir esto no es profesional, ya que respaldar con tests nuestro código no es una tarea ajena al desarrollo de software, sino inherente a ella. Contrariamente a lo que pueda parecer, escribir tests reduce el tiempo dedicado a detectar y corregir bugs, además de darle solidez a la aplicación.

Idea contraintuitiva #4

Hacer tests es un modo de documentación de nuestro proyecto

El exceso de comentarios insertados a lo largo del código es un síntoma de la pobreza del mismo. En ocasiones, contadas, son necesarios, pero en realidad su sobreutilización revela que el código no es lo suficientemente simple y fácil de entender. En relación a los tests, ¿cómo podemos aprender cómo usar una clase, una librería, un módulo, etc.? Efectivamente, con los tests que los respaldan. Nada mejor que aprender cómo se utiliza algo que con un código que lo prueba.

Idea contraintuitiva #5

Hacer tests obliga en cierta medida a realizar un mejor diseño

Plantea una aplicación monolítica para hacer cualquier cosa que se te ocurra. Te saldrá, con toda seguridad, una serie de clases con métodos muy largos, acoplados y rígidos, aunque funcione y realice su propósito… En este libro queremos aprender a programar para que nuestra aplicación acepte cambios más fácilmente y sea más mantenible, ¿no es así?

Esa aplicación monolítica solo podrá ser probada manualmente, poco más. Si quieres introducir tests en ella, pronto te darás cuenta de que su estructura y la relación de sus componentes (diseño) debe cambiar: debe mejorar. Hacer tests te obliga, en cierto modo, a crear un diseño mejor.

Idea contraintuitiva #6

La optimización del código es una tarea continua

Optimizar código para se ejecute con mejor rendimiento es una tarea habitual, sobre todo para aquellas partes de la aplicación que se ejecutan más frecuentemente. Sin embargo, dejar esa actividad para el final es un error. Del mismo modo que incluimos en nuestra práctica y rutina habitual de desarrollo el crear tests para respaldar nuestro trabajo, también debemos incluir esas pequeñas optimizaciones que mejoran el rendimiento del mismo, siempre y cuando no se sacrifique la simplicidad y su legibilidad.

Del mismo modo en que mejoramos la calidad del código y su diseño mediante pequeños pasos, ocurre lo mismo con su optimización.

Idea contraintuitiva #7

El rendimiento de una aplicación no solo se consigue con más hardware, también con un mejor diseño

La solución rápida cuando se presentan problemas de rendimiento, consiste en añadir más hierro al sistema de producción donde se ejecuta la aplicación: más memoria para el engine de la base de datos, más discos SSD, balanceo entre sevidores, etc. Puede que sea necesario, pero, en ocasiones ese coste lo que viene es a tapar una arquitectura, diseño y una solución pobre o ineficiente. He visto quemar, literalmente, miles de euros, en hardware para una solución con una arquitectura errónea y mal planteada.

Idea contraintuitiva #8

El diseño de las bases de datos, como cualquier otro asset de un proyecto software, también está sujeto a una mejora continua

Todos los elementos de una aplicación son susceptibles de mejora: desde archivos CSS, html, scripts de front-end en javascript hasta soluciones de más alto invel en C#. Absolutamente todo. Las bases de datos, su diseño, no escapan a esta mejora y evolución continuas.  Si mantenemos su rigidez inicial, o el modo en que se planteó inicialmente la base de datos, tendremos el problema de tratar de meter con calzador la nueva funcionalidad requerida.

Idea contraintuitiva #9

Una gran mejora siempre es producto de micro mejoras

En software se produce un efecto acumulativo cuando introducimos pequeños cambios de manera continuada: simples refactorings (como los descritos en este libro), mejoras minúsculas en la legibilidad del código siguiendo las técnicas de código limpio, mejoras en el diseño, mejoras insignificantes en la organización del proyecto, etc. Con el tiempo se van acumulando cientos de pequeños cambios que supondrán realmente aumentar la calidad y la mantenibilidad de la aplicación. Además, muchas de estas mejoras son mini tareas que se pueden realizar en minutos, como mejorar los nombres de variables, simplificar un método, extraer código duplicado, agregar un par de test unitarios, etc.


Nota: este artículo es es un resumen y forma parte del proyecto en desarrollo El Libro Práctico del Programador Ágil. Lanzamiento en julio 2018.


 

Hace ya cuatro años que publiqué El Libro Negro del Programador, con una segunda revisión de ese trabajo el año anterior. Desde entonces, no han parado de aumentar las reviews en Amazon así como los mensajes que me llegan directamente desde muchas partes del mundo.

Y todo esto, en definitiva, lo que me ha hecho es comprender que las problemáticas que se describen en el libro forman parte del sector en general, independientemente del país donde trabajes o del tipo de compañía.

Mala organización, software que se desarrolla sin cultura de tests, gestores de proyecto que no conocen la idiosincrasia inherente a un proyecto software, desarrolladores demasiado individualistas, ausencia de cultura de código limpio y de conocimiento de técnicas de refactoring, etc. Todo esto no ocurre más en el mundo castellano parlante, ni mucho menos, tan solo hay que ver algunos repositorios de código en GitHub, algunos de ellos muy populares.

He trabajado en proyectos internacionales con compañías de Suecia, USA y países de Oriente Medio y de Sudamérica, y puedo decir que lo que he visto con frecuencia viene a ser un poco más de lo mismo, las mismas dinámicas y problemas similares, salvo algunas excepciones de las que aprendí muchísimo y fueron fuentes de inspiración con las que tuve la suerte de cruzarme.

Por tanto, he lanzado una nueva edición de El Libro Negro del Programador pero esta vez en inglés, confiando en que sea de la misma ayuda para desarrolladores angloparlantes que para los lectores en español.

Y porque vivimos en un mercado global en donde todo lo digital y el conocimiento apenas tiene fronteras, y porque en el sector de la tecnología, el inglés es el idioma estándar de facto.

Confío en que este nuevo trabajo sea de la misma utilidad para todos los lectores que no hablan español pero sí leen en inglés y que funcione igual de bien tal y como lo ha hecho El Libro Negro del Programador en estos años.

A partir de ahora me propongo ir añadiendo contenido en inglés a mi web personal.

The Black Book of the Programmer

 

Lo he visto en demasiadas ocasiones: una aplicación es concebida inicialmente para realizar un conjunto reducido de tareas, pero, con el tiempo, se va tratando de incluir más y más funcionalidad. Lo que debería ser un éxito (se pide nueva funcionalidad porque lo anterior funciona y es de utilidad) se termina convirtiendo en una auténtica patata caliente imposible de mantener y para la que cualquier nuevo cambio cuesta más y más esfuerzo (y dinero) en introducirse.

También lo he visto (y sufrido) demasiadas veces: los responsables de esas aplicaciones son reacios a reconocer el problema y suelen echar balones fuera y mantenerse dentro de cierto caos antes de asumir profesionalmente que se ha alcanzado un punto crítico en el que hay que tomar decisiones desagradables.

El resultado es siempre el mismo: después de mucha frustración, se llega inevitablemente a la conclusión de que hay que rehacer partes completas de la aplicación cuando no tirarla a la basura completamente y comenzar desde cero.

No podemos perder la perspectiva: si se trata de un proyecto con cierto carácter lúdico, un repositorio que apenas mantienes en Github o Codeplex, bien, no pasa nada, salvo el tiempo que se haya podido perder, pero si se trata de un proyecto empresarial, todo lo anterior se traduce en costes dolorosos y, seguramente, un equipo frustrado por trabajar en una aplicación difícil.

Este es un mantra que conviene no olvidar nunca: todo software requerirá de cambios inevitablemente (y el fundamento del enfoque ágil). Si no se diseña para admitirlos, entonces nos encontraremos tarde o temprano con una aplicación corrupta y el escenario descrito párrafos más arriba.

La buena noticia es que se puede evitar, trabajando desde el inicio del proyecto en la línea correcta.

Pero, ¿por qué llega a corromperse una aplicación con el paso del tiempo a medida que la hacemos cambiar? A continuación enumero una lista de algunas de la razones:

  • Una aplicación es concebida inicialmente como simple o pequeña y se le obliga a crecer de forma muy rápida y descontrolada.
  • No existe metodología a la hora de ir introduciendo nuevos cambios: los requisitos llegan de un día para otro, se vuelve atrás con frecuencia, no hay planificación y cultura de testing o validación de la aplicación antes de ser entregada, abonando el terreno para el caos.
  • Los requisitos no son claros: la traducción de los requisitos de negocio a los requisitos técnicos no se realiza con exactitud y la suficiente comprensión. El resultado es que se implementa funcionalidad que no es exactamente la que se quería, produciendo una cascada de cambios y, posiblemente, dejando código muerto y obsoleto a medida que eso ocurre, ensuciando la solución.
  • Se utiliza una dispersión de tecnologías que dificulta la evolución de la aplicación. Para programar bien y de forma mantenible, hay que conocer bien las librerías y frameworks que se utilizan; un exceso de estos en la misma aplicación provoca confusión y es más difícil de llevar. Además, si se usan librerías complejas, esto ofuscará la solución.
  • No se dedica tiempo a mejorar lo que ya existe, aunque funcione. El desarrollo de software es en cierta medida incremental: construimos nueva funcionalidad sobre lo ya existente o del mismo modo que lo que ya existe. Hay que tener siempre la actitud de mejorar continuamente lo que ya hay.
  • Se intenta mantener código obsoleto, mal diseñado, mal probado, a toda costa. A veces cuesta trabajo eliminar partes de la aplicación porque recordamos el esfuerzo que nos llevó hacerlas, o por simple pereza, pero arrastrar algo que no está del todo bien es perjudicial: podemos decir que lo que eliminamos, en realidad, nos sirvió para aprender a hacerlo mejor.
  • No se tiene en cuenta que no solo se mejora el código en sí, también el diseño y la organización del proyecto.
  • No se siguen prácticas de código limpio y de refactoring de forma continuada.
  • El proyecto no tiene tests o la batería de tests es insuficiente con una cobertura de código baja. Esto provoca que no sepamos cuanto antes qué bugs introducimos al hacer cambios: cuanto antes se detecte un bug, más fácil y sencillo será corregirlo. Además, incluir tests obliga a diseñar la aplicación con mejor estructura (software testeable), alejándonos de enfoques monolíticos y rígidos.
  • El diseño (si es que existe) es pobre.
  • Y, por supuesto, ocurre parte o todo lo que describro en El Libro Negro del Programador

​Lo bien o lo mal que hagamos todo lo anterior, hará que lleguemos antes o después a la barrera de inmantenibilidad, tal y como describe la curva o Ley de Boehm, que viene a indicar el coste incremental de corregir errores desde una fase temprana del proyecto o en una fase tardía (cuando ya el software es... demasiado corrupto):

Boehm's Law

Nota: este artículo es es un resumen y forma parte del proyecto en desarrollo El Libro Práctico del Programador Ágil. Lanzamiento en julio 2018.


 

¿Cómo podemos discernir que una aplicación es de mayor calidad que otra?

Lejos de plantear una definición demasiado académica y siendo pragmáticos, podemos decir que un software es de calidad no solo cuando cumple correctamente la funcionalidad requerida, además, lo consideramos de mejor calidad cuando el coste de su mantenimiento es bajo y la dificultad para introducir nuevos cambios (nuevos requisitos) también es baja o trivial.

Fácil de decir, pero en cierta medida, difícil de conseguir. Esta es la definición de calidad de software que, en mi opinión, es más interesante considerar en el día a día como programador en cualquier compañía.

La mayoría de los desarrolladores, por falta de experiencia, o bien por presiones en tiempo o ausencia de disciplina, nos quedamos atascados en ese primer aspecto de la calidad que comentamos en el párrafo anterior: cumplir la funcionalidad y punto, dejando la implementación de la funcionalidad X del primer modo en que la hemos escrito y resuelto. Sin embargo, ya sabemos que en cualquier negocio o proyecto, salvo excepciones muy contadas, a nuestro código se le va a requerir cambiar, sí o sí. Precisamente de esa realidad (todo software va a sufrir cambios), nació el movimiento de software ágil como forma de abordar mejor el código que escribimos, dando a pie a técnicas, al concepto de diseño ágil, etc.

Métete esto bien en la cabeza: debemos escribir código pensando en que sufrirá cambios necesariamente. La capacidad de aceptarlos determinará el coste de mantenerlo e incluso el éxito o fracaso del proyecto.

Recapitulemos: no programamos únicamente para cumplir con cierta funcionalidad que se exige en la aplicación hoy, también para hacer funcionar un negocio (que es el que paga en última instancia), y pocos negocios hay estáticos y que no tengan que cambiar, optimizarse o mejorar continuamente.

En este sentido, es fácil determinar si una aplicación es de calidad o no, tan solo tenemos que mirar los siguientes aspectos:

  • El código es simple (fácil de entender). La habilidad de un buen programador reside básicamente en encontrar soluciones sencillas a problemas que no lo son tanto.
  • También es legible (fácil de leer y de seguir). El código debe ser fácil de leer por cualquier miembro del equipo y  debe poder ser asumido con facilidad por cualquier nuevo miembro que se incorpore.
  • Existen tests que proporcionan una cobertura suficiente, esto es, un porcentaje alto de todo el código de la aplicación está cubierta por pruebas. El testing es un tema extraordinariamente amplio de modo que un tester en condiciones tiene habilidades técnicas diferentes que un desarrollador. Digamos que, con los pies en la tierra y siendo prácticos, que nuestro proyecto debe tener al menos una buena batería de tests unitarios y de integración.
  • El diseño y el código es homogéneo y coherente. No programamos del primer modo en que se nos ocurre solucionar algo, sino que esta solución debe mantener el diseño de la misma y estar alineada con el resto del código de la aplicación en estilo, uso de librerías externas, normas consensuadas de hacer las cosas, etc. Nada peor que identificar una parte específica de un proyecto en el que se reconoce la mano concreta de un compañero.
  • El desarrollador dedica la mayor parte de su tiempo a añadir nueva funcionalidad, no a corregir bugs. Si pasamos mucho tiempo detectando o corrigiendo errores, entonces ya sabemos que la aplicación se aleja de la definición de calidad que hemos dado más arriba y, por tanto, hay mucho trabajo para mejorarla.
  • A producción solo llegan (si llegan) pequeños defectos, nunca errores críticos. No es profesional liberar una versión de nuestro proyecto de modo que en explotación presente errores graves que impidan el buen funcionamiento de la actividad que soporta.
  • Las métricas más básicas dan buenos valores. Existen muchas métricas para evaluar diferentes aspectos del código, pero algunas básicas son fáciles de obtener y nos pueden ayudar a detectar ciertos problemas, como el número de líneas por método, la complejidad ciclomática, detección de código que nunca se ejecuta, etc

Nota: este artículo es es un resumen y forma parte del proyecto en desarrollo El Libro Práctico del Programador Ágil. Lanzamiento en julio 2018.


 

En junio publicaré un nuevo proyecto en el que llevo trabajando unos meses. Me temo que todas aquellas malas prácticas que describía en El Libro Negro del Programador, las he seguido viendo en equipos de desarrollo y compañías con las que he mantenido cierto contacto desde que lo lancé hace ya casi cuatro años.

Código sucio e ilegible, falta de organización, mal uso de herramientas de seguimiento, código excesivamente acoplado, ausencia total de documentación, redundancias chirriantes, soluciones con una organzación en los assets del código desastrosa, falta de gestión de la configuración, correcciones en caliente en los sistemas en explotación, "hoy programo esto porque me gusta más y no hago lo que es prioritario para el proyecto..." y un largo etcétera.

Si esto te suena, entonces ya conoces el resultado: programadores frustrados, un negocio enfadado que gasta más recursos de los que debería y soluciones que hay que tirar a la basura tarde o temprano (o rehacerlas completamente llamándolas con un nuevo número de versión...). Pero, sobre todo, programadores a los que aún le faltan, en mi opinión, un salto de nivel para considerarse auténticos profesionales. No estoy hablando de crear un proyecto lúdico en GitHub en tu tiempo libre, sino de trabajar correctamente dentro de una compañía y como parte de un equipo con el objetivo de sacar adelante un proyecto software con calidad profesional.

¿Y por qué software ágil? Porque los mercados evolucionan cada vez más rápidos, el time-to-market es cada vez menor, porque a estas alturas de la industria del software debemos diseñar aplicaciones para que puedan evolucionar fácilmente y cuyo coste de mantenimiento sea menor. Lejos están los tiempos en que se creaban aplicaciones demasiado monolíticas (aunque las siga viendo muy a mi pesar en entornos profesionales).

Esto es precisamente lo que persigue el Libro Práctico del Programador Ágil, mostrarte las técnicas elementales para que tu aplicación sea modificable con facilidad y mantenible.

En estos años me han contratado para husmear en la forma de trabajo y la calidad del código que se escribe en diferentes organizaciones, de forma que he ido recopilando una gran cantidad de material y que ahora estoy utilizando para darle forma a El Libro Práctico del Programador Ágil. Esto, además, me ha permitido volver a repasar las referencias de cabecera del desarrollo ágil que todo programador debería tener en la mesilla de noche, profundizando aún más en esas prácticas.

Hechos:

1) Programar puede ser hasta relativamente sencillo; abundan los libros que prometen a un neófito aprender php, python o javascript en 24 horas. 

2) Implementar soluciones utilizando realmente la orientación a objetos de lenguajes de más alto nivel como C#, Java o incluso las últimas revisiones de los lenguajes anteriores, comienza a ser algo menos trivial, imposible de aprender en poco tiempo. En muchas ocasiones, apenas utilizamos la orientación a objetos correctamente.

3) Programar una aplicación sin errores, soportado por pruebas, incluye además otro nivel de dificultad y otro enfoque de diseño totalmente diferente.

4) Desarrollar software dentro de un equipo de trabajo, requiere otro tipo de consideraciones: metodología, uso de determinadas herramientas de colaboración o seguir algún tipo de estrategia ALM (application lifecycle management).

... y 5) Por último, desarrollar un proyecto para que acepte cambios, mejoras y nuevas características durante años sin errores, ese es otro tema.

Sin embargo, me temo que me encuentro habitualmente en proyectos de compañías serias y que dedicarn muchos recursos (€), mucho más de los primeros puntos que del último.

El Libro Práctico del Programador Ágil introduce las prácticas necesarias para asegurar la calidad del software en este último sentido, para garantizar la mantenibilidad del mismo, su futura evolución y que la introducción de nuevas caractarísticas se realicen con el mínimo esfuerzo, de modo que los desarrolladores pasen gran parte de su tiempo... programando, aportando valor, no corrigiendo errores, y mucho menos aguantando a los compañeros del negocio frustrados porque el software que utilizan falla o funciona mal.

Nada más y nada menos. Todo un reto, pero, en definitiva, son buenas prácticas que he vuelto a tener muy en cuenta reciemente desde Solid Stack cuando estamos a punto de lanzar la versión licenciada de un producto como Picly.

Iré publicando en forma de entradas en mi web gran parte del contenido del libro, del mismo modo que hice en su día con el El Libro Negro del Programador

A continuación indico el contenido base de este nuevo proyecto:

  • Qué es la calidad del software
  • Por qué el software se corrompe
  • Ideas contraintuitivas
  • Cómo detectar soluciones no mantenibles
  • Una visión holística al desarrollo de software
  • Prácticas de código limpio
    • Código limpio vs refactoring
    • Nombres con significado
    • Clases
    • Funciones
    • Comentarios
    • Formateo e indentación
    • La metáfora del periódico
    • La afinidad conceptual
    • Abstracción de datos
    • Data Transfer Objects
    • Gestión de errores
    • Cohesión entre clases
    • Acoplamiento
    • Interfaces
  • Testing
    • Por qué crear tests forma parte del desarrollo
    • Tests unitarios
    • Tests de integración
    • Catálogo de pruebas de aceptación y de validación
  • Prácticas de refactoring
  • Principios fundamentales de diseño
    • Single Responsability Principle
    • Open-close Principle
    • Linkstov Principle
    • Inversion Control Principle
    • Dependency Inversion Principle
    • Inyección de depenencias
  • Gestión de la configuración
  • Técnicas de productividad para desarrolladores de software
  • Conclusiones

Este nuevo trabajo va al grano, te muestra las técnicas básicas pero imprescindibles de código limpio y de refactoring, con innumerables ejemplos así como la aplicación práctica de principios imprescidibles con SOLID.

Los ejemplos están escritos en C# y Javascript, tratando en cada caso de elegir uno u otro lenguaje para que cada ejemplo sea más ilustrativo.

La calidad nuestro proyecto software avanzará a años luz tan solo aplicando todos y cada uno de los conceptos de El Libro Práctico del Programador Ágil.

Digital Ocean

Un artículo de Rafa G. Blanes

 

Utilizo Digital Ocean desde hace años para mis proyectos personales y mis webs basadas en Drupal. Estas son las razones por las que seguiré utilizando este servicio por mucho tiempo.

Digital Ocean fue inicialmente una plataforma para la gestión de máquinas virtuales (VPS) con almacenamiento SSD, cuando todavía los discos duros de estado sólido eran caros en el mundo cloud en relación a otros servicios de hosting. Además, tenían una concepción diferente con respecto a otros servicios similares, como Azure, AWS o Rackspace: extraordinaria sencillez en la admistración y orientado completamente a desarrolladores de software.

Con el tiempo, han ido añadiendo más datacenters y han ido pasando de ofrecer un servicio de plataforma como servicios (Paas) a infraestructura como servicio (Iaas), con balanceadores de carga, redes privadas, almacenamiento, gestión de DNS, etc., pero manteniendo la simplicidad como principio. Su panel de control (o dashboard), es asombrosamente sencillo y te da la información rápida y precisa del estado de los recursos que tienes contratados y del coste actual acumulado.

Un máquina virtual se denomina en Digital Space un droplet, que, a diferencia de una VPS tradicional, incluye monitorización de seguridad y de comportamiento por el mismo coste. Puedes crear un nuevo droplet en segundos partiendo de una instalación base de alguna distribución de Linux o alguna imagen preconfigurada con los paquetes software más populares (stacks LAMP, LEMP o MEAN, Docker, MySql, Wordpress, etc.), además de crear un droplet a partir de un snapshot de una de tus propias máquinas ya configuradas.

A continuación, recibes un correo con la contraseña del usuario root y la dirección IP de la máquina recién creada, y poco más, ya tienes acceso a tu nuevo servidor.

Aunque los precios para máquinas virtuales caen cada vez más, en Digital Ocean tienes un droplet con una distribución de Linux de 1Gb de RAM, 1 CPU, 25Gb de almacenamiento y 1Tb de transferencia por 5 dólares al mes..., suficiente para probar cosas o publicar aplicaciones sin demasiadas exigencias (dos de mis webs, ésta y www.gblanes.com, están en una máquina con esas características con un rendimiento más que suficiente). Por el momento, las imágenes bases son siempre distribuciones de Linux.

Digamos que Digital Ocean está evolucionando poco a poco a suministrar servidores virtuales a proveer verdaderamente de servicios cloud.

Como cualquier infraestructura hardware, las actividades de mantenimiento o actualización la informan con tiempo suficiente para que estés al tanto de que tus droplets pueden verse afectados (normalmente esto ocurre poco y la falta de servicio dura minutos). Algunas de mis máquinas virtuales llevan dos años funcionando ininterrumpidamente.

Por otra parte, una característica que me gusta especialmente de Digital Ocean es su enorme sección de tutoriales con una calidad extraordinaria, los utilizo frecuentemente para resolver algunos problemas o recordar cómo se hacía esto o aquello. Imagino que deben tener una política de calidad o algo similar, ya que me llama la atención que verdaderamente se trata de documentación cuidada, bien editada y clara.

Otro punto que me gusta mucho de Digital Ocean es que se incluye con el mismo coste un servicio de monitorización y de alertas para tus droplets (recientemente me avisaron que una de mis máquinas virtuales, al no tener actualizado Drupal a la última versión, estaba realizando un consumo de ancho de banda excesivo. Después descubrí aprovechando una vulnerabilidad de la versión no actualizada de Drupal, me habían instalado un minador de bitcoins..., ejem...).

Al igual que otros servicios similares, disponen de una API con la que se pueden programar la creación de recursos y gestionar su uso.

Si estás buscando un proveedor de máquinas virtuales para algún proyecto, Digital Ocean es una opción que te recomiendo.

Antes de comenzar una nueva fase de desarrollo, conviene dedicar algo de tiempo a mejorar todo lo que ya hay.

La construcción de una pieza de código de calidad es un proceso incremental y nunca, absolutamente nunca, lo primero que escribes, aunque funcione, tiene la calidad que debe tener para asegurar su mantenibilidad.

Es algo que comienza para mí a ser recurrente: encontrarme analizando proyectos que por alguna razón, terminan siendo difíciles o imposibles de seguir evolucionando. No importa la tecnología que se use, aunque hay algunas que tradicionalmente han provocado una mayor cantidad de proyectos muy corruptos, quiero decir, proyectos que terminan siendo reescritos desde cero. PHP, por ejemplo, tiende a esto, pero no por el lenguaje en sí, sino porque su curva de aprendizaje es tan fácil que en poco tiempo alguien que se inicia en el mundo de la programación consigue obtener algún resultado sin siquiera necesidad de programar orientado a objetos, y, con el tiempo, la aplicación va creciendo y creciendo sin consolidar principios de diseño, buenas prácticas, una gestión de la configuración correcta, código limpio y... O sea, una auténtica pesadilla. La orientación a objetos tiende a forzar un diseño algo mejor, aunque este tema da mucho de sí.

Se sospecha en un primer vistazo si el diseño ha sido cuidado y revisado (si es que existe "diseño" como tal, cuando no un sistema excesivamente monolítico), así como la estructura y calidad del código de cada método.

Ocurre exactamente igual que cuando escribes un relato: primero comienzas con un borrador (y sí, "funciona", en el sentido de que transmites la idea que quieres dar a conocer). Si le das una pasada vas a encontrar seguramente algún error de puntuación, ortográfico o gramatical, y con toda seguridad, leerás párrafos que en esa segunda lectura encuentras el modo de mejorarlos. En una tercera revisión vuelve a ocurrir lo mismo, hasta que llega un momento en que la intuyes que ya calidad de lo que has escrito está a la altura de tus expectativas, quizá en la quinta, sexta o décima lectura de correción, y más aún si son otros los que leen tu texto y encuentra typos sutiles que tú has pasado por alto.

En software es igual, con la diferencia de que estas revisiones afectan tanto a la estructura del código (diseño) como a sus defectos (excesivo acoplamiento, baja cohesión, duplicidades, violación de principios de diseño, código díficil de entender, pruebas insuficientes, etc.). La cuestión es, ¿para qué me debo preocupar de esto, si funciona mi aplicación? Mmmmm

Si desarrollas una aplicación que nunca va a tener que ser cambiada, hasta vale entregarla con todos los defectos que se te puedan ocurrir, pero esto rara vez ocurre, porque en la mayoría de los casos todos los proyectos sufrirán modificaciones en mayor o menor medida.

Cuántas aplicaciones he visto ya que son una simple extensión de un núcleo excesivamente monolítico... hasta que llega el momento en que ya no soporta más cambios y hay que tirarla a la basura y comenzar de cero, para frutración (o alivio, quien sabe) de los desarrolladores, y varapalo para el negocio que incurre en sobrecostes, y además algún responsable que tratará de escurrir el bulto como sea.

La forma de evitar esto es refinar continuamente la aplicación en la que se trabaja, tratando de mejorar todos aquellos aspectos que en ingeniería del software sabemos que aportan calidad al código. Hablo de calidad en el sentido de generar una aplicación mantenible, que soporta pruebas automatizadas y que es fácil de modificar y de incluir cambios.

Es sorprendente que algunos de estos refinamientos son triviales, sencillos, se realizan en poco tiempo; e igualmente sorprendente es el beneficio que reportan a medio y largo plazo. Por poner algunos ejemplos:

  • Comprobar si el código cumple con todas las buenas prácticas de clean code (buenos nombres, indentaciones correctas, clases cortas, comentarios limitados a lo necesario).
  • Comprobar la cohesión de las clases para generar un buen diseño.
  • ¿Se cumplen correctamente los principios SOLID?
  • Refactorizar pequeñas partes de la aplicación para mejorar su diseño y aumentar la simplicidad.
  • Darle una vuelta a aquella lógica de negocio más compleja que se pueda simplificar en la medida de lo posible.
  • Revisar si se puede mejorar aún más el procedimiento de despliegue.
  • etc.

Es buena idea antes de comenzar una nueva fase de desarrollo, dedicar algo de tiempo a todo lo anterior; al hacerlo así, es más que probable que favorezca que necesitemos de menos tiempo para incorporar las nuevas características sobre las que tenemos que trabajar.

Desde hace unas semanas ya está disponible en modo beta 1 la primera versión de Picly, un servidor de imágenes con transformaciones al vuelo a través de la misma url. Han pasado ocho meses desde su primer prototipo y, aunque en unas semanas liberaremos la versión comercial, hemos comenzado a "comunicar al mercado" este nuevo producto por aquello de que si sales con demasiadas características, es que sales tarde... 

Hay muchísmo trabajo detrás de este proyecto en el que participa todo el equipo de desarrollo de Solid Stack, realizado en Node JS, usando una base de datos en Redis y mucho, muchísimo testing antes de liberar estar pimera versión.

¿He dicho "muchísimo trabajo"?

Se suele ignorar que detrás de una simple web comercial (que ya tiene lo suyo en diseño, usabilidad, calls to action, etc.), existe toda una infraestructura que le dá soporte para implementar todos los procesos de negocio.

Las personas no demasiado técnicas, incluso muchos desarrolladores que se lanzan a probar una idea, no tienen claro el enorme esfuerzo que existe para coordinar, desarrollar y, sobre todo, mantener, una infraestructura software y hardware para comercializar un producto que con el tiempo tendrá diferentes versiones y se podrá usar en distintas modalidades comerciales (gratuita, profesional y empresarial).

Me temo que no, que esto no es publicar una web atractiva y ya te pones a hacer caja desde el minuto uno...

Tan solo para poder lanzar una primera beta, resumo a continuación todo lo que necesitamos desplegar y desarrollar:

  • Una web responsiva y con un diseño atractivo y comercial: www.picly.io
  • Una aplicación web también fácil de usar y responsiva para el panel de los usuarios que se registran, lo tenemos publicado en account.picly.io
  • Una API Rest para dar soporte a lo anterior, publicada ahora mismo en api.picly.io
  • Y, claro está, el mismo producto descargable y listo para ser ejecutado en una máquina en local.

Tan solo para desarrollar todo lo anterior, nos ha hecho falta:

  • Desarrollar el producto con la suficiente calidad como para poder publicarlo como beta 1 (con tests, pruebas manuales y exploratorias, etc.). Esto es, en sí, un reto, al tratarse de algo más o menos complejo a nivel técnico y que pretende ofrecer una solución de menor coste y mucho más flexible que servicios como Cloudinary.
  • La gestión de la configuración y procedimiento de "compilación" de la versión requiere de un esfuerzo considerable: selección de los assets a publicar, ofuscación de las partes más sensibles del código, minificación de las librerías y css para las distintas web y el panel de control de Picly, etc.
  • Conocer en profundidad las tecnologías y librerías que hemos utilizado: Node JS, Redis, Bootstrap, diseño de una arquitectura distribuida, Graphics Magick, OpenCV, etc.
  • Poner en marcha un mecanismo de "inversión de control" para la incorporación de los plugins de Picly que son los que hacen las transformaciones al vuelo.
  • Infinidad de reuniones para consolidar lo ya implementado y definir los próximos pasos.
  • Integración de la pasarela de pago a través de Stripe.
  • Integración de muchos otros servicios como Google Analytics, Hotjar, etc.

Todo esto parece abrumador al principio, y, en realidad lo es, sin embargo, lo importante es ir dando pasos continuamente poco a poco pero con la dirección clara hasta cumplir la funcionalidad mínima para salir y dar a conocer al mercado este nuevo proyecto.

Para mí, la esencia de un buen trabajo que parece enorme es el refinamiento continuo.

Y a partir de ahí, ¿qué?

A partir de este momento, el trabajo duro continúa pero en una fase diferente, ya que hay que poner en marcha lo que se denominan los procesos de negocio mediante procedimientos bien establecidos y ordenados, como los siguientes:

  • Comunicación regular al mercado mediante noticias, tweets, etc.
  • Campañas de divulgación, webinars, meetups, listas de correos, contacto directo a compañías como potenciales clientes, etc.
  • Mecanismos para recoger, recopilar y analizar el feedback.
  • Procedimiento de soporte.
  • Auditorías internas de seguridad de toda la infraestructura creada y que soporta Picly.
  • Tracking para las licencidas vendidas.
  • Monitorización de la actividad de los usuarios.
  • Procedimiento para la liberación de nuevas actualizaciones (tanto de las webs como del producto en sí).
  • Definición de métricas no vanidosas para comprobar el impacto de cualquier comunicación al mercado.
  • etc.

Todo esto es muchiíisimo trabajo, pero, que, estando bien definido y ordenado, se puede llevar a cabo con la disciplina necesaria para tener éxito con un producto como Picly.

Picly es un producto en el que se ha puesto mucho esfuerzo para mantener un diseño limpio, claro, con módulos sencillos soportados por tests, clean-code y todas las buenas prácticas para el desarrollo de un producto mantenible y evolucionable. Durante este tiempo, han surgido muchas anécdotas que iré contando poco a poco, como la razón por la que no hemos usado ningún framework como Angular, React, etc. para las distintas aplicaciones webs, por qué tomé la decisión de diseño de usar Redis como base de datos y muchas más.

Continuaré hablando de todo lo anterior, tanto a nivel técnico sobre Picly como todos esos procesos de negocio específicos que estamos poniendo en marcha ahora mismo.

En cualquier caso, animo a que descarguéis el producto y nos machaquéis con sugerencias y feedback!

Hay algunas preguntas que me hago recurrentemente cuando llevo un tiempo desarrollando o dirigiendo un nuevo proyecto. Lo he hecho recientemente ahora que estamos a punto de lanzar Picly (web en pruebas aquí: http://stage.picly.io)

Uno de los elementos que caracterizan un buen equipo de otro que no lo es tanto, es la disciplina, a la hora de mantener en el día a día las buenas prácticas, los procedimientos establecidos. Esta disciplina, por lo general, suele venir impuesta por el responsable del equipo, y no por los mismos miembros de este que... bueno, no siempre todos están lo suficientemente motivados o interesados en generar un producto o proyecto mantenible y evolucionable.

En uno de los capítulos de El Libro Negro del Programador resumí en forma de setenta y ocho preguntas los indicadores más relevantes que tenemos que tener en cuenta para generar software de calidad. Son preguntas sencillas, directas, que nos indican en qué punto flaqueamos o qué podemos mejorar tanto para nuestro día a día como desarrolladores así como para mejorar en nuestro sector como profesionales.

Creo que en esas preguntas se resume lo más importante que debe tener en cuenta un equipo de desarrollo y su responsable, partiendo de la base de que ni hay super gurús (aunque sí egos inflados, me temo) ni equipos perfectos, ni falta que hace: lo único que importa es que el negocio para el que se trabaja pueda usar la funcionalidad que necesita entregada en tiempo y que desarrollemos con calidad y que además se puedan demandar más características sin que lleguemos a una solución espagueti que tengamos que tirar a la basura.

Hay muchas razones por las que el software se pudre (software rots). El concepto suena fatal, pero lo que viene a decir es que es casi natural que una solución evolucione de una forma tan caótica que sea imposible mejorarla o mantenerla, y entonces lo único que se puede hacer es tirarla a la basura. Hay razones para que esto ocurra y que abordaré en otra entrada aunque hay buenas referencias publicadas; lo que sí quiero remarcar es que si de las siguientes setenta y ocho preguntas la mayoría se responden afirmativamente, la probabilidad de que haya que tirar un producto o parte del mismo a la basura con el tiempo se reducirán notablemente.

Ahora bien, si conocemos bien las razones por las que esto ocurre, entonces nos esforzaremos sin problemas para evitar que ocurra, digo yo, aunque algunas de estas razones son bastante sutiles y tienen un efecto acumulativo difícil de apreciar a primera vista.

A continuación copio y pego este test que viene incluido en el capítulo de nombre "El test del desarrollador de software altamente productivo". Como se verá, muchas de estas preguntas no son de carácter técnico, sino acerca del entorno, del ambiente y de la forma de trabajar en el que nos desenvolvemos pero que afectan positiva o negativamente a nuestro trabajo:

1. ¿Está el código que generamos suficientemente respaldado por pruebas?

2. ¿Tiene el equipo en el que trabajamos una suficiente cultura de creación de pruebas?

3. ¿Dedicamos conscientemente algún tiempo a refactorizar?, esto es, ¿nos planteamos frecuentemente las preguntas de si algo se puede mejorar o simplificar?

4. ¿Vamos dejando en el código comentarios tipo «to do:…» que finalmente nunca se llegan a completar?

5. ¿Buscamos en nuestro día a día cómo aplicar principios S.O.L.I.D., KISS, etc.?

6. ¿Trabaja el equipo de desarrollo con la suficiente tranquilidad en un ambiente cordial y creativo?

7. ¿Existe suficiente cordialidad entre los miembros del equipo para cooperar en el proyecto?

8. ¿Tienen los proyectos en los que trabajamos que estar finalizados «para antes de ayer»?, es decir, ¿se trabaja siempre con prisas?

9. ¿Buscamos trabajar de cerca con la gente que mejor sabe cooperar y trabajar en equipo?

10. ¿Existen individualismos en el equipo o personas para las que les resulta difícil trabajar en grupo?

11. ¿Fomentan los managers o gestores el buen clima en el equipo de trabajo y ponen todos los medios para que este avance correctamente?

12. ¿Aplicamos intencionadamente principios de diseño cuando programamos?

13. ¿Tendemos a simplificar algo que ya funciona habitualmente?

14. ¿Sentimos la necesidad de llenar de comentarios internos las piezas de código que escribimos?

15. Cuando alguien retoma nuestro trabajo, ¿tiene que estar preguntándonos continuamente por detalles que no termina de entender?

16. ¿Buscamos la maestría en aquellas tecnologías que creemos que conocemos suficientemente?

17. ¿Aplicamos conscientemente las tácticas descritas en el libro de Martin Fowler sobre refactorings?

18. ¿Evaluamos correctamente las librerías y componentes externos que se usan en nuestro proyecto y tenemos en cuenta su grado de evolución, madurez, comunidad de usuarios, etc.?

19. ¿Aislamos adecuadamente las librerías y componentes externos en nuestra aplicación para no depender de ellos excesivamente?

20. ¿Somos suficientemente conscientes de que al proyecto en el que trabajamos se le pedirán más cambios y que estos estarán en proporción a su éxito?

21. ¿Tenemos la tendencia de usar siempre lo último «porque sí» sin considerar si su uso es adecuado (y seguro) en nuestro proyecto?

22. ¿Preferimos usar tecnologías muy maduras antes que tecnologías incipientes y de rápida evolución?

23. ¿Consideramos el riesgo de usar módulos, librerías o componentes relativamente nuevos en nuestros proyectos?

24. ¿Estamos dispuestos a modificar profundamente una pieza de código en la que estuvimos trabajando mucho tiempo?

25. ¿Intentamos mantener a toda cosa un trozo de código sabiendo que se puede mejorar?

26. ¿Somos honestos con nosotros mismos cuando llegamos a la conclusión de que es mejor comenzar algo desde cero que forzar de la manera que sea la incorporación de nuevas características?

27. ¿Permitimos incluir en el equipo más gente en momentos de crisis cuando se acercan las fechas de entrega y se ve que de ningún modo se va a completar el trabajo?

28. ¿Advertimos a nuestros responsables de la falta de recursos para ejecutar con calidad y éxito el proyecto en el que trabajamos?

29. Si somos responsables de equipos, ¿tenemos claro que cuando un equipo falla es nuestra responsabilidad?

30. ¿Sufrimos demasiadas reuniones improvisadas?

31. ¿Las reuniones terminan durando mucho más del tiempo establecido y se discuten más temas de los incluidos en la agenda?

32. ¿Hacemos siempre un trabajo que previamente ha sido planificado por el gestor del proyecto?

33. ¿Se pasa por alto la metodología o las buenas prácticas en momentos de especial estrés o crisis por llegar a las fechas previstas?

34. ¿Cambia el gestor de proyecto de criterio continuamente?

35. ¿Tenemos todos los medios necesarios para hacer un buen trabajo?

36. ¿Comenzamos un nuevo proyecto o fase de desarrollo resolviendo las partes más complicadas o que más nos inquietan?

37. ¿Aplicamos continuamente refactorings al trabajo realizado o sólo cuando nos acordamos?

38. ¿Trabajamos siempre con la idea de la calidad en mente, eso es, queriendo hacer siempre el mejor trabajo?

39. ¿Dominamos suficientemente bien las tecnologías que se emplean en el proyecto?

40. ¿Nos ceñimos fielmente a la metodología que se usa desde el principio hasta al final del proyecto?

41. ¿Abandonamos las buenas prácticas metodológicas cuando sentimos presión?

42. ¿Trabajamos en equipos con talentos descompensados, esto es, unos muy buenos y otros muy «malos»?

43. ¿Se trabaja estableciendo una arquitectura general rígida al principio del proyecto cuando aún no están claros todos los requisitos?

44. ¿Es la arquitectura general del proyecto suficientemente flexible para poder modificarla durante el desarrollo del mismo o es extraordinariamente rígida?

45. ¿Está sólidamente establecida la metodología que se ha decidido seguir o se ignora a primeras de cambio?

46. ¿Se percibe claramente la rentabilidad que se extrae de seguir correctamente una metodología?

47. ¿Se relegan siempre para el final las tareas más aburridas o rutinarias?

48. ¿Nos preocupamos lo suficiente en que nuestro producto software esté bien hecho y funcione y además que lo aparente?

49. ¿Ponemos suficiente énfasis en el diseño de interfaces de usuario ágiles, intuitivas, amigables y elegantes?

50. ¿Nos ocurre a menudo que diseñamos interfaces de usuario pensando más en los propios desarrolladores que en los usuarios finales?

51. ¿Conocemos muy superficialmente multitud de tecnologías pero muy pocas en verdadera profundidad?

52. ¿Nos centramos más en conocer algo de muchas tecnologías que en resolver problemas reales con nuestro software?

53. ¿Sentimos la necesidad de usar lo último de lo último en un nuevo desarrollo «porque sí»?

54. ¿Indicamos en nuestro currículum los problemas que hemos resuelto con nuestro software o bien una retahíla de tecnologías que conocemos superficialmente?

55. ¿Tenemos el trabajo planificado con tiempo de antelación?

56. ¿Es corriente llegar a la oficina sin saber exactamente qué tenemos que hacer?

57. ¿Nos marcan las tareas que debemos realizar sobre la marcha?

58. ¿Sufrimos continuamente interrupciones durante nuestro trabajo?

Páginas

¿Por qué leer El Libro Negro del Programador?

Adquirir desde:
Amazon (kindle eBook / papel)
CreateSpace (papel)
PayHip (epub / mobi / pdf)

El libro negro del programador.com
Segunda Edición - 2017

El libro negro del programador.com
Now available in english!

Archivo

Trabajo en...

Mis novelas...