Mostrando las entradas con la etiqueta requerimientos. Mostrar todas las entradas
Mostrando las entradas con la etiqueta requerimientos. Mostrar todas las entradas

martes, 14 de abril de 2015

Todo lo demás.

Todavía le falta algo (dos “cositas”, en realidad) para llegar al “MVP corregido” (el “minimum viable product” redefinido después de haber subido lo que yo creía que era el minimum). Nadie me hizo llegar nada al respecto. El uso es la intersección entre la promoción y la necesidad, y uno sólo puede controlar el primer término. Sin necesidad, la gente juega un poco y listo. Si gusta se agenda el link para después. Está muy bien, pero no es “uso”.

¿Qué hubo entre esos dos MVP’s, además de esas “dos cosas”? ¿En qué cosas ni siquiera había pensado?

Le pongo Analytics y listo.

… no. Analytics está muy bien tal cual sale de la caja, pero se queda muy corto. Permite ver el impacto de un post, de facebook, de tweeter, del mail, pero nada más. ¿Y el uso? ¿Se usa el upload de esquemas? ¿El login con google? ¿El preview de datos? ¿La ayuda?

El event tracking no es difícil de implementar. Lo difícil es determinar qué trackear (qué acciones) cuando uno ya tiene todo desarrollado. Lo que no se trackea no se ve. Trackear un par de eventos y dejar por error dos o tres afuera implica tener una visión muy sesgada del uso. Si lo hubiese pensado desde el principio, agregándolo a medida que se desarrolla la funcionalidad, afinándolo desde el momento 0…

No, no es “demasiado para un MVP”. Saber hacia dónde dirigir el segundo paso es tan importante como dar el primero. Pero hay un argumento determinante por el cual no se puede dejar para después: recolectar un volumen de datos relevante lleva –con suerte- semanas.

Try-catch-mail alcanza, y por las dudas logueo todo.

Me mando un mail con la excepción y ya está bien para empezar, con eso ya sé dónde buscar en el log. No, tampoco. Cortísimo.

Ok, hubo un error. ¿Quién? ¿Haciendo qué? ¿Qué datos de entrada? ¿Qué valores de salida? Los errores que pueden corregirse mirando un stack trace se agotan rápidamente. Después… las cosas se vuelven más complicadas. El “log viewer” de la consola de GAE es por lo menos “rústico”. Excederse por más y generar 1Gb de log por día está bien cuando podemos comprimir, descargar el archivo y procesarlo tranquilamente, pero no es el caso. Una posibilidad es recolectar parámetros de entrada y valores de salida de todas las funciones pero loguearlos sólo cuando hay un error. O afinar el log para cada operación, o guardar los errores aparte, en la base… Lo que sea, pero no es tan simple como un try-catch-all.

Cada error es un usuario–casi-perdido, y usuarios no sobran.

Malditos celulares.

¿Para qué miércoles quiero dar soporte a celulares en un data generation tool? Si, que se pueda ver… pero no importa si no es usable, no es una aplicación que tenga sentido en un smartphone. Y en la primera versión ni eso, que se vea como se ve. Total foundation ya ayuda bastante sin que hagamos nada.

Error. La aplicación no se usa en un smartphone… pero el 50% (50% medido, no es un decir) de los usuarios entra por primera vez desde uno. ¿Por qué? Y… si promociono por twitter y facebook… ¿qué esperaba? No esperaba nada - señal de que estoy viejo.

No tiene que ser usable, pero es indispensable que sea “probable”, “jugable” o al menos “agendable”. Como mínimo –muy mínimo- que puedan decir “ok, avisáme después.

Lo ideal sería que se pueda jugar un poco, abrir una cuenta y grabar. Bueno… más trabajo (y esto no está incluido en “las dos cosas”).

Consola de administración.

Paráaaaa… ¿un backoffice para un data generation tool? Si.

Estoy usando objectify. Muy lindo, muy rápido el desarrollo de todo, pero… el acceso a datos desde la consola es incluso más rústico que el log. Lo que objectify graba ya es bastante difícil de leer… Si un error “rompe” la cuenta de un usuario (se graba algo y luego le da error cada vez que entra) estamos al horno: corregir esa especie de “assembler de datos” es demasiado peligroso o directamente imposible (ni lo intenté).

Guste o no hay que hacer una página de administración donde podamos ver la data en forma prolija y modificarla si es necesario. Y no podemos empezar a hacerla sobre el hecho de que ya hay alguien que no puede entrar a su cuenta. Y también va a tener sus errores.

Y todo lo demás.

Y, finalmente, las “dos cosas” de las que hablaba al principio. Esas son las únicas dos funcionalidades propias de la aplicación de toda esta lista. Pero no voy a decir cuáles son. Talvez ni hagan falta.

Una buena

Son cosas simples (aunque no “tan simples”) si se las tiene en cuenta desde el principio. Bueno, para esto era, ¿no?

martes, 23 de junio de 2009

Paradigmas.

Los desarrolladores somos –¿hipótesis?- ante todo humanos, luego usuarios, luego desarrolladores.

Como humanos –entre otras cosas-, tendemos a sobrevalorar la propia experiencia. Por ejemplo, si el sistema que desarrollamos nos es fácil de utilizar solemos atribuirle esta característica obviando el hecho de que hemos aprendido a utilizarlo “desde atrás” (es decir, desde el código, el diseño o los requerimientos) y no “desde adelante” (desde la pantalla, los manuales o la capacitación). Para cuando nos enfrentamos a la pantalla de inicio ya sabemos casi de memoria todo lo que sigue. Abstraerse de este conocimiento es –por más que me juren y recontrajuren- imposible, y es por eso que nuestras pruebas y experiencias personales son bastante objetables como medida de lo que sucederá en el mundo real. Esto se aplica, con variaciones, tanto a desarrolladores como a analistas, testers, líderes de proyecto y a cualquiera implicado en el desarrollo de software (excepto, claro está, al cliente y al usuario).

