Tag Archives: Software

We don’t need more semi-senior developers

Hace casi dos años, postulé a puestos en los que me hacían preguntas de todo tipo, era algo extraño pero como era la primera vez –en años– en la que buscaba conectarme al mundo laboral –y bueno, esos procesos me causaban curiosidad– decidía continuar con las entrevistas,

¿Sabes BPM? ¿Oracle? ¿SAP? ¿Android? ¿AWS? ¿GCP? ¿Go? ¿C#? ¿Java?¿MySQL? ¿JavaScript? ¿Linux? ¿TDD?

Me gustaría decir que estoy exagerando, pero dicha entrevista existió (y se repitió en al menos un par de procesos más). Por mi parte no veo inconveniente en responder, pues es un hecho que nadie sabe todo, así que decía la verdad en cada caso. Y bueno, como me gusta conversar, al culminar una de las reuniones, le pregunté al entrevistador la causa de ese nivel de detalle, de eso encontré tres cosas:

Continue reading We don’t need more semi-senior developers

Principios de Arquitectura del nuevo Facebook Messenger

Hace poco me enteré de que los amigos de Facebook liberaron una nueva versión del Messenger para iOS. El nombre del proyecto es LightSpeed y los resultados son interesantes:

  • 1/4 del tamaño original
  • 2 veces más rápido
  • 84% menos en líneas de código (de 1.7M a 360k)

Mientras leo la publicación, encuentro que se habla de una plataforma de mensajería en vez de un app convencional. Creo que una visión de este tipo es muy importante si es que queremos dar un gran paso en el diseño de nuestro software. No está de más decir que una de las barreras que encontraremos regularmente, será el poco entendimiento de la diferencia entre plataforma, aplicación y herramienta.

Si bien es cierto la visión es muy importante, esta debe servir para definir –y abrazar– principios de arquitectura adecuados para cumplir con el sueño esperado.

1. Usar el Sistema Operativo

Aquí la clave fue eliminar el código que podía ser reemplazado por alguna funcionalidad del sistema operativo. Si este no lo hacía bien, pues se decidió construir una librería en lenguaje C, la cual estoy seguro será reutilizada en la versión para Android que lanzarán en algún momento.

Este tipo de estrategias es muy importante porque es una forma concreta de apoyar a la eliminación de código innecesario, el cual muchas veces se refleja en frameworks o intermediarios que a pesar de ayudarnos –bajo la perspectiva de programador– hace que la aplicación sea más lenta.

2. Usar SQLite

De lo que le he revisado no queda claro si antes utilizaban SQLite, pero en esta nueva versión toda la información que se utilice pasará primero por la base de datos local. Esto podría significar que no hay invocación directa a servicios pues la comunicación sería similar a lo que se ve en una aplicación monolítica convencional.

Queda mencionar que el gestor que se utiliza es una versión mejorada de SQLite. La diferencia radica en el soporte a stored procedures y de paso se promueve la reutilización.

A nivel de estructura de datos, lo que se ha buscado en esta nueva versión es eliminar los diseños complejos y reflejar en una tabla lo que se necesita para poder mostrarla en la interfaz de usuario. Estoy seguro de que son tablas con información redundante. Es decir, menos normalización, más velocidad 🙂

3. Reutilizar la Interfaz de Usuario

Cuando los amigos de Facebook revisaron el código fuente encontraron cosas interesantes, el caso que ponen como ejemplo es la cantidad de componentes visuales que representaban un mismo set de datos. Por ejemplo, se encontraron componentes diferentes para la presentación horizontal y la presentación vertical. Hasta aquí todo podría parecer natural, pero creo que encontrar 40 vistas para representar un mismo set de datos es un error que no se puede volver a cometer.

Lo que algunos hacemos en este tipo de casos es quedarnos con la vista que pueda ser tomada como base de reutilización o bueno, en el peor de los casos tenemos que crear un nuevo componente. Eso sí, en casi todos los casos iremos eliminando vistas innecesarias y por ende, código innecesario.

