domingo, 11 de abril de 2004

Sobre documentación y requerimientos

La primera vez que desarrolle software para un cliente de manera profesional (porque recibí dinero a cambio) fue para la construcción de un pequeño sistema administrativo junto a unos amigos. Como pasa generalmente en estos casos, el aprendizaje que obtuve de este proyecto paso más por cómo no se deben hacer las cosas que por cómo hacerlas bien.

Entre todos los problemas que nos encargamos cuidadosamente de tener a lo largo del proyecto, uno de los principales fue la falta de definición y gestión de requerimientos.

Al inicio tuvimos un par de charlas con el cliente aunque sin hablar con demasiado detalle y sin definir un alcance claro. Durante el proyecto tuvimos alguna reunión ocasional con el cliente para presentar el avance del desarrollo, aunque más que presentar el avance, en la reunión mostrábamos que era lo que habíamos hecho durante el tiempo que no nos habíamos visto. O dicho de otra manera, se trataba de responder a la pregunta del cliente: "¿Qué han estado haciendo con mi dinero?".

Como carecíamos de dotes adivinatorias, frecuentemente lo que hacíamos no era lo que el cliente esperaba y comenzaban las peleas, la típica asignación de culpas con analogías:

- ¡Esto es como hacer una casa sin ventanas!
- Pero si querés ventanas me lo tenés que decir.
- Es obvio, si en una casa va a vivir gente necesita ventanas.
- Los bunkers no tienen ventanas y son construidos para que viva gente en ellos.

Bueno, la historia conocida por todos.

Así, desde mi primer contacto con un proyecto de software (o algo parecido) comenzó a ser evidente la ineludible necesidad de conocer y gestionar los requerimientos.

Creo que la importancia de saber definir qué se debe construir antes de hacerlo es algo conocido por cualquier profesional que tenga algo de experiencia por lo que no puede existir mucho espacio para debatir en este sentido. La controversia surge cuando se comenzamos a pensar: ¿cómo lo hacemos?, ¿cómo definimos qué debemos construir?

La especificación de requerimientos es una de las actividades que, a mi entender, tiene una relación más fuerte con la documentación en la mente de las personas que se dedican al desarrollo de software. Percibo que existe una sensación que la manera de medir que tan bien se está realizando esta actividad es proporcional a la cantidad de documentación de requerimientos que se genera.

Esta bien, todos sabemos que se pueden hacer malos documentos y que se puede perder mucho tiempo inútilmente cuando no se saben escribir, pero es difícil encontrar alguien que piense que se puede llevar adelante un proyecto de desarrollo profesionalmente si no se documentan extensivamente los requerimientos.

Alistair Cockburn dice en un artículo:
"...escribimos esos documentos de especificación y diseño como si realmente pudieramos explicar completamente que queremos decir. Y no podemos. Nunca podemos aspirar especificar completamente los requerimientos o el diseño. No tenemos la menor de las posibilidades. Cuando escribimos, asumimos que el lector tiene un cierto nivel de experiencia. Si podemos asumir más experiencia, entonces podemos escribir menos. Si tenemos que asumir menos experiencia, entonces tenemos que escribir más."
Software Development as a Cooperative Game, Alistair Cockburn