Además de humanos –si es que damos por válida la hipótesis-, somos usuarios de sistemas de un determinado negocio: entornos de desarrollo, clientes de bases de datos, herramientas de diseño y documentación de requisitos, entre muchos otros, conforman el software de soporte al negocio del desarrollo de software. Negocio en el que estamos inmersos y que, como todos, tiene su paradigma establecido y materializado en la forma de determinados estándares: flujos de trabajo, herramientas visuales, disposición física de los objetos en una oficina… todo lo que nos rodea se deriva de éste en alguna medida.

La importancia de estos elementos –paradigma y estándares- que sobre el papel parecen un conjunto arbitrario de caprichos funcionales -¿por qué Ctrl+U y Ctrl+Shift+U? ¿Por qué un árbol y no una serie de listas encadenadas?- radica en que condicionan toda nuestra visión de la realidad (¡vaya si estamos condicionados por los paradigmas de nuestro negocio!). Los sistemas -si pretenden ser exitosos- deberán respetar –o revolucionar, pero esto es más difícil-, sobre todo en la interacción con sus usuarios, los paradigmas del negocio para el que fueron diseñados.

Como desarrolladores que somos –de eso sí estamos seguros- nos sería imposible, si estuviésemos librados a nuestro criterio, no aplicar el paradigma y los estándares propios del negocio al que pertenecemos –el desarrollo de software- a los sistemas que desarrollamos.

El problema es que, como establecimos más arriba, otros negocios o actividades tienen estándares y paradigmas diferentes. Internalizarlos es prácticamente imposible (deberíamos ser, por ejemplo, tan usuarios de distintos sistemas de gestión como lo somos de distintos entornos de desarrollo, tanto como lo es un empleado administrativo que ha transitado por diferentes empresas y puestos). Sólo podemos pretender, a lo más, conocerlos. Y para ello se requiere de una experiencia… “presencial”. Es la experiencia que trata de transmitir el analista funcional, el área comercial o quienquiera que tenga contacto directo con el cliente.

Pero un modelo mental es algo realmente difícil de describir, los estándares que se deriven de éste serán en su gran mayoría reglas y prácticas comunes y no estarán explicitadas en ningún lado. Es, en definitiva, difícil de transmitir. Por todo esto, cuantos más intermediarios haya entre aquellos que conocen a los clientes y usuarios y los desarrolladores, más probabilidades habrá de que nos apartemos del paradigma y los estándares a los que ellos están acostumbrados.

sábado, 7 de marzo de 2009

Cuando se cumple con los requisitos y no sobra nada.

Examen de literatura

Ejercicio: Realice una composición literaria que incluya los siguientes tópicos:

  • Sexo
  • Monarquía
  • Religión
  • Misterio

Respuesta: Se follaron a la reina, ¡y el rey no estaba! Por Dios, ¿quién habrá sido?

Otro gran aporte de @Cerebrado, y vaya uno a saber de dónde lo sacó.

martes, 3 de marzo de 2009

Metáforas: la deuda técnica (technical debt).

Paying Down Your Technical Debt, de Coding Horror, trae a cuento esta metáfora pergeñada por Ward Cunningham.

La deuda técnica es, muy básicamente, aquella en la que se incurre cuando se desarrolla funcionalidad rápidamente posponiendo cuestiones menos urgentes tales como legibilidad, escalabilidad, simplicidad, etcétera. La implementación “sucia y rápida” es el capital de esta deuda que, como toda deuda, genera intereses que el equipo va pagando en forma de aumento de costos de mantenimiento y dificultades al desarrollar nuevas funcionalidades. La única forma de quitarse el peso de ese interés es pagando el capital, o sea refactorizar la funcionalidad.

Martin Fowler la desarrolla muy bien en su blog en la entrada TechnicalDebt (en inglés, por supuesto). Para los que prefieran leer en castellano, el blog “Qué quieres desarrollar hoy?” ha publicado un post reciente al respecto.

A leer, que se acaba el mundo.

miércoles, 11 de febrero de 2009

Sobre requerimientos, comunicación y honestidad cuando las papas queman.

Dark-Evil-41164

En Por dónde comenzar, hablando de gestión de requerimientos, Improbable ha dado a luz un párrafo genial que le da de lleno a mi falta de paciencia para con el área de análisis funcional (por lo menos con la que me toca convivir). Dice:

[…] recuerdo los valores ágiles de responsabilidad, honestidad, y demás virtudes. Pero ocurre que la gente es gente, y cuando las papas queman y alguien pregunta por determinados retrabajos o por qué se ha invertido seiscientas horas de desarrollo en algo que debería haber tardado doscientas, no es descabellado esperar que quien nos ha guiado a través de un camino sinuoso intente endilgarle la responsabilidad a otro. Quiero decir: que un Product Owner que nos ha hecho trabajar y retrabajar haciendo una cosa y luego la contraria continuamente intente explicar el poco valor conseguido luego de un tiempo considerable hablando de la falta de habilidades técnicas de los programadores.

#define evil_mode=1;

Pocas cosas son más molestas que cuando, sin haber cometido ninguna falta –condición más que fundamental para lo que sigue-, la gente se preocupa más por cubrirse que por hacer el trabajo, con actitudes como cambios que no se pasan por escrito, horas que se distribuyen entre otras tareas para ocultar retrabajos, olvidos sugerentes y demás.