4. Usar –más– el servidor

Si bien es cierto estamos en la época de las aplicaciones que procesan información por medio de servicios o alguna de sus variantes, en este caso se aprovecha el procesamiento local (gracias a SQLite) y se trabaja con un componente que hace las veces de sincronizador de información. Lo interesante es que este componente está alojado principalmente en el servidor, lo cual me recuerda al concepto de publicador/suscriptor. Ojo que estoy tratando de simplificar conceptos, estoy seguro de que hay más trabajo por detrás 🙂

Comentarios

Me parece muy interesante de que Facebook invierta en un proceso de ingeniería que para muchos podría ser considerado como radical y que “no se puede hacer drásticamente pues no representará valor para el negocio”. Esto lo coloco entre comillas pues es una respuesta que encuentro regularmente cuando converso con desarrolladores de software que trabajan en proyectos en diferentes rubros.

Por otro lado, está de más mencionar que los beneficios hablan por sí solos, pero creo que es consecuencia de haber esperado tanto tiempo para poner una suerte de termómetro en el desarrollo que venían realizando. Estoy seguro de que hubo al menos una reunión en la que comentaba lo difícil que era seguir avanzando con el desarrollo y que lo mejor era rehacer algunas –o muchas– cosas si se buscaba mayor escalabilidad.

Con respecto a algunas consideraciones técnicas del trabajo realizado, la reducción de código es una consecuencia directa de la eliminación de código muerto y de haber descartado funcionalidades que eran menos utilizadas. También hay que resaltar la importancia de las automatización de pruebas unitarias y la respectiva cobertura, una vez escuché que en Facebook buscaban una cobertura del 100% y en este caso solo mencionan que el componente de sincronización cumple con ese objetivo.

Ahora, yendo un poco más atrás y revisando la presentación del proyecto en una sesión del F8 del año pasado, se menciona que el objetivo es contar con una nueva versión tanto para iOS como para Android, así que en cualquier momento tendremos mayores novedades 🙂

Un abrazo

Código Muerto 💀

Una de las anécdotas más comunes de un proyecto de software es que siempre hay una clase o una función que será recordada por el número de líneas que esta tuvo. Estoy seguro de que al menos una vez hemos escuchado:

“No toques esa clase, tiene como 1000 líneas de código”

Developer anónimo

Este es un dato particular de acuerdo a los proyectos en los que estuve y conversaciones entre amigos. Lo que es menos común, es saber cuántas líneas de código tiene el proyecto en el que estamos trabajando.

Si en este momento nos hacemos esa pregunta o se la hacemos a otro miembro del equipo, es posible de que no consigan una respuesta concreta. Si bien es cierto no considero necesario ser 100% precisos, he notado que pocas personas se preocupan de esa métrica, a menos claro, de que haya algún costo asociado.

Si no les ha pasado, les comento que casos como este se dan desde hace mucho en proyectos donde se audita código. Sin ir muy lejos, Amazon liberó [CodeGuru], un servicio (aún en preview) que analiza el código fuente. Como es de esperar, el costo está asociado al número de líneas y no es el único producto o servicio que hace este [tipo de trabajos]

Fuente: [Amazon CodeGuru]

¿Qué es lo que regularmente encontraremos?

He participado en proyectos donde el análisis o auditoría de calidad de software era uno de los objetivos más importantes. Muchas veces el costo de servicios adquiridos –u ofrecidos– estaba relacionado al número de líneas de código (o LoC por [Lines of Code]).

En cada trabajo era común confirmar lo encontrado en proyectos anteriores:

  1. Pocas personas conocían el número de LoC o la importancia de este indicador
  1. Una práctica conocida –y en algunos casos, aceptada– era “agregar código de ejemplo, ir cambiando y probando pero guardar la versión original por si algo se malograba”
  1. Muchas veces se mantenían las carpetas de plantillas y ejemplos de las librerías y componentes de terceros que en algunos casos ya no se utilizaban