Cockburn profundiza la presentación del concepto en en el borrador de su libro "Crystal Clear" (http://members.aol.com/humansandt/crystal/clear/):
"Las personas que hablan entre ellas para comunicar ideas, necesariamente usan referencias de experiencias en común. Esto debe ser así, de hecho, no existe otra forma de comunicarse. Las personas con las experiencias compartidas necesarias entienden la comunicación, las otras no.
...La ventaja [de esta característica de la comunicación] es que los desarrolladores de software pueden acotar las descripciones de lo que están haciendo acudiendo a la extensiva experiencia compartida con sus compañeros. Esto les permite moverse más rápido."
Quien lleve un tiempo desarrollando seguramente habrá experimentado esta ventaja. ¿Cuántas veces hemos participado de un dialogo como el siguiente? :

- Juan, ¿no te acordas si en algún lado habíamos hecho una clase de búsqueda para el XML de seguridad de la versión vieja?
- Si, Carlos, creo que hay algo en el sistema del gobierno para la importación a Meta4. Fijate en la carpeta Varios, creo que por ahí estaba la dll y el código.

Este dialogo esta lleno de referencias a experiencias compartidas. Juan y Carlos saben que es "una clase de búsqueda para el XML de seguridad de la versión vieja", "en el sistema de gobierno para la importación a Meta4" y "la carpeta Varios".
Este tipo de conversación sería imposible entre dos personas sin experiencias compartidas. En ese caso la conversación tendría que ser más específica, detallada y lenta. Cockburn continúa:
"...esto no es algo que se pueda evitar. No es como se piensa, que escribiendo casos de uso los desarrolladores entenderán repentinamente los requerimientos. Los desarrolladores que leen los casos de uso deben tener un conocimiento adecuado en el vocabulario del negocio para entender lo que están leyendo. Si ellos tienen un conocimiento amplio, entonces los casos de uso pueden ser más cortos y anecdóticos... La especificación no es una especificación a menos que los lectores la entiendan."
Es interesante pensar como pueden afectar nuestra manera de valorar los requerimientos las connotaciones de esta última frase.
Karl Wiegers define algunas características de requerimientos excelentes. Entre ellas:
"Completo: cada requerimiento debe describir completamente la funcionalidad ha ser entregada. Este contiene toda la información necesaria para el desarrollador para diseñar e implementar esa funcionalidad..."

"Sin ambigüedad: Todos los lectores de una especificación de requerimientos deben llegar a una única y consistente interpretación de esta."

Writing Quality Requirements, Karl Wiegers

Si tomamos como ciertos los comentarios de Cockburn, podemos concluir que es imposible que estas sean características intrínsecas de los requerimientos. La completitud y ambigüedad variara según el lector.

Por eso una especificación puede carecer de ambigüedad, ser completa, y a la vez ser breve, para un lector o grupo de lectores en particular. La brevedad me resulta una característica muy valorable en una especificación de requerimientos, donde se aproveche al máximo las experiencias compartidas de las personas que se tratan de comunicar a través de esta especificación.
Saber que es lo que se debe construir no implica necesariamente escribir un extenso documento. Muchas veces no es la mejor manera de hacerlo aunque sé que en muchas situaciones es la manera posible, aceptada, o habitual. Y por eso pienso que documentar requerimientos no es una regla básica que se tenga que cumplir, aunque conocer las necesidades y definir las soluciones si lo es.

Muchas veces se plantea como un cambio difícil de lograr el que requiere dejar el caos para comenzar a desarrollar software aplicando buenas prácticas. Creo que un cambio igual de difícil es replantear esas buenas prácticas a la luz de los objetivos y pensar que pueden existir alternativas que merecen ser consideradas.

miércoles, 3 de marzo de 2004

Personas, aprendizaje y proceso de desarrollo

La influencia de las características de las personas en el desarrollo de software es un tema que me resulta de gran interés. Por eso es inevitable que los libros de Alistair Cockburn sean el origen de más de un artículo en este sitio.

Esta vez me gustaría pensar un poco sobre personas, aprendizaje y procesos de desarrollo. Comencemos...

Alistair Cockburn, en su libro Agile Software Development, hace mención de las tres etapas de aprendizaje, las cuales que me resultaron especialmente reveladoras. Se trata de lo siguiente:

La gente que está aprendiendo nuevas habilidades pasa por tres etapas de comportamiento bien definidas: following, detaching y fluent.

La gente en la etapa following busca un procedimiento que funcione. Aún cuando 10 procedimientos distintos puedan funcionar, ellos no pueden aprender 10 al mismo tiempo. Ellos necesitan uno para aprender primero, uno que funcione. Ellos lo copian y lo aprenden. Necesitan instrucciones explícitas, una receta.

En la etapa detaching la gente localiza las limitaciones de su procedimiento y busca reglas para saber cuando el procedimiento no sirve. En esta etapa la persona aprende a adaptar el procedimiento a varias circunstancias. Ahora está más interesado en aprender los 10 procedimientos alternativos, en aprender cuando aplicar cada uno y cuando no funcionan.

En la tercer etapa, fluent, se torna irrelevante para la persona si está siguiendo una técnica específica o no. Su conocimiento se ha integrado entre cientos de acciones y pensamientos. Si se le pregunta si está siguiendo un procedimiento particular seguramente levantara sus hombros: no es importante para él si está siguiendo un procedimiento, improvisando uno alrededor de uno existente, o creando uno nuevo. Entiende el efecto final deseado y simplemente se conduce hacia él.
Conocer esta evolución me ha aclarado gran cantidad de situaciones.

He vivido esta evolución más de una vez.

Recuerdo clases de Diseño de Sistemas en la universidad, cuando el paradigma orientado a objetos era algo relativamente nuevo para mí y me iniciaba en la tarea de encontrar objetos a partir de requerimientos. Allí estaba yo, algo desconcertado, conociendo una manera distinta de pensar los problemas y sus soluciones. Sin duda transitaba la primer etapa que menciona Cockburn, y necesitaba una receta que pudiera seguir. La receta clásica para encontrar objetos es extraer los sustantivos que forman parte de los requerimientos. Así, si en alguna parte de la especificación de requerimientos dice:

Mensualmente cada empleado recibe su sueldo según las horas trabajadas

yo detectaba los objetos empleado, sueldo y hora. Es una técnica bastante simple (y directamente inútil para algunos[1])
No hizo falta que pasara mucho tiempo para que me diera cuenta de las limitaciones de esta receta y que la utilizara sólo como un punto de partida para agregar luego otras abstracciones que me parecieran necesarias y quitar las prescindibles. Ya estaba en la etapa 2.

Hoy no uso concientemente una técnica particular para detectar abstracciones en los requerimientos, simplemente lo hago. Me resultaría molesto que alguien me obligue a aplicar una técnica como la extracción de sustantivos para detectar objetos. Haría mi trabajo más lento, los resultados serían peores y encima estaría de mal humor. Pero esa receta tuvo su utilidad en algún momento.

Etapas de aprendizaje y procesos de desarrollo

Ahora me gustaría establecer una relación entre estas tres etapas y la definición de procesos de desarrollo de software.
Me parece lógico que el nivel de definición de un proceso de desarrollo sea acorde al nivel de aprendizaje de las personas que lo utilizarán.

Supongamos un escenario extremo: no hay proceso de desarrollo definido (¡huy, qué extremo!). En este contexto, hay personas a las que se les puede dar un proyecto de desarrollo y lo hacen. Y pueden tener éxito repetidamente. Porque saben lo que necesitan para hacerlo y lo que no saben lo aprenden. Punto.

Tal vez comiencen registrando requerimientos en un documento casi sin formato y pasarán a algo más sofisticado si hace falta.
Seguramente acordarán un conjunto de directivas de codificación que respetarán uniformemente, y no les tomará demasiado tiempo porque saben que lo importante de las directivas de codificación es respetarlas, no definirlas.

Estableceran algúna política para el manejo de versiones y desarrollarán todo el código utilizando pruebas unitarias. Integrarán diariamente el código y no permitirán que código que no pase las pruebas unitarias esté presente en el repositorio. Se organizarán asignado tareas para cada uno considerando las dependencias y las fechas de entrega, y no será gran problema si alguna tarea tarda un poco más o menos sabrán resolverlo. Posiblemente hagan el seguimiento del proyecto en una simple planilla de cálculo. Si hay problemas de sincronización de cambios en la base de datos definirán un procedimiento para realizar estos cambios y tal vez hasta desarrollen una pequeña heramienta para hacerlo. Si faltan datos en la especificación de requerimientos, modificarán los documentos para que se incluyan. Tambien es muy probable que hagan revisiones de pares para partes críticas o, ¿quien sabe?, tal vez hasta apliquen pair programming.

El hecho es que no les importa si lo que hacen es parte de un proceso definido previamente o una nueva técnica digna de un premio Turing. Lo hacen. Funciona. Punto.

Un proceso simple con herramientas simples son suficientes para que ellos sean eficientes. Ellos piensan: "Desarrollar software no es rocket science". Simplemente lo saben hacer.

Tambien existen otras personas que necesitan recetas, guías paso a paso para poder sentirse seguras que están haciendo las cosas tal como deberían. Prefieren contar con grandes plantillas para definir requerimientos y no las modificarán aunque en la mitad de los datos solicitados siempre escriban "No aplica". Necesitan revisar listas de verificación de varias páginas en cada paso del proyecto para saber que lo hicieron bien y valoran una planificación detallada de actividades de horas de duración para saber quien hace cada cosa y que se debe hacer despues. La programación se les torna demasiado complicada sin un documento de diseño con diagramas de clases que les indique que métodos deben programar, como se relacionan los objetos y hasta que tipo de colección conviene utilizar para guardar los items de una factura.

No son malas personas, no son menos inteligentes, sólo estan en una etapa temprana de aprendizaje.

Un equipo de desarrollo de software compuesto por personas en este estado inicial de aprendizaje por más proceso de definido que tengan dificilmente pueda nivelar sus resultados con un equipo formado por personas en la tercera etapa, de la misma manera que un principiante en diseño orientado a objetos no puede alcanzar los diseños de Kent Beck identificando sustantivos en una frase. Esto es así y no hay nada que pueda cambiarlo. Además las recetas detalladas apropiadas para determinadas personas pueden ser contraproducentes para otras.

Esta idea de adaptación de un proceso a las personas que lo utilizan parece brillar por su ausencia, porque muchas veces pensamos que podemos resolver la mayoría de los problemas definiendo con más detalle nuestro proceso de desarrollo, agregando más documentos, más actividades, más listas de verificación. Dejando menos margen para el error. Mitigando más riesgos. Y estamos dispuestos a invertir dinero en este refinamiento del proceso porque parece que con esto ganamos en certidumbre, en predecibilidad.

Si observamos que agregar más detalle a un proceso que será utilizado por personas que saben desarrollar software no es necesario porque en realidad no representa una mejora, entonces es posible que exista una alternativa: invertir dinero en el aprendizaje de las personas para formar equipos que sepan adaptar las prácticas a su proyecto, que completen su proceso, que sepan desarrollar software. Priorizar las personas y sus interacciones sobre los procesos y las herramientas.


[1] Bertrand Meyer, en su libro Construcción de Software Orientado a Objetos, habla sobre la técnica de identificación de objetos mediante sustantivos:

"Si la vida fuera tan sencilla uno podría llevarse a casa por la noche los documentos de requisitos y jugar al Object Pursuit en la mesa del comedor. Esta podría ser una buena forma de mantener a los niños alejados de la TV y hacer que revisen sus nociones de gramática mientras ayudan a mamá y papá en su trabajo de ingeniería de software"

domingo, 11 de enero de 2004

SWEBOK

El IEEE SWEBOK es un intento para definir el cuerpo de conocimiento de nuestra profesión, de manera tal que pueda ser utilizada como base para transformarla en una profesión practicada bajo licencia. Busca identificar y describir un subconjunto del cuerpo de conocimientos que es generalmente aceptado.

¿Qué significa "generalmente aceptado"? Significa que el conocimiento y las prácticas descritas son aplicables a la gran mayoría de los proyectos, la gran mayoría de las veces, y que existe un consenso generalizado sobre su valor y utilidad.

Cuando uno analiza los objetivos de este proyecto piensa que su resultado será un documento que sintetiza las grandes verdades de la ingeniería de software, mayormente verdades incuestionables. Si un documento puede tener estas características, seguro que no es el SWEBOK.

Para empezar la ACM (The Association for Computing Machinery) evaluó el SWEBOK y concluyó que este era seriamente defectuoso y que la ACM debía alejarse de su desarrollo.

Por otro lado, Cem Kaner hace una crítica detallada de la sección de testing del SWEBOK y concluye:
"Podría escribir páginas y páginas sobre las flaquezas del SWEBOK, pero pienso que no tendría sentido.
Estoy de acuerdo con la evaluación de la ACM que el SWEBOK comenzó con un enfoque esencialmente defectuoso. El resultado continúa siendo esencialmente defectuoso...
Yo dicto cursos de testing de software. El SWEBOK no es una buena referencia para incluir en ellos.
El criterio de inclusión y exclusión del SWEBOK es poco satisfactorio. Muchos de los tópicos más importantes de mis cursos de testing, (como test driven development, testing a nivel de API, testing de escenarios, skilled exploration, la diferencia de objetivos y costo/beneficio entre los conjuntos de test regresivos a nivel de unidad y a nivel de sistema, testing basado en riesgos, ... y varios más), están ausentes en el SWEBOK.
Mucho de lo presente en el SWEBOK está organizado extrañamente, es anticuado, y muchas de las técnicas son marginales en términos de que tan frecuentemente son utilizadas y cual es el valor que realmente proveen."

SWEBOK Problems, Part 2, Cem Kaner

Grady Booch dijo en la lista de discusión de Extreme Programming:
"Yo fui uno de esos 500 revisores iniciales - y mis comentarios fueron completamente negativos. El SWEBOK que revisé era bienintencionado pero malenfocado, simplista, incoherente, y simplemente errado en tantas dimensiones."

Recuerdo mi entusiasmo cuando encontré la página del SWEBOK en Internet hace un par de años. En un primer momento consideré que había encontrado un recurso muy valioso. Bajé los documentos, los imprimí y comencé a leerlos. Poco a poco el entusiasmo se fue diluyendo. Nunca terminé de leer esos documentos y no está en mis planes hacerlo alguna vez. Posiblemente la explicación de mi desinterés se encuentre en la frase de Martin Fowler:
"Existen montones de estandares de la IEEE ahí afuera que son rutinariamente ignorados por cualquiera que esté haciendo desarrollo de software comercial. La mayoría de estos estándares son escritos por estudiosos y estos están ocupados en grandes proyectos gubernamentales. La gente de negocios no considera al ámbito gubernamental como un sinónimo de eficiencia."

Swebok, Martin Fowler

domingo, 5 de octubre de 2003

Aprendiendo de Toyota

Observar los errores y aciertos de otras industrias es una técnica muy utilizada para mejorar el estado actual del desarrollo de software como disciplina, y pienso que aprovechar años de madurez de industrias como la automotriz puede ser beneficioso siempre que se haga observando con atención hasta donde cada práctica, técnica o principio es adecuado para el nuevo ámbito donde se lo desea aplicar.

Bien, ahora el punto es, ¿a quién observamos para aprender? Muchas empresas en el pasado han aprendido del fenómeno japonés y de Toyota en particular. ¿Observar a Toyota puede aportar algo al desarrollo de software? Podemos pensar que si.

Taiichi Ohno fue contratado por Toyota para instalar un sistema de producción para producir automóviles de alta calidad. Durante 3 décadas, Ohno desarrollo el Toyota Production System, conocido ahora como Lean Manufacturing.

Los valores básicos de Lean Manufacturing son:

* Agregar sólo valor
* Centrarse en las personas que agregan valor
* Generar valor por demanda
* Optimizar a traves de organizaciones

Hay varias factores llamativos en Lean Manufacturing: su aplicación representó un mejoramiento notable de la calidad y productividad, requería un cambio de paradigma porque contradecía buenas prácticas aceptadas hasta su aparición y sus principios han sido exitosamente aplicados en negocios de todo tipo.

Seguramente, estos factores han sido elementos importantes que llevaron a Mary Poppendieck ha escribir un conjunto de artículos y un libro trasladando las enseñanzas de Lean Manufacturing al desarrollo de software. Es un material que merece ser leido.

Algunos extractos de sus artículos para tener una primera aproximación al tema:
“El 'Lean Thinking' observa la cadena de valor y se pregunta: ¿cómo se pueden estructurar las cosas para que la empresa no haga nada además de agregar valor, y que lo haga lo más rápido posible? Todos los pasos intermedios, todos los tiempos intermedios y todas las personas intermedias son eliminadas. Sólo se deja el tiempo, las personas y las actividades que agregan valor para el cliente”

“La medida de madurez de una organización es la velocidad con la cual puede responder repetida y confiablemente a solicitudes de sus clientes.
Si, escucho bien. La madurez no es medida por la amplitud de la documentación de un proceso o la habilidad de hacer planes detallados y ejecutarlos. Es medida por la excelencia operacional, y el principal indicador de la excelencia operacional es la velocidad con la cual la organización puede repetida y confiablemente servir a sus clientes.”

“Por lo tanto, si el cliente quiere algo, ¿qué pasos debe cumplir la solicitud para que el resultado sea entregado al cliente? ¿ Qué tan rápido fluye ese proceso? Si la solicitud de un cliente espera en una cola para aprobación, una cola para diseño, una cola para desarrollo, una cola para testing, y una cola para despliegue, el trabajo no fluye muy rápido. La idea es crear celdas(o equipos) de personas encargadas de tomar cada solicitud desde la cuna hasta la tumba, rapidamente y sin interrumpciones. Entonces el valor fluye.”

“Los documentos, diagramas y modelos producidos como parte de un proyecto de desarrollo de software son productos perecederos, ayudas utilizadas para producir el sistema, pero no necesariamente parte de un producto final. Una vez que un sistema completo es entregado, al usuario le puede importar muy poco estos productos intermedios. Los principios del Lean Thinking sugieren que cada producto intermedio es candidato a escrutinio. La carga sobre cada producto intermedio no es sólo probar que agrega valor para el producto final, sino tambien que es la manera más eficiente de alcanzar este valor.”

“Cuando se observan detalladamente, la mayoría de las teorías sobre como administrar proyectos de software son basadas en la teoría de descomposición: separe el todo en partes individuales y optimice cada una. El Lean Thinking sugiere que optimizar parte individuales casi siempre lleva a sub-optimizar el sistema completo.
Por ejemplo, optimizar el uso de recursos de testing decrementa la aptitud de todo el sistema de producir rapidamente código testeado y funcionando. Medir la habilidad individual de producir código sin defectos ignora la hecho bien conocido que el 80 % de los defectos son causados por la manera en que el sistema funciona, y por lo tanto problemas de management.”

Los artículos: Lean Software Development, Principles of Lean Thinking, Lean Programming , Mary Poppendieck
El libro: Lean Software Development: An Agile Toolkit for Software Development Managers, Mary Poppendieck y Tom Poppendieck.

viernes, 5 de septiembre de 2003

Craig Larman en Argentina

En la entrada del hotel se podía leer un cartel que decía: "Craig Larman, UML y Patrones".
Esa frase es prometedora. Escuchar hablar sobre patrones y UML a un consultor reconocido mundialmente y autor de uno de los libros más vendidos sobre diseño de software, es una oportunidad muy valorable. pero es indudable que las personas que asistimos al evento no obtuvimos lo que esperabamos, pero más importante, no esperabamos lo que obtuvimos. El nombre completo del seminario era "Modelado Agil con UML y Patrones". Agil. Esa palabra puede marcar una gran diferencia.

Algunos temas que pude rescatar de mis notas:

Coraje

En la presentación de los valores de Agile Modeling comenzó a evidenciarse cual sería el tono que se mantendría en toda la charla. "Uno de los valores de AM es coraje. Coraje para decir no sé, coraje para aceptarlo". Aquí comenzo su cuestionamiento al enfoque predictivo (¿o adivinatorio?) aplicado comunmente donde se responden a las preguntas "¿Cuánto costará?" y "¿Cuánto tiempo tomará?" antes de iniciar un proyecto, momento en el cual las únicas respuestas sinceras y racionales serían: "No sé."

El desarrollo de software es desarrollo de un nuevo producto

Este fue un concepto enfatizado constantemente. Se trata de entender el desarrollo de software como el desarrollo de un nuevo producto donde son necesarias grandes cuotas de creatividad, investigación, descubrimiento y retroalimentación, y donde no son aplicables procesos repetibles de manufactura.

Siguiendo esta línea de pensamiento, Larman dijo que lo peor que uno puede hacer al iniciar un proyecto es armar un plan detallado lleno de tareas, definiendo su duración, sus responsables, sus precedencias, etc, especificando cual será la realidad del proyecto de aquí a seis meses y luego seguirlo. "Es lo peor que un administrador de proyecto puede hacer. Si lo hace, no está administrando un proyecto".

Presentó la alternativa de un plan compuesto por varias iteraciones sin mucho detalle, donde existe una planificación sobre las fechas y los objetivos mayores a cumplir, y donde se conoce el detalle de lo que se hará sólo para las siguientes 2 iteraciones a lo sumo, hablando de iteraciones de 2 o 3 semanas. El plan va evolucionando a medida que pasa el tiempo y se va adaptando a las necesidades que se manifiesten, haciendo uso de lo aprendido en las iteraciones ya terminadas.

Tambien mencionó la madurez de otras industrias, como la farmacéutica y la petrolera, para entender las características de su negocio y aceptar que no se pueden hacer estimaciones y planes útiles, es decir con márgenes de error aceptables, sin una etapa de investigación.

CMM

En la ronda de preguntas surgió una inquietud previsible: ¿Cómo se relacionan estas prácticas agiles con frameworks de madurez como CMM?
Larman contestó: "No sé cual es la realidad que se vive en la Argentina, pero por mi experiencia puedo decir que la sensación que tengo es que CMM está muerto...
Subirse a la ola de CMM es subirse a la ola de los años '90, es subirse a una ola que está comenzando a decaer...
Hoy el interés de las empresas, en vez de pasar por certificar un nivel de CMM, reside en responder a cambios de manera rápida. Por eso se están interesando en las metodologías agiles."

Waterfall thinking

Mencionó que uno de los errores que ha observado con mayor frecuencia es la superposición de los principios de un ciclo de vida en cascada sobre cualquier proceso o metodología que se utilice. "Una y otra vez visito empresas donde escucho: 'Estamos comenzando a usar RUP en un nuevo proyecto. Cuando terminemos de definir todos los casos de uso, podremos definir la arquitectura, y luego comenzar a desarrollar.'"

No esperabamos lo que obtuvimos, pero en lo personal el balance resulto muy positivo. Creo que el valor mayor del seminario estuvo en poner en contacto con ideas nuevas e importantes en el mundo de desarrollo de software a una comunidad que por lo general participa de este tipo de movimientos con años de retraso.

El desarrollo agil es una alternativa demasiado importante para desconocerla.

lunes, 28 de abril de 2003

YAGNI

Hace unos años, cuando cursaba cuarto año de la facultad, participe en un proyecto de desarrollo con unos compañeros.
En aquella época gran parte de mi atención estaba centrada en el diseño orientado a objetos. Probablemente Bertrand Meyer fue el responsable mayoritario de esto. Para ser sincero, en aquel tiempo pensaba que la orientación a objetos podía resolver gran parte de los problemas que aquejaban al desarrollo de software. Me parecía fantástico conceptualmente y me provocaba sorpresa que no toda la gente lo viera como yo.

En aquel entonces programaba en Borland Delphi y era muy entretenido ver en acción la herencia, el polimorfismo y usar la RTTI (run-time type library, similar al concepto de Reflection en Java). Dado este interés, en este proyecto decidimos hacer uso de objetos para modelar las entidades del negocio (clientes, proveedores, facturas).

Pero nos encontramos con el problema de la impedancia entre el modelo relacional y el orientado a objetos; básicamente el problema de traducir los objetos, sus atributos y sus relaciones en tablas y campos. En búsqueda de una manera optima de resolver este problema, leímos todo artículo relacionado con el tema que pudimos encontrar en Internet. Llegamos a la conclusión que debíamos construir una capa de persistencia, un conjunto de clases mediante el cual uno podría manipular objetos, guardarlos y consultarlos sin necesidad de conocer nada acerca de la base de datos. Algo similar a lo presentado por Scott Ambler en The Design of a Robust Persistence Layer For Relational Databases. Recuerdo que desarrollar una capa de persistencia era un problema que me resultaba muy motivante para resolver. Hay muchas dificultades para sortear, muchas decisiones para tomar, muchas características para agregar.

* ¿Cómo manejamos las colecciones dentro de un objeto?
* ¿Qué pasa cuando traemos a memoria 100 objetos desde la base de datos?
* ¿También traemos los objetos relacionados?
* ¿O sólo los construimos por demanda?
* ¿Cómo controlamos la concurrencia?
* ¿Cómo hacemos con los generadores de reportes y otros componentes que generalmente requieren un conjunto de datos con filas y columnas?
* ¿Cómo diseñamos la capa de persistencia para que sea independiente de RDBMS?
* ¿Permitimos uso de transacciones anidadas?

Si, definitivamente era divertido.

Pero estábamos en la universidad. Y las disquisiciones de valor académico que son válidas en ese entorno no lo son cuando salimos de él. El tiempo invertido en aquel proyecto de desarrollo para construir ese framework celestial para guardar objetos representaría un uso ineficiente de recursos para un proyecto real. No contábamos con elementos significativos de retroalimentación (¿qué le importa a un cliente si mapeo una jerarquía de herencia con una tabla o dos tablas?) e invertimos trabajo en funcionalidad que nunca se utilizó.

He observado que en un proyecto de desarrollo se presentan muchas oportunidades para invertir recursos en funcionalidad que no se necesita, aunque estas aparecen de manera sutil, como funcionalidad completamente razonable.

Por ejemplo, pensemos en una aplicación donde se emite un formulario impreso que puede tener dos formatos distintos según la categoría del cliente al que se le envía, "mayorista" o "minorista". Es algo simple de hacer, seria algo así:

if (Cliente = "mayorista") ImprimirFormulario(Formato1)
else ImprimirFormulario(Formato2)


No, mejor guardamos en una tabla con parámetros las categorías de cliente y los diseños de formulario que le corresponden. Al momento de imprimir consultamos la tabla de parámetros y aplicamos el diseño adecuado. Es más, podríamos guardar un template que represente el diseño del formulario en algún formato. Ya sé, ¡en XML! Y podríamos hacer un diseñador de templates donde el usuario podría hacer sus propios formularios y asignarlos a nuevas categorías de clientes si estas surgen en el futuro...

¡¡¡ Y A G N I !!!

Eso gritaría un practicante de Extreme Programming. YAGNI es un acrónimo que significa "You Aren't Gonna Need It" (No lo necesitarás). YAGNI representa la idea: siempre implemente algo cuando realmente lo necesite, nunca cuando supone que lo necesitará.

Ron Jeffries, reconocido desarrollador y pionero en el campo de las metodologías ágiles, lo explica claramente con un ejemplo:
Usted está trabajando en alguna clase. Sólo agrega la funcionalidad que necesita. Supone que va a necesitar algo de funcionalidad adicional. Si no la necesita ahora, no la agregue ahora.

Por qué no?

"OK, Sam, ¿por qué quieres agregarla ahora?"

"Bueno, Ron, nos ahorrará tiempo más adelante."

A menos que tu universo sea muy distinto al mío, no puedes ahorrar tiempo. Sólo puedes hacer menos. Entonces me estas diciendo:

"Vamos a poder hacer menos más adelante (a costo de hacer más ahora)."

A menos que tu proyecto sea muy distinto al mío, ya tienes mucho por hacer ahora. Hacer *más* ahora es algo muy malo cuando ya se tiene mucho por hacer. A menos que tu mente sea muy distinta a la mía, tienes una probabilidad distinta de cero de no necesitar esa funcionalidad después de todo, o de tener que retocarla aún antes de necesitarla cuando modifiques la clase por alguna razón.
Si algo de esto pasa, has desperdiciado tu tiempo completamente, además de asignarte más cosas para hacer ahora, cuando difícilmente necesitas más para hacer.

"Pero Ron, si lo hago ahora sabré como hacerlo, y más adelante tal vez no lo sepa."

"Entonces, Sam, me estás diciendo que la clase que estás escribiendo es tan compleja que ni tú serás capaz de mantenerla?"

Mantenla simple. Si necesitas la nueva funcionalidad, la puedes agregar más adelante. Si no la necesitas, no tendrás que hacer nada de ese trabajo. Tomate el día libre.

Por supuesto, no basta con decir YAGNI para que un elegante diseño evolutivo emerja espontáneamente. Hay dos técnicas fundamentales que hacen posible este diseño evolutivo: refactoring y TDD, temas lo suficientemente interesantes como para dedicarle un espacio en el futuro.

Cada vez que escribo, termino con más preguntas que respuestas. Esta vez no será la excepción.
¿Por qué nos cuesta tanto hacer sólo lo que realmente necesitamos?

viernes, 18 de abril de 2003

Fábricas de software

Imaginemos, por un momento, como sería la empresa de desarrollo de software ideal. Como sería el trabajo en un proyecto en esa empresa. Visualicemos el día a día, los roles, la manera de trabajar...

He notado que muchas personas tienen una visión coincidente sobre la empresa de desarrollo ideal. Piensan que idealmente una empresa de desarrollo debería ser como una fábrica.

Una fabrica de software donde exista un proceso definido y repetible. Las actividades son planificadas y se desarrollan de manera predecible. Un plan inicial es trazado y día a día, los desarrolladores ingresan datos en un sistema que reflejan el avance al minuto. El tiempo es aprovechado al máximo porque se conoce con certeza la precedencia de las actividades, la disposición de recursos, las fechas de entrega. El conocimiento necesario para realizar las actividades esta formalizado explícitamente en documentos y cualquier nuevo componente incorporado al proceso productivo puede contar con esa información para hacer su trabajo. Existen los elementos que permiten medir la productividad de cada uno de los componentes de la fábrica y hacer ajustes donde sea necesario. Se tiene control sobre la calidad de los resultados y la productividad. Control, predecibilidad, certidumbre, calidad.

Una verdadera fábrica industrial de software.

Pero...

Hay otras personas que no creen que la fábrica de software sea posible. Y van más allá, opinan que muchos de los problemas que afronta nuestra actividad surgen del enfoque que pretende estructurar empresas de desarrollo de software como fábricas. Mike Beedle es una de esas personas y dice al respecto:
"Durante 30 años el mundo del software ha sido influenciado por las ideas de la manufactura. Todo esto comenzó cuando gerentes de manufactura tomaron empleos en compañías de desarrollo de software y se le solicito a pensadores de manufactura que pensaran sobre software. Desafortunadamente ellos llegaron con un montón de equipaje de manufactura y tratamos de aplicar las mismas técnicas usadas en manufactura en ese tiempo:

* Procesos estandarizados definidos y repetibles
* Técnicas de TQM[Total Quality Management]
* Gestión voluminosa, donde las entradas y salidas son sólo observadas como hitos de fases.

Desgraciadamente, este paradigma de fabricación no se acomoda demasiado bien al desarrollo de software. En cambio, el software requiere un enfoque mucho más parecido a un proceso de desarrollo de un PRODUCTO NUEVO , porque el software siempre es una combinación de 1) crear nuevos componentes o 2) ensamblar viejos componentes de formas nuevas.
Crear nuevos productos requiere investigación, creatividad y enfoques de prueba/error. Y esto se adapta muy bien al software porque:

detectar requerimientos,
diseñar una solución,
implementarla, y
testearla

requiere investigación, creatividad e implementaciones de prueba/error.
Por otro lado, la mayoría de las veces, estas actividades no llegan en secuencias lineales repetibles -- ellas son simplemente el resultado de inspecciones y pruebas constantes, donde cualquier actividad puede disparar cualquier otra.
Tal así, el software requieren de un nuevo conjunto de practicas y actitud, que permita que el software sea desarrollado en una manera mucho más dinámica, adaptable y auto-organizada."

También se cuestiona la idea de la fabrica de software porque no considera características de las personas, factores principales en el proceso de desarrollo. Alistair Cockburn, en su artículo Characterizing People As Non-Linear, First Order Components In Software Development expresa:
"Quizás más interesante y menos obvio ... es la manera no lineal en que las personas trabajan. Ellos no siguen un secuencia predecible para ir del problema a la solución. Esto es sabido para matemáticos y programadores, quienes se ganan la vida resolviendo problemas. Esto ha mantenido siendo un secreto para gerentes y especialistas en metodologías quienes aún tratan de hacer un proceso de desarrollo de software que sea lineal."

Mas allá de esto, la discusión sobre si se pueden aplicar principios de fabricación industrial al desarrollo de software no es la cuestión central. Pienso que la cuestión central es que queremos mejores resultados, queremos ser más productivos, queremos productos de más calidad.