Y es porque me da la sensación de que esto genera espejismos hacia la gestión del proyecto, que a falta –razonable y esperable- de conocimientos técnicos se guía por la percepción del desarrollo que nosotros exponemos, acumulada en forma de experiencia. Espejismos que luego nos juegan en contra.

Así, si nos “da vergüenza” pasar una semana con una funcionalidad que parece trivial y para la que estimamos dos horas, y en vez de poner el esfuerzo en explicar lo sucedido distribuimos esas horas en otras tareas, estamos fortaleciendo la imagen, por ejemplo, de que somos buenos estimando y de que lo que parece fácil es fácil. Estamos fijando un piso que difícilmente podamos mantener.

Pero una cosa es “distribuir horas” y otra es tirar la basura al patio del vecino (como describe el párrafo citado), siendo más conveniente (aunque harto más difícil) explicar a la gestión que los requerimientos no eran claros y que por presiones de tiempo se comenzó a programar lo antes posible, por lo que buena parte del tiempo de desarrollo fue en realidad tiempo de aprendizaje, prueba y error, ajuste y corrección sobre la marcha… una situación que simplemente se dio así y que no tiene nada de malo per sé…

…a menos que creamos que no somos tan buenos como deberíamos en lo que hacemos.

#define evil_mode = 0;

domingo, 26 de octubre de 2008

Panqueque System III: El infierno de las preferencias.

Es difícil que un desarrollador que haya trabajado en algún sistema de gestión no se haya enfrentado con esta situación.

Circuitos administrativos hay para todos los gustos. Tenemos los clásicos compras, producción, ventas, facturación, atención al cliente, liquidación de sueldos. También tenemos algunos más infrecuentes, pero de todas maneras muy comunes: presupuestos, importación, exportación, marketing...

Todos ellos han sido descritos, caracterizados y estandarizados extensivamente por la bibliografía de la administración de empresas. Algunos de ellos, por estar atravesados por restricciones legales, son muy parecidos en todos lados.

Pero el problema de las sutilezas existe siempre. Cada empresa tiene las suyas, a veces justificadas, a veces no. Y el momento de comprar un software que gestione el circuito será el de la dura negociación para determinar quién se adapta a quién (la empresa al software o viceversa) y en qué grado.

En Panqueque System II: Un caso de dependencia del cliente apuntaba al caso en el que el cliente requiere customizaciones de tal especificidad que termina quebrando al desarrollo en dos versiones (por lo menos). El problema es casi comercial: se cobran customizaciones pero el cliente domina hábilmente la negociación y termina con un software a medida.

Este caso es sutilmente diferente. Más que de un error comercial, estamos hablando de un vicio funcional.

Los analistas funcionales, en su contacto cotidiano con diferentes clientes, son caldo de cultivo para esas pequeñas variaciones orientadas a demostrarle a cada cliente que el software se adapta perfectamente a sus necesidades.

Tomadas individualmente cada una de estas variaciones parece inofensiva, fácil de implementar y con una relación costo-beneficio ampliamente favorable. El cliente siente que el producto le calza como un guante. Cada vez que durante la demostración él apunta a cuestiones como "ah, nosotros requerimos que el gerente apruebe el pago para los mayores a..." podemos responderle "eso es configurable aquí".

Finalmente, todo termina siendo configurable allí (en esa pantalla infernal con 200 opciones que se activan y desactivan unas a otras). Que si tal funcionalidad está desactivada tal pantalla no tendría que verse, que si el módulo tal no está activo los datos tendrían que mostrarse de tal manera o de tal otra... Que los vendedores a veces pueden y a veces no pueden, que los descuentos a veces son fijos o pueden ser variables o...

Cada una de estas variaciones aporta su granito de arena para hacer de la gestión de configuración un absoluto desastre.

Lo divertido es -esto le he visto ya en varias ocasiones- cuando la combinatoria de estas opciones a veces sutilmente incompatibles unas con otras, resulta en comportamientos completamente insospechados. O cuando para activar ésta se necesita activar aquélla y para activar aquélla necesito esta otra que requiere la primera... una especie de abrazo mortal.

Y ni hablar de cuando se pretende incorporar nueva funcionalidad. El desarrollador que esté a cargo del nuevo módulo o pantalla puede verse involucrado en uno de dos infiernos: o se encuentra con una larga lista de opciones y variaciones pre-existentes que está comprometido a implementar, o (esto es tal vez peor), no hay documentación clara sobre alguna o ninguna de ellas o de la relaciones entre todas y se va enterando sobre la marcha o durante el testing.

En el primer caso, se genera una sobrecarga tal que la más mínima funcionalidad agregada insume un número aparentemente desproporcionado de horas. Pero por lo menos esto puede estimarse. Es un problema, y es conocido. En el segundo caso -la falta de documentación-, el desarrollador se va enterando sobre la marcha, con la sensación de ir retrocediendo a cada paso. Si había estimado 4 horas, luego fueron 8 y luego 16 y luego...

¿Soluciones? Ninguna es categórica. Cuándo incorporar una variación que surge del circuito administrativo de un cliente en particular es siempre es una relación de costo-beneficio. Los beneficios son instantáneos y los costos a mediano y largo plazo.

¿Podemos decir que no? Dependerá de qué tan importante sea la "sutileza" para el cliente y de qué tan importante sea el cliente para la empresa. Lo que es imposible de explicar (de cara al cliente) es que de alguna manera la calidad del producto puede verse comprometida.

Desde lo técnico el nudo de la cuestión estará en crear una arquitectura en la cual se puedan establecer cambios de comportamiento en forma global, de manera tal que el programador no tenga que estar al tanto de estas variaciones al momento de codificar. Esto no siempre es posible, y si lo es, lo será sólo en cierta medida.