Ya en un caso concreto, estuve en un proyecto donde el desarrollo tenía más de un millón de LoC y estaba seguro de que eso no podía ser posible pues las funcionalidades del sistema no reflejaban dicha realidad.

Sabía que estaba frente a un caso de Código Muerto, pero tenía que demostrarlo.

¿Qué es Código Muerto?

Sin entrar en detalles (pues es posible que encuentren discrepancias y hasta [una canción]), el código muerto o “Dead Code” es aquel que no aporta valor al negocio.

El código muerto se puede clasificar de la siguiente manera:

  • Código que no se usa: Muy usual en los proyectos de software, algunas veces no se recuerda su objetivo inicial y por lo general ocurre pues las necesidades van cambiando y el código no se depura adecuadamente luego de cada cambio (mucho cuidado con las frases “es que no hay tiempo” o “lo vemos después”)
  • Código que se ejecuta pero que no se usa: Aquí entran los casos como los de variables asignadas o llamadas a funciones cuyo resultado no es utilizado. Esto es nocivo pues además ser código inútil, consume recursos del sistema.

¿Cómo identificar Código Muerto?

Con el paso del tiempo preparé una secuencia de análisis que me sirvió para encontrar casos de código muerto bajo la premisa de que si algo se define en el programa, este debe ser utilizado de manera efectiva. La lista puede parecer obvia, pero ya está demostrado que en tecnología no debemos confiar en las obviedades 🙂

  • Variables
  • Funciones
  • Clases
  • Comentarios (sean redundantes o código que fue comentado para ser utilizado “más adelante”)
  • Elementos de archivos de configuración (por ejemplo, secciones comentads o que ya no se utilizan)
  • Archivos de configuración
  • Librerías (componentes de terceros)
  • Elementos idénticos (funciones, clases archivos, librerías o carpetas distribuidos en ubicaciones distintas)
  • Elementos parecidos (librerías con versiones diferentes, funciones o clases que inicialmente eran una copia de la otra)
  • Carpetas y archivos varios que poco a poco quedan relegados hasta el olvido

Un hecho común en todos los casos, es que el código muerto existe debido al temor a perder código o a malograr el sistema construido. Esto tiene relación directa con el desconocimiento de que los gestores de versiones permiten volver al pasado si es que se necesita ver algo que ha sido borrado.

Otra consecuencia es que a más código muerto, más complejo será el entendimiento de nuestro sistema, la mantenibilidad será afectada y a su vez generará dependencias con un programador en particular (a veces pueden ser más personas). Recuerden, el código es de todos los miembros del equipo y mientras menos dependencias, mejor.

¿Qué herramientas debemos usar?

Puede que parezca una broma, pero un elemento muy importante es la inspección visual. A pesar de ello, esta debe pasar a segundo plano pues debemos evitar confiar totalmente de los presentimientos o “literalmente” de puntos de vista.

De acuerdo a esta premisa, lo primero que debemos hacer es trabajar con [herramientas de análisis estático] que nos brinden un enfoque acertado de lo que está ocurriendo.

A pesar de ello, hasta el momento no he encontrado una herramienta que brinde un indicador de código muerto bajo un enfoque holístico. Es así que utilizo principalmente [SonarQube] como base del trabajo a realizar.

Regresando al caso del millón de LoC, encontré pistas que me ayudaron a confirmar la existencia del temible código muerto.

Si queremos empezar con estas prácticas, algo que nos podría ayudar está incluido en las herramientas del navegador web. Una de las que ha llamado mi atención es la utilizada para analizar la cobertura de los archivos JavaScript y CSS. Esta viene en [Chrome] y no es complicado de usar/entender.

¿Qué conseguí luego de presentar lo encontrado?

El objetivo de mi trabajo en dicho proyecto, fue preparar un informe sobre lo que se estaba construyendo y sobre eso un plan de trabajo para implementar una nueva arquitectura. No me parecía adecuado llegar con una presentación llena de indicadores ni menos señalar responsables (aunque en algunos casos ese ha sido mi trabajo), así que gracias al apoyo y explicaciones que el equipo dio cuando estaba analizando el código, tenía el conocimiento necesario para “limpiarlo”, al menos en casos que parecían obvios o donde veía que complejidad baja o media.

