sábado, 21 de abril de 2018

Acerca de lo urgente y lo importante en el desarrollo de software

Lo importante es tener detectores de humo que funcionen correctamente, lo urgente es salir corriendo de tu casa si se está quemando.

"I have two kinds of problems, the urgent and the important. The urgent are not important, and the important are never urgent.", Dwight D. Eisenhower

Matriz de Eisenhower

En nuestra profesión, el desarrollo de software, nos enfrentamos casi exclusivamente a tener que resolver dos tipos de problemas, los urgentes y los importantes.

Los problemas urgentes son aquellos que tenemos que resolver de forma inmediata para que el negocio que soporta nuestro sistema siga operativo. Si estos no se resuelven, se puede generar una situación que conlleve una grave crisis, incluyendo pérdidas materiales (o en el peor de los casos humanas), y que en última instancia nos acabe sacando del mercado, con consecuencias de diversa índole.

La resolución de temas importantes, son los que nos ayudan a que nuestros sistemas siguán vigentes en el futuros, nos ayudan a proyectarnos hacia delante, es la planeación a gran escala y a mediano y largo plazo.

En la práctica hay que saber balancear adecuadamente las tareas importantes y urgentes. Una mala gestión de lo que es importante y urgente, lleva siempre al desastre.

Es muy común, olvidarse de las tareas importantes, para ocuparnos exclusivamente de lo urgente, pero una cosa es innegable, cuando mas postergamos las tareas importantes, mas se van a convertir en urgentes (además de importantes).

Las tareas importantes son las que generan beneficios (en el negocio) de un sistema, son las que nos permite adaptarnos adecuadamente y de forma proactiva al mercado, ser innovadores y poder marca una diferencia y posición.

Las tareas urgentes son tareas enfocadas la reactividad, a reaccionar al mercado (en lugar de incidir en el), hace que tengamos que centrarnos en la "supervivencia", y no generan beneficios, son cosas que "tienen que hacerse".

Si clasificamos nuestros issues en mejoras y defectos de nuestros sistemas productivos, las mejoras serian los cambios importantes, los que generan benéficos (económicos en última instancia), es la evolución de un sistema hacia nuevos retos y horizontes, los defectos por otro lado son los elementos urgentes, lo que hacen que un sistema funcione mal. Corregir defectos no genera beneficios, sino que hace que un sistema funcione como se supone que debiera funcionar. Todo el tiempo (y dinero) invertido en corregir un error, son recursos que no se van poder recuperar y que no van a generar nada.

Otro ejemplo acerca de lo que es importante, es el ejercicio físico y cuidar nuestra alimentación, eso nos proporciona una vida sana y más placentera, hacia el futuro y a largo plazo, una enfermedad es algo urgente y que debe ser atendida, en el mejor de los casos al tratarnos recuperarnos nuestro estado inicial (antes de la enfermedad), pero nuestro cuerpo no va estar mejor (en todo caso igual), es la diferencia entre prevenir y curar. Los sistemas, son iguales, pueden considerarse elementos orgánicos (por eso hablamos del "tiempo de vida de un sistema"), en los que si invertimos en lo importante (como la arquitectura), nuestro sistema va a estar más sano, mas adaptable y menos propenso a fallos, que si nos dedicamos solo a lo urgente, el negocio. Los "urgente", será cada vez mas rápido y sencillo de atender, y podrá ser resuelto con menos recursos y esfuerzo. Al igual que en el cuerpo humano, si no atendemos lo urgente, el sistema tampoco funcionara a corto plazo, pero una vida sana, a la vez que un sistema sano, podrá hacer frente con mas capacidad a los problemas inmediatos e imprevistos.

Los temas urgentes e importante, se pueden clasificar, según la matriz de Eisenhower, en los siguientes elementos:


  • Urgente e importante: Es necesario realizarlo inmediatamente, con una supervisión cercana, disminuyendo la burocracia y aumentando las facilidades de comunicación entre los diversos miembros del equipo. Las tareas importantes no atendías a tiempo se convierten en urgentes, el negocio (sobretodo) y la arquitectura (en menor media) entran en este rublo.
  • No urgente e importante: Es necesario planearlo adecuadamente, decidir cuándo deben realizarse, antes de que se convierta en urgente. Atender un tema aquí es mucho más barato que dejar que se convierta en un problema. La arquitectura (principalmente) y el negocio (en menor medita) entra en este rubro.
  • Urgente, pero no importante: Es necesario delegarlo en la medida de lo posible, si no es posible delegarlo, hay que establecer unos tiempos, y espacios de resolución, y resolverlos adecuadamente, suele ser llamadas o correos o interrupciones. El consejo es dedicar una fracción del día en resolver esto problemas, como por ejemplo, una hora en contestar email y llamadas, y el resto de tiempo dedicarlo a la planeación (y ejecución) o los temas urgentes.
  • No es importante, ni urgente: No lo hagas, estas tareas no aportan nada, es necesario eliminarlas después de identificarlas apropiadamente .