Y desde lo metodológico, la simplificación: no sólo implica hacer más simple el código existente, sino retirar lo que no es frecuentemente utilizado. Este punto es al que se le suele restar importancia. Un producto con algunos años y versiones sobre sus espaldas puede estar cargando con un sinfín de posibilidades que ya nadie utiliza.

De cualquier manera, lo importante no es evitar el infierno de preferencias, dado que éste infierno, si está controlado, puede ser el que incline la balanza hacia nuestro favor al momento de ganar clientes. Lo importante es que la parte comercial y funcional del proyecto o la empresa sea consciente de la forma en la que sus decisiones afectan al producto.

Varias veces el equipo de desarrollo se encuentra con que se han aprobado customizaciones u opciones sin ningún tipo de consulta previa. No es una cuestión de "querer estar en todo", pero... ¿Si no se ha consultado al área técnica, sobre qué bases se ha decidido que lo que se cobra o ingresa por la customización es mayor al costo actual y futuro de la misma?

Los artículos de la serie:

Panqueque System.

Panqueque System II: Un caso de dependencia del cliente.

jueves, 25 de septiembre de 2008

Panqueque System II: Un caso de dependencia del cliente.

En Panqueque System hacía referencia a esos sistemas en los que el rumbo cambia 180º de vez en cuando, en una forma tal que por más ágil que uno quiera ser, termina embrollando el desarrollo.

Se me habían ocurrido dos causales: problemas en las definiciones y dependencia del cliente. Había empezado por desarrollar un poco el primero. Vamos al segundo.

Trabajé casi siempre en empresas chicas, a lo sumo medianas. Así que conozco de primera mano la importancia de el cliente, sobre todo cuando se lo puede nombrar en singular y ya se sabe de quién estamos hablando.

En el caso que tengo en mente, la aparición de un comensal importante, de buen apetito y bolsillo aparentemente generoso motivó la aceleración del cierre de un producto de evaluación de desempeño que si bien teníamos prácticamente terminado todavía no había sido utilizado en una evaluación real.

La idea original era atraerlo con un buen precio por evaluación más algún sablazo por customizaciones que, bien implementadas, serían nuevos sabores a ofrecer en nuestra recién abierta panquequería, que tenía forma de aplicación web.

Creo que el modelo de negocio, tan natural en estos tiempos que corren, era demasiado innovador para el momento del rubro (no es autobombo, yo sólo picaba código), y el cliente demasiado grande.

Esos dos factores se juntaron para que se negociaran cambios de tal magnitud y especificidad que en la práctica hicieron imposible su aplicación como opciones a ofrecer al público en general.

De un lado del escritorio no existía la mentalidad de utilizar una aplicación web como un "servicio enlatado", por lo que se terminó pidiendo cualquier cosa.

Del otro lado la dependencia económica era tal que se terminó concediendo cualquier cosa, y el desarrollo tuvo que abrirse en dos versiones divergentes, una dedicada exclusivamente a éste cliente y otra estándar que permanecía en vidriera.

Así, se vendió el desarrollo de un programa a medida al precio de un par de customizaciones. Y como era una aplicación web, el cliente comió una vez, dos tal vez, y satisfecho su apetito continuó por su camino libre de ataduras, sin nunca más volver.

Creo -ya aclaré que estoy alejado del rubro- que no se logró posicionar la versión estándar como un servicio web a utilizar "como está" y que actualmente se encuentra más o menos abandonada.

Esta anécdota ejemplifica bien la situación en la que el panqueque gira y gira en el aire hasta romperse en dos mitades. En este caso un comensal un poco grosero picoteó apenas de una de ellas, encima pagando sólo el proporcional, y el cocinero se quedó con las sobras. Sobras que pueden servir de tener a quién ofrecérselas a tiempo, pero no fue éste el caso, me parece.

Mi opinión es que la clave está en la metodología. Si el proyecto crea una base de componentes o una capa de negocio reutilizable que soporte los cambios de tecnología, conformarán en realidad no una pérdida en horas de trabajo sino una inversión.

Ésa salida sólo puede darse si es apoyada conscientemente por el entorno de negocio del desarrollo. Si se presiona a los programadores a cumplir con los requerimientos en tiempos extremadamente ajustados (en este caso, forzando un nuevo desarrollo en tiempos de "customización"), el código resultante tendrá una calidad acorde, y no será para nada reutilizable.

¿Es compatible la entrega en esos tiempos con calidad y posibilidad de reutilización? Las metodologías ágiles nos han enseñado que es posible entregar rápido y refactorizar después. Podemos hacer una implementación desprolija (aunque correcta para el usuario, eso es indispensable) si luego tenemos tiempo de capitalizar la experiencia reorganizando y reescribiendo el código donde sea necesario. Pero muchas veces gana la idea cortoplacista de producto terminado y a otra cosa... una panquequeada más que termina con lo poco que quedaba en el suelo. Otra variación conocida de esa frase es esperemos a que surja un nuevo negocio... por supuesto, y a que los tiempos se ajusten nuevamente.

Queda para otro post una situación más, el infierno de las preferencias. Es el caso en el que para cada nuevo cliente creamos un nuevo gusto y terminamos estancados en el mencionado infierno con más sabores que comensales. Pero como dije, será para otro día.

Actualización: Ya llegó el día: Panqueque System III: El infierno de las preferencias.

jueves, 18 de septiembre de 2008

Otro disparo a la productividad del Jueves.

Yo no me metería con esto si tuviese algo importante que hacer:

Magic Tiles Adventure.

Si tienen la suerte de que en un principio les parezca aburrido no le den una segunda oportunidad.