Como este tipo de trabajos me gustan, no paré hasta eliminar 95% del código del sistema. No esperaba llegar a ese número pero más de un millón líneas era código muerto que se podía limpiar fácilmente.

Nada mejor que llegar con un informe que tenga un entregable como ese 🙂

La buena noticias es que el equipo quedó sorprendido. Cuándo me preguntaron cómo lo hice, les comenté que empecé por las obviedades (y ya saben lo que pienso de ellas :)) creo que eso los animó a seguir limpiando (luego de una segunda limpieza el código no superaba las 30 mil LoC)

¿Qué es lo que aprendí?

  • Es posible que este tipo de trabajos sea incomprendido al principio, pero se consigue mucho enseñando con el ejemplo. En dicho proyecto tenía que preparar una arquitectura que aproveche lo que ya estaba construido, pero ante las sospechas de código muerto, decidí detenerme un momento y evaluar cómo eliminarlo, primero por mi cuenta y luego con el equipo.
  • Lo que he encontrado en muchos casos, es que hay pocas intenciones de refactorización que a veces no se dan por el uso desmedido de frameworks y herramientas. Lo que creo que se debe hacer es sentar una base medible de lo que está sucediendo sin olvidar que lo más se hace en un proyecto de software es la construcción del mismo. Si es así ¿por qué no saber cómo va creciendo nuestro código?
  • La automatización de pruebas es muy importante pero esta se debe postergar si hay casos obvios de código muerto, he comprobado que a veces resulta más rápido borrar (sin miedo) que ponermos a programar un caso de prueba.
  • Siempre debemos utilizar un gestor de versiones (personalmente prefiero Git sobre GitHub) y tenerlo enlazado a un motor de automatización (como [Jenkins] o [Azure DevOps], ambos me parecen buenos y Azure DevOps es más sencillo de configurar) que ayude a tener visibilidad de la integración continua.
  • El equipo de desarrollo pasa a otro nivel de conocimiento, pues además de entender la importancia de prácticas de limpieza de código muerto se abre una nueva puerta hacia la calidad del producto.
  • Si la confianza y comunicación son las adecuadas, este tipo de situaciones se convierten en anécdotas del equipo.

¿Cuál fue mi reflexión final?

Antes de refactorizar o hacer lo que sea en el sistema, eliminen el Código Muerto, no teman.

Un abrazo,

Fuente imagen cabecera: [Finding Dead Code]

¿Qué tanto le debes a tu sistema?

En términos simples, la deuda técnica tiene que ver con el tiempo que tendrías que invertir para solucionar problemas que estás dejando de lado a nombre de generar un resultado en el menor tiempo posible.

Sí, con esto me refiero a las consecuencias del “déjalo ahí, luego lo arreglamos”

Lo que me he encontrado es que esa es una frase que es aceptada hasta que los problemas se empiezan a poner serios. Por otro lado, hay que considerar que si queremos mejorar “algo”, pues tenemos que saber cómo medir ese “algo” antes y después de los cambios realizados.

¿Cómo mido un sistema?

Estoy seguro de que hay muchas formas para eso, pero aquí los pasos que sigo regularmente:

  1. Perspectiva del usuario final
  2. Comportamiento en tiempo real (análisis dinámico de código)
  3. Perspectiva del desarrollador (análisis estático de código)

1. Perspectiva del usuario final

Asumiendo de que el usuario está contento con las funcionalidades existentes y de que no hay errores en producción (Sí, es un gran supuesto), lo que normalmente sugiero es tomar nota del comportamiento de la aplicación.

¿Qué se hace ahí? Pues se mide lo que llega al usuario ¿Cómo medimos la aplicación? Para nuestra suerte, si estamos trabajando con una aplicación web, existen herramientas gratuitas que nos permiten tener reportes como el que nos genera [GTmetrix]