Un camino de alcanzar esto ha sido observar otras actividades y detectar si hay algo que podamos aplicar en la nuestra. Otro camino posible es observar los proyectos exitosos de nuestra actividad y ver que características tienen para repetirlas en nuevos proyectos. Esto es lo que ha hecho James Coplien.

Analizando un proyecto exitoso

James Coplien escribió el famoso paper Borland Software Craftsmanship: A New Look at Process, Quality and Productivity donde documenta las conclusiones de su estudio del admirable proyecto de desarrollo de Borland Quattro Pro® for Windows (QPW).
"El desarrollo de Borland Quattro Pro for Windows (QPW) es una de las más notables organizaciones, procesos y culturas de desarrollo que hemos encontrado en el proyecto de investigación de procesos Pasteur de AT&T Bell Laboratories. El proyecto asimiló requerimientos, completó el diseño y la implementación de 1 millón de líneas de código, y completó el testing en 31 meses. La programación fue hecha por no más de ocho personas a la vez, lo que significa que la productividad individual fue mayor que 1.000 líneas de código por persona por semana."
"El producto QPW ingresó al mercado con gran aclamación. PC Sources dijo, 'Quattro Pro hace el mejor uso de la interfaz de usuario de Windows que ningún otra planilla de cálculo actual." PC User dijo que 'Quattro Pro for Windows es la mejor planilla de cálculo del mundo' Computer Shopper dijo sarcástico 'Quattro Pro for Windows supera al campeón actual de planillas de cálculo Microsoft Excel 4.0' "