Vía Cerebrado (ojo, al mediodía, ¡eh!).

jueves, 11 de septiembre de 2008

Panqueque System

Ésta caracterización la escuché hoy en la oficina y me quedó dando vueltas en la cabeza. Hablando de los causales del no muy lento ocaso de cierto producto ERP, se mencionó el hecho de que el sistema "se panquequeaba cada dos por tres". Es decir que los requerimientos, el diseño o las funcionalidades incluidas cambiaban abruptamente ("se daban vuelta") en forma continua, de forma tal que se reescribían casi completamente.

Si bien el cambio y la evolución son elementos comunes y deseables en el desarrollo de un sistema, se supone también cierta racionalidad. Se agrega o quita funcionalidad a partir de un núcleo conceptual que se mantiene en el tiempo o que cambia muy gradualmente.

Persiguiendo la idea, se me presentaron dos orígenes para un Panqueque System, que probablemente puedan luego sub-clasificarse: problemas en las definiciones y dependencia del cliente.

Lo que tienen en común ambos orígenes, que es en definitiva lo que define al panqueque, es el lugar en donde se encuentra la indefinición. Para que un sistema de vueltas en el aire sobre el fuego, ésta debe estar ubicada en el punto de apoyo de todo sistema: la definición del negocio. No en un sentido funcional ("cómo se ordenan los elementos en la pantalla X"), sino aquélla que nos define tiempos, alcances y restricciones generales del proyecto ("hemos vendido un sistema de XXX, que abarca el circuito desde A hasta B. Debemos dar muestras de avance cada TTT meses...").

La definición de negocio es ante todo una apuesta estratégica, la adopción de un riesgo, la declaración de una visión de muy general alcance. Es el terreno de la intuición, de la política, del regateo y la conquista del cliente.

El origen "problemas en las definiciones" implica graves fallos en la definición del negocio: o no hay seguridad sobre a qué negocio apuntamos, o el negocio es demasiado innovador o no hay suficiente conocimiento en el equipo acerca de él, etcétera.

Es esperable que si el proyecto sobrevive a un fuerte bamboleo inicial las definiciones se vayan asentando con el correr del tiempo, a fuerza de prueba y error. Como reza el adagio, "en la marcha se acomodan los melones".

Desarrollar en un ambiente así requiere de muchísima habilidad, prolijidad, de una arquitectura extremadamente resistente a los cambios y un fuerte énfasis en el encapsulamiento y modularización de toda funcionalidad en el sistema, entre muchas otras cosas. Puede que se cumplan los requerimientos, pero que el código se vuelva completamente inmanejable en poco tiempo.

Así y todo, aún considerando el peor de los casos (necesidad de recodificación), no deja de ser un modelo de desarrollo viable. Si la idea resultante realmente tiene éxito, llegará un punto en el que justifique una recodificación que materialice la experiencia obtenida.

Peor es, como en el caso del ERP que inicia este comentario, cuando existe en el seno de la empresa una lucha entre dos visiones antagónicas del negocio. No hablamos ya de discusiones dentro del equipo de desarrollo, sino de aquéllas que se dan en un nivel superior, aquél en el que se define "negocio". Puede ser una lucha interna propia (por ejemplo entre dos consultores estrella de la empresa) o proveniente del propio cliente (por ejemplo entre los dos socios que conforman la empresa que nos contrata). Ya sea una pelea explícita o implícita, esperemos recibir palos ora de un lado, ora del otro.

El impacto dentro del equipo es la sensación de hacer y deshacer continuamente las mismas funcionalidades o de estar implementando en realidad dos sistemas completamente diferentes, separados apenas por un par de opciones de configuración. También es posible que se dé un alto nivel de esquizofrenia en el sentido de que lo que por un lado se nos requiere, por el otro sea fuertemente criticado.

Si lo pensamos detenidamente nada impide, en teoría, satisfacer ambas necesidades, reutilizando lo posible. Pero digo en teoría porque en la práctica es común que la lucha de poder entre las dos visiones genere requerimientos "de destrucción de la otra parte", que vistos a la distancia pueden hasta ser divertidos. Por ejemplo: "retirar completamente del sistema la funcionalidad XXX". Vaya un requerimiento, ¿dónde está el por qué, el relevamiento, el análisis? En estos casos las causas reales no pueden describirse fácilmente ni mucho menos escribirse. ¿Qué les parece un documento en el que se lea "esta visión del módulo de ventas es infantil e inútil y no resiste el más mínimo análisis de alguien con experiencia en el rubro"?

Y así el Panqueque System se va dorando vuelta y vuelta, un poco de un lado un poco del otro. Eventualmente estará bien cocinado (de ambos lados) o quemado de uno o ambos, lo que para el caso es lo mismo.

Resta para una segunda parte el segundo origen del Panqueque System: dependencia del cliente, que aparecerá en breve. ¿Tu proyecto es un panqueque?

Actualiazación: sigue en Panqueque System II: Un caso de dependencia del cliente.

Actualiazación II: ¡Obsesionado con los panqueques! Panqueque System III: El infierno de las preferencias.

martes, 2 de septiembre de 2008

Asteroides III

Seguimos obsesionados con los asteroides (ver Asteroides y Requerimientos: cuando no son asteroides sino sólo polvo cósmico).

Aquí un buen ejemplo de la llegada de uno de ellos a nuestro escritorio: ¿Qué pasaría si un asteroide de 500km colisionara con la Tierra? (Vía ALT1040).

jueves, 28 de agosto de 2008

Requerimientos: cuando no son asteroides sino sólo polvo cósmico.

Nota: esta entrada es una contribución de Cerebrado relacionado con la entrada Asteroides, que les recomiendo leer primero.