Fuente: [Análisis del blog personal]

Parece obvio, pero les cuento que he estado en proyectos en los que no se había considerado una revisión bajo esa perspectiva y ya se tenían quejas de que “el sistema estaba lento”

Lo bueno de herramientas como GTmetrix, es que brindan una mirada objetiva de lo que le entregas al consumidor final. Aquí es donde encontrarás aspectos como el tiempo de carga de la página (Fully Loaded Time) o incluso el tamaño de lo que se descarga al navegador (Total Page Size)

Por otro lado, GTmetrix incluye una serie de análisis usando herramientas como [PageSpeed] o [YSlow]. Para ambos casos se genera un score que puede mejorarse si sigues las recomendaciones que, para tener una idea, se crearon bajo estándares de Google (para el caso de PageSpeed) o Yahoo! (para el caso de YSlow)

Otra opción interesante viene con Google Chrome y se puede usar desde la opción Developer Tools/Audits, lo cual, en resumen, hace uso de [Lighthouse], que también es usado por Google PageSpeed 🙂

Fuente: Archivo personal

Los que me conocen saben del cariño que le tengo a YSlow y que me apena que ya no haya una extensión de navegador para hacer un análisis a ese nivel de detalle. Tiempos aquellos 🙂

Update: Si pueden denle una oportunidad a https://yellowlab.tools/ Se ve muy interesante!

2. Comportamiento en tiempo real (análisis dinámico)

Una vía rápida para reaccionar a lo que le ocurre al sistema, es saber lo que le pasa a este mientras va funcionando. No soy partidario de esta forma de trabajo, pero en sistemas que ya se están ejecutando en producción es importante contar con al menos una herramienta que permita tener una vista de ese tipo.

Aquí es donde hablamos del análisis dinámico del código con herramientas del tipo APM (Application Performance Monitor). Una que hace muy bien ese trabajo es [New Relic]

Fuente: [New Relic]

La importancia de este tipo de herramientas radica que no son invasivas. Es decir, no tienes que tocar tu código y la performance de la aplicación no se ve afectada. Antes de New Relic probé otros analizadores que degradaban la aplicación al punto que decidíamos desactivar el analizador.

3. Perspectiva del desarrollador (análisis estático)

Tal como mencioné en la sección anterior, no soy partidario de ir reaccionando acorde a lo que le ocurra al sistema pues creo firmemente que la mejor forma de solucionar un problema es evitándolo.

Bajo esa premisa estamos en la obligación de encontrar mecanismos que permitan controlar lo que se está construyendo o modificando. Aquí es donde entran herramientas como [SonarQube]

Fuente: Archivo personal

Lo bueno de esta herramienta (entre muchas cosas) es que te ayuda a clasificar los posibles problemas de programación y te da una estimación base de lo que necesitarías para cubrir esa deuda técnica.

¿Qué ocurre normalmente?

Lo que he encontrado en algunos proyectos es:

  1. No se mide lo que se está construyendo
  2. Se mide lo que se construye pero en términos de deuda técnica convencional (análisis estático con SonarQube)

No pondré en duda si se toma acción sobre la deuda técnica pero lo que regularmete encuentro es que se pierde la perspectiva de lo que ocurre en producción o se hace a consecuencia de un problema.

¿Qué estamos perdiendo?

No soy un experto en el tema pero les puedo asegurar que poco a poco iremos perdiendo el control de nuestra aplicación analizada. No he encontrado un estudio detallado del impacto financiero al respecto, pero valgan verdades hay situaciones en las que el equipo de desarrollo sugerirá rehacer un componente/servicio/módulo/aplicación a consecuencia de que lo encontrado es inmantenible.

¿Se imaginan eso en términos financieros? Pues ahí un primer vistazo al dinero perdido a consecuencia de una deuda técnica mal gestionada.

¿Qué tenemos que hacer?