Un mayor detalles de la matriz.


Mi organización personal de día a día, en estos asuntos, es de la siguiente forma:

Reunión general de equipo, aquí surgen los temas importantes y urgentes del día a día, lo que se tiene que resolver en el momento y lo que tiene que postergar

Segundo revisar el correo para realizar una planificación del día, es necesario comenzar a leer los correos, desde el ultimo al primero, el correo más urgente siempre es el último en ser recibido. Créeme que si tienes un correo importante que has recibido el primero, te vas a enterar por otro medio, ya sea telefónico o en persona. Los últimos correos siempre tiene la información más reciente y más importante, no hay nada más molesto y caótico que alguien que contesta un correo intermedio de una conversación.

Al leer los correos decide, en ese momento, si es urgente y atiéndelo o si es importante. si es importante ponle una fecha o delégalo, si no es importante ni urgente bórralo. A esto le dedico una hora o menos

Si tengo muchos asuntos urgentes que atender… bueno es que estoy haciendo realmente mal mi trabajo.

Después reviso mis tareas, ya sea por planeación o por un sistema de ticket, si puedo delegarlo, siempre lo delego, y siempre con una fecha.

Para una planeación correcta es necesario liberar siempre las tareas que crean dependencia con otras, es decir las tareas que hay que resolver forzosamente antes que otras. Por ejemplo al momento de crear una componente que sea una API consumible por otros, hay que definir antes la interfaz, y después implementarla. Es decir, si primero liberamos la interfaz (entiéndase no la grafica, si no la interfaz de consumo, las estructura de nuestro sistema), los consumidores de nuestra funcionalidad ya podría comenzar a desarrollar sus propios componentes, aunque nuestro componente no haga nada, es decir sean simplemente clases vacías, así es posible realizar un desarrollo en paralelo en lugar de secuencia.

Aquí se ve otro ejemplo de lo urgente y lo importante, lo urgente es la interfaz (la API, lo que define lo que hace el negocio), la implementación de dicha API (lo que realmente hace) no es urgente, es importante y puede ser resuelto mas tarde

Una vez resuelta la planeación es el momento de ponernos manos a la obra, ya hemos resuelto lo urgente, y podemos dedicarla el tiempo a los seria "trabajar", a implementar nuestro sistemas o sus mejoras, en mi caso comienzo mis labores de supervisión y verificación de código

lunes, 5 de marzo de 2018

Acerca de la mantenibilidad del software


Hace ya un tiempo vi la siguiente imagen en internet, acerca de una experiencia que casi cualquier programador ha vivido:


La verdad es una imagen que me arranco una sonrisa, y a la que francamente me he enfrentado en multitud de ocasiones. Como antiguo programador de Visual Basic clásico (anterior a Microsoft.NET), me he encontrado código con multitud de variables globales sin tipo ( e incluso con más de un objetivo cada una), con funciones kilométricas llenas de gotos, controles de errores extrañísimos, funciones altamente acopladas o if encadenados hasta el infinito. Sistemas que fallaban si tosías cerca demasiado fuerte. Recuerdo que bromeaba con que esas líneas no eran código fuente, si no un conjuro escrito en una antigua lengua olvida, que levantaba el sistema.

El caso es que un software vale tanto como tan mantenible puede llevar a ser. Un sistema no es un edificio que pueda estar levantado inmutable durante siglos, es un ente que debe evolucionar para ajustarse a las mismos cambios por los que pasa el mercado, el dominio que intenta abarcar nuestro sistema, lo que llamamos habitualmente el negocio. De esto hemos hablado aquí y aquí.