Hay veces en las que el requerimiento es la implementación de una solución.

¿Cómo? Analicemos.

Sí, hay veces en las que lo que se requiere es que se implemente una solución. Se entiende por solución una forma determinada, específica, de resolver de un problema. ¿Cómo? ¿No es así siempre? No, no debería ser así. El requerimiento debería ser el planteo de un problema. El equipo debería encontrar la solución.

Por las dudas va un ejemplo. Un requerimiento normalmente diría:

El sistema debe detectar que el saldo de una cuenta ingresa en rojo y alertar al ejecutivo de cuentas asignado al cliente.

Pero hay veces en las que dice:

Implementar un trigger sobre la instrucción insert de la tabla cuentas_movimientos. En este trigger, cuando sld_cnt - deb_pnd + crd_pnd sea menor a 0 insertar un registro en la nueva tabla notificaciones con los siguientes valores: ....

En vez de asteroides llega sólo polvo cósmico de esa nube de requerimientos de la que se hablaba en Asteroides.

Hay un intermediario que filtra, soluciona, resuelve... pero no comparte ni la información obtenida ni el método que usó para obtenerla.

En definitiva se requiere que escribas lo que otro pensó. Hasta ahí no habría mucho de qué quejarse, incluso hay gente que no es proactiva y a la que éste tipo de tareas le cae más que bien.

Uno implementa esa solución, sin saber qué resuelve. Actúa por el "cómo", y no por el "qué".

Pero luego ocurre un problema, un cambio en el requerimiento, la funcionalidad no trabaja como debería. Y ahora sí, nos llega un asteroide hecho y derecho con forma de reporte de error... ¿por qué no aparece de vuelta ese polvo cósmico con la solución detallada?

¿Y ahora qué se hace? En los restos del polvo cósmico original no hay piezas suficientemente grandes como para extraer información de cómo debería funcionar la cosa, ni de por qué funciona mal.

Entonces es cuando uno hace dotes de adivino, prueba y falla, busca al intermediario para sacudirle los bolsillos hasta que caiga al menos alguna piedrita... si lo encuentra (suelen tener la habilidad de aparecer y desaparecer a voluntad y escasa voluntad para ajustar sus propias soluciones). Así hasta que el intermediario queda satisfecho con lo que hemos hecho.

Puede tomar mucho tiempo, mucho esfuerzo, y el resultado puede no ser el óptimo.

¿Cuales son los resultados posibles?

  • Puede que hayamos entendido qué hicimos. Sería el mejor de los casos.
  • Puede que hayamos creído entender lo que hicimos.
  • Puede que no hayamos entendido un catzo.

Para cada una de las anteriores, puede que no nos importe... o que sí. La cosa anda, pero si vuelve a ocurrir algo en la nube (y con seguridad va a ocurrir) volveremos a recorrer el mismo penoso camino.

¿La falla es del intermediario, por no saber transmitir? ¿Por no confiar (con o sin razón) en el poder analítico de su subalterno? ¿Es nuestra, por conformarnos (y acostumbrarnos) a la información reticente? ¿Por no exigir / pedir más definiciones?

La falla es un composé de muchos puntos:

  • Comunicacional. El intermediario no sabe / puede / quiere comunicar.
  • De rango: porque cree que dar la menos información es tener más control.
  • De confianza: porque no confía en su gente.
  • De experticia: porque no sabe trabajar en equipo.
  • De incumbencia: porque el intermediario resuelve a ese nivel de granularidad aunque sus funciones no lo especifiquen.
  • De usos y costumbres: porque se han resuelto demasiados problemas de esta manera como para poder plantear la posibilidad de que haya algo malo en el método.

Ahora, la pregunta es... ¿queremos un asteroide o sólo polvo cósmico?

domingo, 24 de agosto de 2008

Asteroides

La Nube de Oort es una nube de cometas que se cree se encuentra en el límite del Sistema Solar, a una distancia aproximada de 100.000 UA ó 1 1/2 años luz del Sol. Se ha calculado estadísticamente que puede haber entre uno y cien billones (1012 – 1014) de cometas. [...] El efecto gravitatorio de las estrellas próximas desvía a los cometas de sus órbitas y los envía hacia el Sol, donde se vuelven visibles.

Wikipedia - Nube de Oort

Todo ambiente de desarrollo está rodeado de una nube de requerimientos suspendidos en delicado balance en los límites del negocio. Algunos son conocidos, la mayoría no. De vez en cuando alguno de ellos cae y debe ser manejado de alguna manera. Léase esquivado o absorbido por uno o varios integrantes del equipo. De tiempo en tiempo una gran perturbación en esta nube, una explosión o el paso de alguna mala estrella puede provocar una verdadera lluvia de estos objetos.

Tal ha sido el caso de la semana pasada. En principio apareció un cometa de polémicas dimensiones. Desde el punto de vista del líder de proyecto, apenas una simpática piedrita que aparecía para decorar el firmamento por un par de horas. Desde el punto de vista del líder técnico y de uno de los integrantes de más experiencia, un asteroide amenazador que avanzaba en picada siguiendo un peligroso rumbo de colisión hacia lo más delicado de un sistema ya bastante golpeado.

Como muchas veces sucede, nos fuimos enterando de las verdaderas dimensiones y características del objeto cuanto más cerca estaba de nuestras cabezas. Resultó ser de esos que luego del primer impacto esparcen peligrosas esquirlas por todos lados.

Yo observaba la escena desde una distancia prudencial. Tenía algunos pequeños asteroides propios que destruir y me entretenía en ello, levantando de vez en cuando la mirada para ver pasar alguna de estas piedras convertida en estrella fugaz. Lindo despliegue.