La primera respuesta es obvia, “tenemos que medir nuestra aplicación” pero en realidad, además de invertir para lograrlo, hay mucho por hacer al respecto pues lamentablemente no he encontrado una herramienta que nos muestre lo que es realmente la deuda técnica. Si bien es cierto SonarQube nos da una idea al respecto, pero no podemos confiar en ese único indicador (Resumen, SonarQube te ayuda pero no es la solución definitiva ☹️)

La segunda respuesta tiene que ver con lo que algunos llamamos el diseño y ejecución de nuestro plan de pagos. Es decir ¿cómo vamos a ir pagando nuestra deuda técnica?

Es aquí donde tenermos una [gran responsabilidad], pues además de englobar esta serie de issues/riesgos/problemas/bugs tenemos que darle forma al indicador y a su impacto técnico/financiero. Por otro lado, debemos aceptar que siempre estará ahí pues estoy seguro de que no hay proyecto que elimine la deuda por completo. Es decir, siempre habrán issues con los que tendremos que convivir, pero si es así, tiene que ser una convivencia sana 🙂

Un abrazo,

¿Qué tan importante es la arquitectura de un sistema?

¿Qué ocurre “normalmente”?

Me gustaría empezar aclarando lo que posiblemente muchos hemos vivido en nuestros proyectos. Un sistema se construye con o sin una arquitectura definida. La realidad indica que quieras o no, el sistema se construirá pues así lo determina el negocio. En resumen, tenemos que responder a una necesidad.

Si el sistema ya está en producción y no está claro si hubo un trabajo de arquitectura, más que tomar una posición al respecto, lo que debemos hacer es evaluar y fundamentar con evidencias, el comportamiento del software desde su primera liberación al usuario.

Fuente: [Clean Code]

Si el sistema no ha presentado problemas a consecuencia de cambios constantes en el negocio, podremos concluir de que la decisión tomada fue la mejor para esa realidad. Claro está, que eso no implica que dicha formula funcione para otras realidades.

Ahora, si es que está en nuestras manos incluir este tipo de trabajos (es decir, los de arquitectura), pues tenemos que hacerlo sin dudar siquiera un segundo 🙂

¿Cuál es el impacto “mínimo” de una arquitectura?

En este tipo de situaciones considero poco profesional que nos basemos en supuestos, puntos de vista, corazonadas o peor aún en feelings, pues lamentáblemente estos no nos servirán en momentos que llegan gracias a los clásicos y no tan queridos “cambios de última hora”. Es por ello que en vez de feelings, lo mejor es que tengamos a la mano hechos concretos:

  1. Impacto en el proyecto: Un caso –muy gráfico– se remonta a un hecho ocurrido en USA en 1940. Si no conocían [la caída del puente Tacoma Narrows], les comento que hay [estudios al respecto] y que todo indica que el diseño inicial omitió consideraciones como por ejemplo, el efecto que tendría el viento sobre la estructura del puente ¿Servirá de algo compartir este tipo de experiencias? Esto lo dejo a su elección, pero vale la pena mencionar que para esa época, USD 6MM fue la cantidad de dinero que literalmente “se fue al agua”
  1. Rapidez de implementación: Podría sonar lógico escuchar que una buena práctica incrementa la rapidez del desarrollo, pero es mejor mostrar un caso en el que, por ejemplo, TDD genera una mejora de al menos 30% del tiempo esperado bajo “condiciones normales”
  1. Costos de mantenimiento: Si bien es cierto este estudio se hizo hace más de veinte años, estoy seguro de que se han encontrado con problemas que son complicados de resolver, pues la solución implicaba “cambiar muchas cosas”. Aquí un gráfico que refleja lo encontrado luego de analizar proyectos en empresas como HP o IBM, el cual en resumen indica que si hemos avanzado mucho en el trabajo y nos encontramos con un error, corregirlo será muy costoso.
Fuente: [Code Complete]

¿Qué consideraciones debe incluir nuestra arquitectura?