Es obvio que de forma inconsciente y progresiva todos queremos cierta estabilidad en el negocio que estábamos implementando, y cuando mas tiempos hemos estado involucrados en dicho negocio (sobre todo si es de una forma pasiva), menos vamos a querer que cambie, incluso podemos, sin darnos cuenta, sabotear el cambio. Esto se llama zona de confort. Sin embargo, basta con dar un vistazo al mismo mercado de nuestra profesión para darnos cuenta que el cambios es algo inevitable, veamos cómo ha cambiado la informática desde los 90 hasta ahora, o la telefonía móvil desde hace una década. los cambios son cada vez mayores y mas rápidos, los sistemas que antes duraban décadas, pasaron a durar años y en la actualidad tenemos sistemas que reciben actualizaciones cada pocas semanas o incluso a diario. Es inútil negar la necesidad de cambio y adaptación que tiene los sistemas actuales, hacerlo es condenar a nuestro negocio a quedarse obsoleto en el mercado y finalmente a desaparecer.

Lo cual nos lleva a la imagen que acompaña al post, imaginemos que es una situación real, estaría impidiendo a nuestro sistema poder adaptarse a nuevas necesidades, dejándolo atrapado estáticamente en la misma funcionalidad.

Pensando en cómo se ha llegado a esa situación, posiblemente sea por alguno (o todos) de los siguientes problemas y errores:

  • Es una función terriblemente grande, con muchos caminos y ramificaciones, tal que no puede ser comprendida en su totalidad.
  • La función hace más de una cosa
  • La función usa, y modifica, variables globales.
  • La función necesita ser llamada en determinada secuencia junto con otras.

En resumen la función esta acoplada fuertemente dentro del sistema, de forma que no puede ser considera una parte independiente, extraíble o sustituye. Es un "todo" junto con el resto de funciones.

En esta situación es una bomba de tiempo esperando explotar en cualquier momento, es necesario ser consciente de la situación y ponerle remedio, analizar las dependencias de la función o el modulo oportunamente y reestructurarlo para que el sistema sea libre de poder recibir nuevos cambios y funcionalidades con el menor impacto posible.

viernes, 23 de febrero de 2018

El uso beneficio de los IDEs en la programación


Una de las cosas que más me sorprenden cuando leo foros en internet, es cuando alguien, generalmente estudiantes, pregunta si es malo usar IDEs y multitud de personas contestan que "si" o les recomienda usar el "bloc de notas".

Hay que considerar que cada oficio tiene sus herramientas y si queremos desarrollamos profesionalmente debemos usar sin miedo las que son propias de nuestro trabajo. En nuestro caso como programadores son los IDEs.




Qué es un IDE?


IDE es la abreviatura de Integrated development environment (Entorno de Desarrollo Integrado).

Originalmente (o más bien regresándonos a un punto preciso del pasado para clarificar esta idea), los programas eran creados en una terminal, usando cualquier editor (o entrada de texto disponible), para posteriormente ser compilado y enlazado, los pasos exactos serian.
  • Creación de los archivos fuentes: Se crean (de la forma que sea) una seria de archivos de código fuente. Si nuestro código es un ejemplo posiblemente sea solo un archivo uno, pero lo normal es que se sean multitud.
  • Compilación de los archivos: El conjunto completo de los archivos que se ha creado representa a nuestro sistema pero es necesario compilarlos a código maquina por separado. Cada archivo se convierte en otro en código maquina.
  • Unión o “Lincado” (link): Se unen los distintos archivos en código maquina, en un solo “ejecutable”. A partir de allí podemos ejecutar nuestro sistema
  • Depuración: Nuestro sistema va a fallar, te lo aseguro. Nunca va a funcionar un sistema a la primera, con lo cual necesitamos depurarlo. Necesitas comprender por qué está fallando y donde.

Estos pasos son extremadamente repetitivos, así que se construyeron herramientas para poder hacerlos de forma más ágiles, como por ejemplo la herramienta make.

Esto pasos, en esencia, son exactamente los mismos que se tienen que ejecutar en la actualidad, creación, compilación, unión y depuración. los IDE con herramientas que nos permiten realizar todas esta tareas desde un mismo entorno, y de la formas más sencilla y rápida posible.