Así, distraído con el espectáculo principal, no noté el acercamiento de un pequeño asteroide que se aproximaba dando tumbos, rebotando de aquí para allá, sin decidirse a adoptar un rumbo fijo.

La primera vez que lo ví ya había impactado en mi escritorio, dejando un pequeño cráter rodeado de una nube de polvo. Era un reporte.

Hacer reportes tiene sus bemoles. Uno de vez en cuando es divertido. Hay que investigar el negocio para ver cómo se consiguen los datos. Esta parte me gusta, aparecen complicadas relaciones entre un sinfín de tablas y cálculos extraños que hay que resolver con algo de ingenio. Luego, a jugar con SQL. Y aquí se acaba la gracia. Porque una vez que uno tiene la consulta la cosa está cocinada, no hay mucho más que pensar pero... no alcanza con ello. Hay que hacer el reporte.

Y aquí empieza: que dos cuadros separados por algún criterio que no es el más cómodo para obtener los datos, luego que no me entran los datos en la página, luego alinear un sinfín de columnas, luego que la columna "cantidad" me aparece con decimales... y cuando ya tenemos una miríada de detalles menores resueltos... "no, mejor esta columna la pasamos acá" y de vuelta a alinear y reacomodar. La herramienta que manejamos (Crystal Reports, por una situación de muchos "legacy reports"), si bien es completa, de vez en cuando se tara de mala manera (usualmente con un detalle nimio pero que "no puede quedar así") y nos roba un buen par de horas fuera de agenda.

Viendo entonces que el objeto era un reporte, soplé un poco para apartar la nube de polvo y ver la definición... me encontré con un par de instrucciones SQL. Mmmmmm.... ¿qué es esto? Esperaba más bien un documento o una hoja garabateada que indicara el formato y algún ejemplo.

La intención era clara. Estos son los datos, hay que armar el reporte. Ajá. Me acordé de División de tareas, donde citaba proféticamente:

Vos vení con problemas y yo te doy soluciones. Si me venís con soluciones, te voy a dar problemas.

Dicho y hecho. Me había caído no un requerimiento sino una solución. Y como toda solución, tenía sus problemas.

En principio no abarcaba el formato del reporte. Este dato vino en la forma de otro asteroide proveniente de un sector diferente de la nube que no guardaba relación aparente con el primero. Así que había que ajustarlos, ya que no encajaban.

Para seguir se volvió claro, luego de un par de minutos de trabajo, que tenía ante mí un boceto de alguna intención que yo podía más o menos entrever intuitivamente. Pero tenia algunas contradicciones respecto de algunas partes del negocio que yo conocía. Esto también había que resolverlo.

A esta altura del partido he aprendido a reclamarle peras al olmo constantemente (casi por deporte), pero sin quedarme sentado a esperarlas. Es divertido ver todo lo que se puede avanzar a ciegas. Hice bastante (a mi entender) sin saber demasiado bien qué era lo que estaba haciendo. Un poco de olfato, un poco de oficio, bastante de saber a quién preguntar dónde buscar. Trabajo detectivesco.

Pero por más garra que uno le ponga, en algún momento iba a ser necesario entender hacia dónde me dirigía. Tres o cuatro días después de empezar, ya un poco cansado, logré entender qué estaba haciendo. Es decir, logré que me explicaran, de-una-forma-en-la-que-yo-pueda-entender (sí, soy un poco lento) el objetivo del negocio, el concepto detrás de esos datos.

Sólo para darme cuenta de que a la luz de este objetivo se percibían dos o tres "pequeños detalles menores" a corregir (irónico, por si no lo notaron), que al fin y al cabo el requerimiento no era tan complicado de expresar y que si lo hubiese tenido desde el principio no me hubiese costado tanto.

En resumen, intenté ir desde un boceto de solución hasta el requerimiento original, por supuesto que no lo logré, finalmente me lo explicaron y con ello corregí lo que había hecho hasta llegar a una nueva solución. Que no creo que esté del todo bien, pero por lo menos ahora es contrastable con respecto a ese objetivo y por lo tanto corregible.

Por ahora los dejo masticando la anécdota de la que creo que pueden derivarse varias cuestiones teóricas... va para otro post. Habría que redondear un poco más lo siguiente: hay un montón de blogs de desarrolladores contando anécdotas quejosas más o menos parecidas, con mayor o menor gracia. Por otro lado tengo un buen par de blogs donde se discuten las famosas "cuestiones teóricas"... rara vez se cruzan estos dos enfoques.

Actualización: La historia continúa en Requerimientos: cuando no son asteroides sino sólo polvo cósmico.

viernes, 23 de mayo de 2008

Puertas que se abren

Todo lo que un sistema hace debería estar justificado por un requerimiento del cliente. Lo que falte será un incumplimiento, y lo que sobre horas de trabajo perdido. Por lo menos así reza la teoría.

En muchos casos el equipo de desarrollo no tiene contacto directo con el cliente final, sino con un analista funcional, o un líder de proyecto que conoce el negocio, o alguien que cumple una función por el estilo. En este caso el cliente, desde el punto de vista del equipo, será esa persona.