La “respuesta corta” es, tenemos que implementar nuestro sistema considerando una arquitectura que soportará las necesidades del negocio.

La “respuesta larga” incluye estas consideraciones:

  1. Estamos en la época en la que gracias a la agilidad, podemos confirmar en plazos cortos si nuestro producto (o parte de este) es útil. De aquí es donde se desprende el concepto de valor.
  1. El valor se asocia a la utilidad desde el punto de vista el usuario, y eso es bueno, pero lo que no debemos olvidar es que el usuario final no es ni será el único usuario del sistema. Pues de alguna u otra manera, los desarrolladores y resto del equipo técnico son usuarios. Por consiguiente, el valor también se debe visualizar desde una perspectiva técnica.
  1. Este “valor técnico” muchas veces es confundido con una necesidad que podría estar en una prioridad distinta a la requerida por el usuario final. Y es lo que comúnmente ocurre, pues “eso es transparente para el usuario”
  1. Esta nueva restricción podría basarse en la experiencia del equipo, pero lo recomendable es incluir criterios de calidad probados por el mercado. Para esto hay muchos modelos, pero creo que una base muy entendible es [la propuesta de Jim McCall]:
  1. Cubrir los criterios de cada perspectiva, requerirá contar con una arquitectura que las soporte y un conjunto de prácticas que no necesariamente se verán reflejadas en el diseño, pero sí en la implementación del mismo. Es aquí donde entran a tallar el uso de estándares de programación o de prácticas como la de TDD o incluso prácticas de DevOps (y la lista podría ser muy larga)

¿Dónde está el código?

Si bien es cierto soy partidario de hablar con código en mano, este es un caso en que necesitamos aceptar que el código llegará luego de entender con claridad los criterios mencionados por el Modelo de McCall. La mala noticia es que no hay magia en este trabajo, si queremos empezar y no sabemos por dónde, pues podríamos tener en cuenta lo siguiente:

  1. Hace poco escribí sobre [10 aspectos a considerar si les interesa la arquitectura]. Si es que ya se sienten listos para empezar con la parte técnica, pues les sugiero revisar los puntos 3 y 7 (Conceptualizar y Estudiar y poner en práctica).
  1. Si bien es cierto [mi post] lo menciona, es posible que no esté claro cómo empezar con lo que denomino “conceptualización” ¿Cómo podrían empezar con esto? Pues este gráfico de niveles de diseño, les dará una idea de lo que a algunos les podría parecer obvio, pero que a pesar de ello he notado que muchas veces no se hace bien, debido a la necesidad de escribir código lo más pronto posible.
Fuente: [Code Complete]
  1. Este tipo de razonamiento se debe complementar con conceptos de diseño como [acoplamiento / cohesión] y claro, de [SOLID]. De este último he encontrado un [video que lo explica muy bien] y que además muestra ejemplos de código.

Conclusiones

Creo que sobran argumentos sobre la importancia de la arquitectura de un sistema, pero esto no sirve de mucho si no aceptamos que la arquitectura es solo una parte del trabajo que debemos realizar.

Líneas arriba mencioné la relación que existe entre la arquitectura y las prácticas como TDD, DevOps y aquí podría agregar los estilos de arquitectura, el uso de patrones de diseño, automatización de pruebas y herramientas que nos permitan acelerar de manera eficiente el trabajo del equipo de desarrollo. Sin olvidar claro, el concepto de valor.

Por otra parte, lo que no debemos hacer es separar el concepto de valor en más de una vertiente. Mi explicación del “valor técnico” fue hecha por la necesidad de demostrar de que el “valor” incluye otros factores, y que en primera instancia estos son transparentes para el usuario, pero con una correcta asesoria este comprenderá la necesidad de incluir estos alcances a lo largo del proyecto.

Me gustaría agregar que la entrega de valor debe estar equibilibrada bajo la premisa de que no hay un solo tipo de usuario. Esta es muchas veces una línea delgada con alto riesgo de ser confundida u omitida.

Un abrazo,