En los 80 y sobre todo en los 90 se popularizaron mucho los IDEs (y en la actualidad son indispensables). Microsoft ofrecía un IDE de BASIC (qbasic y anteriormente gwbasic) en su SO y Borland unos magníficos, y clásicos, compiladores de C, Pascal y Asm (y prácticamente de cualquier lenguaje interesante), Después en los 2000 llegaron nuevos IDE acordes a las nuevas necesidades como Visual Studio, Eclipse, Xcode o JetBrains.





¿Qué hacen actualmente los IDE?


Para que un ambiente pueda considerarse un IDE, lo mínimo que debe ofrecer son las funcionalidades de edición de código fuente, compilación, unión y depuración.


Los IDE actuales ofrecen gran cantidades de herramientas , tal como:

  • Editores de texto avanzados , con resalte de sintaxis, ayuda en línea sensible al contexto, búsqueda de referencias y análisis de código a la vez grandes capacidades de refactoring…
  • Creación de Interfaces Gráficas: Se pueden crear interfaces gráficas de forma rápida.
  • Grandes capacidades de depuración: Se puede controlar la depuración de múltiples formas, incluso modificar los valores de las variables y el mismo código al momento de la ejecución.
  • Integración con sistemas de control de versiones y seguimiento: Los sistemas actuales se pueden conectar con subversión o git (o otros sistemas de control de versiones) de forma sencilla, además algunos se integran con elementos de seguimiento y colaboración entre equipos de trabajo
  • Plantillas y elementos pre-creados: Los IDEs suelen ofrecer múltiples plantillas y elementos previamente creados, para que no tengamos que elaborar de cero nuestros sistemas.
  • Descarga de librerías y framework comunes: Los IDE pueden conectarse a repositorios comunes de componentes reutilizables (junto con sus dependencias) y agregarlos automáticamente a nuestro sistema.




¿Por qué debo usar IDE en nuestro trabajo?


A veces pienso que nuestra profesión es la única que se cuestiona por que debe usar herramientas para hacer más sencillo nuestro trabajo. Cuando salió C, se decía que era mucho mejor programar en ASM, cuando salido C++, C era mejor, igual paso con Java o C#, es como si nos resistiéramos a hacernos la vida más fácil por una falsa sensación de “autenticidad” que da hacer las cosas de forma más complicada. ¿Se cuestiona acaso un carpintero acera de usar herramientas más potentes y mejores para hacer su trabajo, o un doctor desecha mejores y mas modernos medios de diagnostico?





Hay que comprender que las necesidades empresariales hacia nuestros sistemas no van a acabarse nunca, siempre van a estar evolucionando, cambiando y creciendo, haciendo que nuestro tiempos y recursos disminuyan. Si podemos ser más productivos con una herramienta , mientras garantizamos la calidad de nuestros software, debemos serlo.

Nuestro objetivo es resolver, mediante software, las necesidades de nuestros clientes. Nuestro cliente no quiere deslumbrarse con nuestra capacidad de escribir en el bloc de notas, ni necesitamos impresionarle con una mal entendida independencia de herramientas de desarrollo. Lo único que quiere nuestro cliente es un sistema que le resuelva un problema.

Es importante conocer un lenguaje de programación, pero realmente no es tan importante como saber comprender y resolver los problemas de nuestro cliente. las tecnologías cambiar constantemente, y en los últimos años con mayor rapidez. Lo que hoy es una la solución para todos los escenarios posibles, en cinco años estará obsoleto y será reemplazada por algo mejor y mas potente, con lo que todo ese esfuerzo que hemos hecho para conocer una api, o ciento de funciones, quedara en nada. Si tenemos herramientas como los IDE que nos ayudan a centrarlos en lo importante, en hacer sistemas, tendremos más tiempo para hacerlos mejor, más rápido y de más calidad, en definitiva, mas productivamente.

jueves, 25 de enero de 2018

Regla N°16 de la Ingeniería de Software: Por defecto todo es privado (principio de ocultación)


Esta semana me paso algo que definitivamente creo que merece una nueva regla. Me encontraba con la necesidad de modificar la implementación de una funcionalidad dentro de un componente de uso común, el motivo es porque se comportaba de forma errónea. Hasta allí todo era normal, una modificación de un componente que no debiera impactar en absoluto al comportamiento ni a la implementación de los sistemas que lo consumen. Cuando me di a la tarea, apareció una variable pública dentro de la clase, que además era parte fundamental de la implementación… y allí comenzaron todos los problemas.