Siguiendo con la teoría, el cliente presenta un requerimiento, el equipo lo evalúa, lo presupuesta en horas y el cliente decide. La negociación económica -cuando corresponde- debe enfocarse en el precio de la hora, no en la cantidad. Pensémoslo de esta manera: si quiero pintar mi casa, necesito tantos litros de pintura y puedo buscar el mejor precio, pero no comprar menos, y no tiene sentido discutir este punto. Pero el software no es pintar una casa, y hay sutilezas. Hay muchas, muchísimas variables internas del proveedor de software que hacen que uno tarde significativamente más o menos que otro en hacer prácticamente lo mismo. De todas maneras, el punto importante aquí es que es el equipo el que determina cuántas horas requiere para el proyecto. Sé de equipos en los que la parte funcional no entiende esto y es motivo de discusión. Porque -si han evaluado honestamente- no hay forma de que el requerimiento se cumpla en menos tiempo, así tengan una pistola en la cabeza. Tengo que reconocer que por suerte no he sufrido esto en carne propia.

Concentrémonos en el tema de las variables internas, pensando en un sistema informático que soporta un sistema administrativo (sistemas de venta, de facturación, de marketing, etc.). Más específicamente, en la interfaz con el usuario (IU). En este tipo de sistemas, la IU es por lejos el subsistema más complicado. ¿Por qué? Porque hace de interfaz entre dos lógicas completamente diferentes. Una cuestión es una interfaz entre dos sistemas, en donde las cosas están bien definidas en un momento dado, de mejor o peor manera. Con las personas -los usuarios- es imposible. Lo que una persona ve con claridad, a otra le parece incomprensible. Uno quiere trabajar así, otro quiere trabajar asá, y el área funcional quiere satisfacerlos a todos -con razón, ya que ellos son los que pagan-. Tratamos de promediar, de establecer métodos, estándares, pero el problema con los promedios es que no representan a nadie, y cada cliente viene con sus pequeñas variaciones. Si tenemos un sistema que vendemos a varios clientes, esas "pequeñas variaciones" acumuladas generan el clásico infierno de las pantallas de "opciones" o "configuración general" con miles de variantes, que son típicas en este tipo de software.

Así que es en la IU donde como desarrolladores tenemos que esforzarnos en buscar los puntos realmente importantes para concentrarnos en ellos. Es decir, aquel subconjunto de pantallas más utilizadas y poner todos los "chiches" ahí, y dejar el resto del sistema en la forma más simple posible que sea funcional al usuario.

Hay que tener en cuenta que, por suerte, es en la IU donde el proveedor tiene más poder de decisión. En general el cliente tomará la primera propuesta y pedirá modificaciones siguiendo la línea que se le presenta. Es raro que un usuario venga con un boceto de una pantalla, más bien tiene una idea de la funcionalidad que quiere agrupar en cada una, pero no más que eso. El resto lo tomará de lo que nosotros le presentemos.

La típica frase gira alrededor de "¿no se podría poner en la pantalla de facturación un ayudante como el que está en la de presupuesto?". Así que más vale que el "ayudante" que pusimos en la pantalla de presupuesto no haya sido el producto de un rato de ocio o el exceso de creatividad de algún programador, porque ahora se ha convertido en un estándar para el usuario, que probablemente termine queriéndolo en todos lados.

Y ahora viene el párrafo donde aparece el título: "No abras esa puerta" (la frase no es mía, si el autor quiere crédito no tiene más que mandarme un mail, él sabe quién es). Es decir, ojo con ofrecer espontáneamente funcionalidad en la UI que luego nos cueste mantener o replicar, o que genere demasiada complejidad, o que incluso se aparte demasiado del estilo del resto del sistema.

Un ejemplo. Empecé a jugar con la técnica que mucho después terminaría siendo "Ajax" en una pantalla bastante simple de ingreso de CV a una base de datos. Lo típico en ese momento era una tablita al estilo:

TítuloEstablecimientoAño de ingreso Año de egreso

(bueno, con más estilo, pero la idea se entiende)

Así que hice una grilla que editaba por "Ajax" (no tenía ninguna utilidad que lo hiciera, era puro javascript a mano) un objeto guardado en sesión, del lado del servidor. Transformé la tabla en un ABM clásico, con ventanas pop-up que editaban los datos de cada fila. Claro, estaba jugando, experimentando. No había encapsulado nada, y no era nada prolijo por adentro. Incluso habían graves cuestiones no resueltas (recuerdo por ejemplo que las llamadas al servidor eran asincrónicas, sólo porque no sabía que se podía hacer sincrónico).

Había varias listas parecidas en la pantalla: "Idiomas", "Experiencia"... y claro, no se podía hacer unas de una manera y otras de otra. Copié y pegué hasta reproducirlo en todas las listas. ¿En qué terminó todo esto? En una pantalla lenta, pesada y tosca, con problemas de redibujado en el Internet Explorer, que ni siquiera se mostraba decentemente en otros navegadores y que cumplía la misma funcionalidad que la anterior, pero que obligaba al usuario a utilizar intensivamente el mouse... un asco. Y yo tratando de explicar que no, que había sido un experimento, que ahora ya está en esa pantalla pero que no tiene por qué extenderse a todas las demás, que eso del redibujado era grave, que no tengo tiempo para hacer todo prolijo de vuelta, que emprolijarlo a partir de lo que está es casi imposible, etc., etc... es decir, terminé tratando desesperadamente de cerrar esa maldita puerta.

Años después, trabajando en base a un framework en javascript estilo Ajax, con ventanas, llamadas sincrónicas al servidor, y un montón de temas ya resueltos y con el Internet Explorer 7, la cuestión se volvió moneda corriente. Por supuesto gran parte del framework fue desarrollado y mejorado prolijamente a lo largo de **mucho tiempo** por el que ahora es algo así como el "Team Leader" en donde trabajo (repito lo de los créditos).

Resumen. Las puertas pueden y deben abrirse... a su debido tiempo, o nunca.

lunes, 19 de mayo de 2008

Proyecto de software típico.

Me acordé de esta secuencia, y estuve un buen rato buscándola por internet. No hay mucho mas que decir.