Productividad y calidad impresionantes. Veamos algunos puntos que caracterizaron este proyecto:

* Alta comunicación entre los integrantes del equipo.
"El proceso de QPW tiene una comunicación superior que el 89% de los procesos que hemos observado... Es una organización pequeña e intensamente interactiva"
"El equipo de arquitectura se juntaba diariamente para elaborar las interfaces de las clases en C++, para discutir algoritmos y enfoques globales y para desarrollar los mecanismos fundamentales sobre los cuales el sistema sería construido"

* Equipo pequeño y estable con profesionales expertos en su campo.
"El equipo de desarrollo de QPW tiene una membresía cronológicamente madura para los estándares de la industria... Las personas son incluidas en el equipo por su reconocida experticia en dominios de importancia central para el proyecto: motores de planillas de cálculo, gráficos, bases de datos, y así sucesivamente... Cada uno trae un talento especial para el logro."
"QPW tuvo un equipo principal pequeño --cuatro personas-- quienes interactuaron intensamente durante 2 años para producir la parte principal del producto."

* Desarrollo iterativo.
"El desarrollo de QPW fue altamente iterativo"

* Sin proceso formalmente definido.
"Borland no está sujeto a estándares de proceso ISO 9000, no tiene noción de su valuación SEI CMM, y no es entendido en la jerga de procesos de desarrollo de software siendo usada cada vez más en grandes organizaciones de software...
Aún cuando la organización no tiene un sistema codificado de proceso, es agudamente conciente de lo que hace, como lo hace, y que funciona. Ven el desarrollo de software como algo fundamentalmente conducido por casos especiales (al menos para desarrollo inicial genérico) y la repetibilidad no es una parte importante de su sistema de valores. No obstante los miembros de la organización fueron capaces de articular con gran detalle aspectos de su proceso que demostraron para mi satisfacción que ellos compartían un único modelo, tal vez basado en reglas de desarrollo, de como el desarrollo debe ser realizado."

Un conjunto de personas conformaron un equipo de desarrollo asombroso basados en alta comunicación, retroalimentación constante, idoneidad de sus integrantes y valores compartidos. No eran una fábrica de software.

Conclusión

Pienso en este proyecto y me tomo la libertad de sacar algunas conclusiones rápidas casi imprudentes:
Tal vez no nos hace falta un proceso formalmente definido.
Tal vez no nos hace falta un proceso repetible.
Tal vez no nos hacen falta actividades predecibles.
Tal vez no nos hace falta control absoluto.
Tal vez no hace falta parecernos a una fábrica.
Tal vez simplemente deseamos empresas donde proyectos como el QPW sean posibles, y contar con las personas que lo hagan posible.