El hecho que estuviera pública la variable implicaba que cualquier cambio hacia la misma afectaría a los módulos que ajenos al sistema que la consumieran (y en este caso así era). La funcionalidad estaba horriblemente implementada (y era incorrecta), y la variable francamente era innecesaria, sin embargo debiera mantener compatibilidad con la multitud de sistemas que la usaban. Aquí había dos opciones, mantener la variable y de alguna forma modificar a funcionalidad para que la sigan usando en los mismo términos (cosa que se me hacía un malabarismo completamente innecesario y perjudicial, a la vez que chapucero) o rediseñar la funcionalidad y solicitar a todos los sistemas que se adecuaran a ella, con lo que implicaba coordinar una liberación múltiple de sistemas. Una tercera opción es mantener los dos componentes productivos, el que tiene el error y el que no, pero eso implicaría un doble mantenimiento en supuesto caso que hubiera que mover nuevamente el componente.

Intentando comprender que motivos tenía el programador para crear un variable (que claramente tiene un ámbito privado), como publica, me doy cuenta que se comparte entre dos módulos del mismo componente, esto de por si era innecesario, pero no solo no se redujo el ámbito de la variable al nivel del componente, si no que se hizo totalmente pública.

He observado que esto es un problema muy común de muchos programadores noveles, escriben la palabra "public" por inercia al momento de crear una nueva funcionalidad, sin pararse realmente a pensar que están haciendo, y solo cuando lo meditan bien escriben "privado". A veces no se dan cuenta de esta circunstancia, otra veces piensan que es más sencillo, si todo es público, a veces incluso piensan que le dan cierto sentido de "libertad", cuando lo que se hace abrir puerta al desastre (la “libertad” la da en todo caso, compartir el código fuente, no habilitar métodos privados como públicos).

La verdad es que se lo único que se está haciendo es romper el "principio de ocultación". El principio de ocultación indica que cualquier implementación interna de una clase debe estar oculta para los consumidores, no debiera mostrarse variables de ningún tipo, si no que la interacción y la modificación de la instancia de una clase se hacen mediante mensajes (representados genialmente a través de métodos, o propiedades). Generalmente esto se consigue mediante el encapsulamiento, agrupar dentro de la clase todo lo que le de identidad como tal (tanto funcionalidad, como datos), y solo exponer los mensajes necesario para interactuar con ella.

Partamos de una clase que tiene todo privado. Ok… ese tipo de clase no sirve de nada, puesto que necesita comunicarse con el exterior, o más bien el exterior necesita comunicarse con ella para que sea útil, eso es porque la clase tiene una responsabilidad (debemos asegurarnos que solo y exclusivamente tenga una). Debemos asegurarnos de exponer solo los métodos (o propiedades), mínimas indispensables para poder comunicarse, cuanto menos sean mucho mejor será.

Con esto estoy garantizando otro principio, que es el del desacoplamiento. Esto es que las clases dependan muy poco entre ellas y de sus implementaciones particulares, de forma que pueden ser sustituidas fácilmente por otro tipo de la implementación, o incluso con otras clases, sin mayor impacto en sus consumidores. Esto era imposible en mi escenario, el hecho que los sistemas usaran una variable pública implicaba que dependía mucho de cómo internamente se usaba ese variable, impidiendo cualquier sustitución, con los que estaban demasiado acoplados.

Existen los siguientes grados de ocultamiento (en la mayoría de los lenguajes):

  • Privado: El más restrictivo. Cuando más privado sea todo más desacoplado será, Solo la misma clase puede usar un método privado.
  • Protegido: Solo puede usarlo la misma clase o sus descendientes. Por lo que por lo menos garantizamos que no hay un consumo indeseado desde el exterior de clase. Si no hay algún motivo para hacerlo protegido, debiera seguir siendo privado, es más fácil cambiar un método de privado a protegido, que al revés.
  • Interno: Aquí entramos un poco un terreno más público. Indica que todos los módulos (clases) que pertenezca al mismo componente, podrán usar el método, en este escenario seguimos teniendo el control de lo que es público y privado, ya que siguen siendo llamadas que ocurren en el interior de nuestro componente.
  • Público: Aquí ya estamos en el ámbito publico totalmente, cualquiera podría usar el método o la variable en cualquier momento y forma, con lo que sí está mal expuesta (como nuestro caso), los métodos que la implementan lo harán de forma incorrecta, dificultando el poder reemplazar el componente por otro más optimo debido al acoplamiento sufrido.
  • Amistoso "friendly”: Este es algo curioso, es cuando un componente tiene “derecho” de acceso a un método privado de otro componente. Tenemos en este caso dos componentes que no tienen nada que ver entre ellos y sin embargo uno puede acceder a los métodos privados del otro. Aquí hay un problema de cohesión, debido a que si es realmente necesaria la “amistad” seguramente debieran ser el mismo componente y no dos componentes separados. Además hay un problema de acoplamiento debido a que estamos haciendo que un componente que no tiene nada que ver con otro, conozca detalles de su implementación interna.

En definitiva debemos usar el modificador más restrictivo siempre e ir haciendo publico según tengamos la necesidad, cuestionándonos siempre si realmente es necesario el cambio. Esto reducirá el acoplamiento de los componentes y nos facilitara el mantenimiento en nuestros sistemas.

jueves, 11 de enero de 2018

Regla N°15 de la Ingeniería de Software: Haz que las cosas sucedan

"... En la guerra puede haber cambios de circunstancias ante las cuales el general debe reaccionar. Decir que debe esperar las órdenes del soberano para decidir es como esperar las órdenes para apagar un fuego. Antes de que lleguen las órdenes pertinentes, todo estará reducido a cenizas." Sun Tzu, el arte de la guerra.

Una de las cosas que más afectan al éxito del desarrollo de un sistema es la pasividad y falta de proactividad. Esto es, principalmente, quedarse esperando a que las cosas pasen por si solas.

Muchas veces existen escenarios de incertidumbre en que no queda claro que es lo tenemos que hacer en cuanto al sistema que se está construyendo, esto puede ser por muchos motivos, puede ser una falta de visibilidad del objetivo real o que no se nos ha comunicado apropiadamente.

Pero es necesario comprender que mientras el sistema no esté finalizado (satisfaga las necesidades del cliente), hay tareas pendientes que hay que resolver y es responsabilidad de cada integrante del equipo conocer cuáles son y conseguir se lleve a cabo. Es responsabilidad de cada uno hacer que las cosas sucedan.


Los escenarios por los se puede caer en la pasividad son, entre otros, los siguientes:

  • No existe una fecha de finalización del proyecto. Esto provoca que no se dé la suficientemente importancia a acabar el proyecto, siendo laxos con los compromisos y avanzando de manera inadecuada e irregular.

    Toda tarea debe tener una fecha. Cada vez que surja una tarea, ponle una fecha, si no puedes ponerle una en ese momento, ponle una fecha para volver a revisar la tarea, pero nunca dejes nada sin que este establecido una tiempo para ser atendido.

  • No existe un objetivo claro. Esto provoca que no se sepa que es lo que hay que hacer y por lo tanto no se hada nada relevante, agregando módulos al sistema o quitándolos sin sentido alguno. Es necesario tener unos objetivos definidos, cerrados y limitados.

  • No existen unas tareas claras. Dicho de otra forma se tiene un objetivo, pero no se ha analizado claramente y no se sabe cómo llegar a él, con lo que se va dando tumbos, realizando código (u otras tareas), sin saber muy bien como llega a buen puerto. Es necesario trazar una ruta para poder conseguir nuestros objetivos, dividir el problema en pasos y recorrerlos uno a uno.

  • No hacer una tarea por estar esperando un correo o una llamada. No hagas eso, nunca van a llegar en el tiempo adecuado y el resultado es que no vas a hacer nada. Finalmente el trabajo de las personas no es responder correos, así que no estarán pendientes para contestarte o lo harán cuando acaben sus tareas, o incluso si son bien organizados tendrán un día, o una hora al específica para contestar todos los correos. Mi recomendación es que mandes un correo, y después llames por teléfono para avisar que mandaste cierta información por correo. Sobretodo que establezcas un tiempo prudencial determinado y concreto para obtener respuesta a ese correo, y que además la persona receptora sea consciente de dicho tiempo, si no se ha cumplido vuelve a llamarla. Es mucho mejor ser molesto, que no hacer tu trabajo.

  • Diferentes áreas, diferentes intereses. Este problema es muy común, dos áreas involucradas tienen responsabilidades diferentes con respecto al proyecto, esto es un problema de difícil solución y tiene que ver con que no se percibe que un sistema incompleto no le sirve a ninguna de las dos áreas (es del famoso caso de "No es el lado de mi barco el que se hunde"), es necesario aumentar la comunicación entre áreas, para llegar a un mutuo acuerdo, a veces solo es un mero problema de comunicación.


  • Plantear un problema sin la solución. Es necesario que cuando tengamos un problema, intentemos buscar una solución antes de delegárselo a otra área. Es importante presentar los problemas junto con las soluciones

  • Para cada solución tiene un problema o más. Es un caso curioso, cuando se dan soluciones a un problema, inmediatamente surgen nuevos problemas que invalidan la propuesta, de forma que al final ninguna acción es tomada, nada se hace. Hay que considerar que ninguna solución resuelve completamente un problema, pero es mejor tener una solución que haga algo a no tener nada en producción.

Ahora bien, ¿Puedes tomar decisiones desde cualquier puesto? Si, por que si realmente no tuvieras que tomar decisiones en tu puesto, sería más fácil reemplazarte con algún tipo de proceso automatizado, si no es el caso, es que tus decisiones afectan a tu trabajo y a la forma de desarrollarse de este, y puedes influir en el éxito del proyecto.

sábado, 23 de diciembre de 2017

Acerca del uso de las metodologías de desarrollo en la empresa

Hace unos días un lector del blog me hizo la siguiente pregunta:

Me he estado preguntando que metodologias del desarrollo de software utilizas? Sería interesante conocer ese tipo de detalles para los ingenieros que apenas estamos comenzando nuestra etapa profesional
Me he estado preguntando que metodologías del desarrollo de software utilizas? Sería interesante conocer ese tipo de detalles para los ingenieros que apenas estamos comenzando nuestra etapa profesional

La verdad es que de manera inadvertida, la respuesta a esa pregunta creció mucho y decidí convertirlo a una entrada del blog sobre el uso de metodologías en el empresa, para ofrecer un opinión desde un punto de vista personal a la vez que profesional. En los siguientes párrafos esta mi respuesta.

Es una pregunta muy interesante la que planteas. Aquí hay un tema importante; no siempre vas a poder usar la metodología que quieras o incluso la adecuada para el tipo de problema planteado, porque a veces viene establecida por la empresa encargada del desarrollo directamente.

Cuando comencé a trabajar formalmente dentro de equipos de desarrollo de software, teníamos que usar metodologías tradicionales y pesadas, en las que pasábamos por cada fase en estricta secuencia y había que documentar cada paso (c-a-d-a p-a-s-o). Las metodologías agiles estaban todavía muy verdes (en implantación) y no ofrecían confiabilidad con respecto a la forma de desarrollar software que llevaban vigente durante décadas.

En lo personal a mi no me gustaba mucho esa forma de trabajo, era algo bastante frustrante, que enaltecía el análisis y el diseño frente a la codificación, a la que prácticamente nulificaba en cuanto a importancia.

He de decir que no creo que ningún problema pueda ser comprendido en su totalidad hasta que no está resuelto y eso quedaba patente en el desarrollo de software, cuando muchos elementos deben volver al análisis (una y otra vez), porque su conclusión es insatisfactoria. Aquí comienzan los problemas, porque siempre hay una fecha de entrega, y muchas veces no definida por el tamaño y complejidad del sistema, sino por cuestiones de mercado y contractuales. En este punto lo más frecuente es que se empiecen a saltar partes del proceso para llegar cuanto antes a la finalizaciones. Pero saltarse partes de la metodología de desarrollo, sea la que fuera, solo lleva el desastre.

Recuerdo como anécdota ir a una serie de conferencias de PMI (Project Management Institute ) y pensar "Esta gente debe ser genial construyendo edificios, pero no han hecho un software en la vida". Mi comentario no es del todo objetivo y justo, incluso se pudiera decir "erróneo", pero realmente es lo que sentí en ese preciso momento.

Afortunadamente ya mediados de los 2000, se comenzaron a aceptar de forma empresarial a las metodologías agiles (aunque existan desde muchos antes).

Ahora intento usar Programación Extrema (XP) y Scrum.

  • XP nos da una pauta para poder desarrollar (programar) software con calidad y rapidez, valorando las capacidad del software frente al cambio (si un software puede cambiar fácilmente, es que está bien construido), que el seguir un plan cerrado sobre el producto.
  • Scrum abarca otras partes del proceso de manera más global, ya considerando iteraciones con diversos elementos del equipo de una forma adecuada.
En lo que posible, fomento la comunicación verbal, y disminuyo a lo mínimo necesario la documentación y la comunicación por escrito, sobre todo cuando no aportan ningún al sistema.

Aquí es importante la situación real por la que pase el equipo de trabajo. Comentaba en otro post, que cuando mas maduro y capaz de comunicarse sea el equipo (de desarrollo) más éxito tendrá una metodología ágil, mientras que si el equipo es "novato", o tiene fricciones es mejor una metodología mas pesada y documental.

No hay que confundir la falta de documentación, con el desorden y el caos. Scrum propone mecanismos muy claros sobre cómo tiene que ser la comunicación en el equipo, el seguimiento y la asignación de tareas.

Comentar que igual que he tenido éxitos, también he tenido fracasos por aplicar determinadas metodologías en momento y con equipos inadecuados (para dichas metodologías). Hay que considerar que el éxito no es que un software llegue a estar productivo (cosa que siempre suele llega a pasar, porque es raro que se deje una necesidad de negocio sin suplir), sino que se haya desarrollado en el tiempo y la calidad requerida, además de al le equipo haya quedado satisfecho con el resultado y no exhausto después de hare maratónicas sesiones de codificación.

En cualquier caso es posible que otras áreas que no tengan que ver con el desarrollo de sistemas tengan procesos más pesados y documentales, generalmente es porque su proyectos son (en cuanto tiempo) de más corto alcance, con lo que no tiene la necesidad de "agilidad" propia de un desarrollo software. En este caso puede haber "rozamiento" entre áreas, por las diferentes metodologías. En este punto hay que llegar a la forma correcta de comunicación entre una área y otra, afectando lo mismo posible la metodología de desarrollo "de puertas para adentro".

Algunos artículos relativos a este tema son:

sábado, 16 de diciembre de 2017

Regla N°14 de la Ingeniería de Software: Evita la ceguera voluntaria


La ceguera voluntaria es ignorar de forma deliberada situaciones que si bien son perjudiciales, no suponen un daño inmediato, con lo que no se hace nada para corregirlas, convirtiéndose en una posible situación catastrófica a futuro.


Ejemplo de ceguera voluntaria en la serie Silicon Valley, Capítulo 03x05.

Aunque pudiera parecer absurdo intentar ignorar o omitir posibles problemas dentro del desarrollo de software (o realmente en cualquier tipo de proyecto) es algo bastante común.

Cuando aparecen problemas en mitad de un desarrollo y no son atacados y mitigados cuando son pequeños, aumentaran de forma progresiva hasta ser de tal tamaño que afecte al tiempo, calidad o costo del proyecto.

Lo elementos que más se suelen ignorar son:

  • Retrasos en el desarrollo del software: El producto saldrá claramente después de la fecha estimada, sin embargo ninguna alerta es disparada, haciendo creer al cliente que tendrá su sistema cuando se le indico. Aparentemente nadie quiere decir la palabra "retraso" en voz alta, aunque es algo claramente palpable.

  • Problemas tecnológicos: El equipo no tiene la capacidad técnica suficiente para llevar a buen término el sistema, ya sea por una sobreestimación de sus posibilidades, o porque directamente se construyo un equipo sin la preparación necesaria.

  • Problemas de recursos: No hay algún factor tal como dinero, tecnología necesaria (teléfonos, tablet o computadores) o gente disponible.

  • Problemas de integración de equipos: Aquí simplemente el equipo (de personas), no puede trabajar juntos, ya sea porque no tiene una buena relación o porque tienen una idea del trabajo tan individualizada que no son capaces de entender el concepto de trabajo en equipo.


Hay que entender que la ceguera temporal es algo que se da en todos los niveles, el programador puede omitir datos críticos, pero un buen líder de proyecto debe detectar omisiones y faltas al plan de desarrollo y buscar la forma de mitigarlos y sobretodo que emerjan a la luz, y estén claros, es decir asegurarse que hayan sido comprendidos (al nivel jerárquico que corresponda). Un líder de proyecto que ignora lo que ocurre en su equipo y en la construcción de un sistema, es un mal líder de proyecto y posiblemente un irresponsable que echarla la culpa del fracaso de "su" sistema a otras personas.