Tinselcity

Bien, tenemos un problema, lo comprendemos, sabemos en qué consiste y hemos evaluado que, efectivamente, necesitamos desarrollar una solución para resolverlo. ¿Cómo empezamos?

Comienza por el comienzo

“…y cuando acabes, te callas”, decía el Sombrerero Loco a Alicia. Pero este es exactamente nuestro problema: ¿Por dónde empezamos? Puede que nos estemos enfrentando a un tipo de problema por primera vez, puede que el problema sea tan grande que nos cueste ver por dónde enfrentarnos a él, puede que, incluso comprendiendo el problema, aún no tengamos suficiente información. Sea por el motivo que sea, no siempre es sencillo saber cómo empezar.

Hay diferentes técnicas y diferentes herramientas que nos pueden ayudar. Cuál elegir es algo que dependerá, en gran medida, de nuestra manera de organizarnos y de pensar. Algunas formas se adaptarán mejor a unas personas y otras técnicas encajarán mejor con otras. Es bueno conocer varias y elegir la que mejor nos ayude o incluso, cuando ganemos más experiencia, quizá desarrollar nuestra propia técnica adaptando o mezclando cosas de cada una.

Eso sí, tengamos claro que todavía no tenemos una solución. Por tanto, el comienzo del que estoy hablando no es aún ponernos a escribir código1).

La solución

Insisto. Recordemos que en este momento del proceso no estamos todavía llevando a cabo la solución, estamos buscándola, y la solución no es código. Por tanto el “comienzo” del que hablamos es el comienzo la búsqueda de una solución, no por dónde empezamos a picar código.

Descomposición e identificación

Si hemos hecho bien el trabajo a la hora de comprender el problema, ahora deberíamos tener una vista suficientemente clara de en qué consiste. Sin embargo, como decíamos, puede que el problema sea muy grande o puede que nunca hayamos hecho nada parecido y no sepamos cómo se puede resolver.

Existen muchas técnicas y herramientas para diseñar una solución. Yo me voy a centrar, porque es lo que uso yo, en algo relativamente básico pero que me funciona muy bien. Las dos herramientas fundamentales a la hora de empezar a plantear o diseñar una solución que yo uso son: La descomposición despreocupada y la identificación de puntos importantes.

Descomposición despreocupada

Cuando tenemos un problema con una cierta complejidad o en general un problema que consideramos que es “muy grande”, la mejor forma de empezar es descomponerlo en partes más pequeñas. No intentemos, inicialmente, pensar en todo el problema a la vez. En lugar de eso, tomemos las diferentes partes que lo componen e intentemos hacer un pequeño esbozo de solución solo de esa parte.

Por ejemplo, imaginemos que queremos hacer 2) un sistema de comunicación visual basado en transmitir código Morse con algún tipo de LED3) en el emisor y con algún tipo de sensor de luz4) en el receptor. Y podemos escribir texto en un terminal y el sistema lo traduce y lo envía y lo recibe y lo vuelve a traducir de vuelta y lo muestra en el otro terminal.

Si lo miramos entero, el problema no es enorme pero es suficientemente grande como para que nos resulte difícil ver por dónde empezar. Sin embargo, en nuestra propia descripción del problema podemos percibir claramente que hay partes bastante diferenciadas e independientes. Lo más evidente es que por un lado tenemos el sistema emisor y por otro el receptor. Lo único que comparten esos sistemas es que el código usado entre ellos es Morse. Pero por lo demás ninguno depende del otro en absoluto.

Tomamos entonces el emisor, por ejemplo, y podemos ver que hay también varias partes: Tomar el mensaje que queremos transmitir; traducir el mensaje a Morse; usar el código Morse generado para encender y apagar el LED o la pantalla que usemos. Estas partes parecen algo más unidas. Pero solo lo parecen. En realidad son problemas bastante independientes también. Lo que ocurre es que, sin darnos cuenta hemos definido la solución de algo: del proceso de alto nivel.

Igual que al analizar el problema podíamos definir diferentes niveles de detalle, al diseñar nuestra solución debemos hacer lo mismo. Y, sin darnos cuenta, esto es lo que hemos hecho. Lo que tenemos en el párrafo anterior es la solución del proceso de alto nivel. Es decir, que exactamente “tomar el mensaje, traducirlo, sacarlo en pantalla” es, en sí mismo, una parte de la solución, es el proceso de alto nivel que dirige cada una de esas otras partes nombradas.

Podemos pensar: “Pues vaya cosa. ¿En qué me soluciona esto algo a mi, si luego no sé cómo hacer cada una de esas partes?”. Y por esto mismo a mi me gusta ponerle esa cualificación de “descomposición despreocupada”. De lo que se trata es de descomponer la posible solución completa en partes y que, cuando nos centremos en cada una de esas partes lo hagamos sin tener que preocuparnos del resto. Es decir, que cuando estamos planteando la solución de una parte del problema nos despreocupamos de las otras partes. Es razonable pensar que será más fácil resolver partes más pequeñas o que por lo menos algunas partes nos resultarán más familiares o asequibles.

Ojo, esto no quiere decir que mientras no nos estemos ocupando de unas partes las ignoremos o que no las tengamos en cuenta. Lo que quiere decir es que solucionamos una parte asumiendo que las otras están solucionadas. No sabemos cómo estarán solucionadas, pero ya llegaremos ahí cuando toque.

Siguiendo con nuestro ejemplo del comunicador por Morse. La solución del proceso de alto nivel ya la tenemos. Es tan simple como lo que hemos dicho. “Tomamos el mensaje”… no me importa cómo, asumo que ya solucionaré ese tema, pero ahora sé que tendré una forma de hacerlo y que me devolverá ese mensaje. Ese mensaje lo pasaremos a la parte que “traduce el mensaje”, que tampoco nos importa cómo lo haga, sólo nos importa que nos devolverá el mensaje traducido a Morse, para que después “lo saquemos por pantalla”, que de nuevo tampoco sabemos cómo ni nos importa, pero asumimos que le pasaremos el código Morse y lo sacará. Y cuando estemos pensando en cómo resolver la parte de, por ejemplo, traducir un mensaje de texto a Morse, no nos importará ni cómo hayamos obtenido ese texto ni qué vayamos a hacer luego con el código Morse. Es a esto a lo que me refiero con que nos despreocupamos.

Interfaces y protocolos

Hay un detalle que debemos tener en cuenta. Está muy bien despreocuparnos de cómo funcionen otras partes por dentro pero hay algo que sí nos afecta: cómo usamos esas partes desde fuera. Esto es todo un área en el diseño de soluciones: el diseño de interfaces y protocolos. Para no distraernos ahora con ello, ya lo veremos en algún capítulo próximo, pero como adelanto nos quedamos con la idea e que sí, en algún momento también será necesario definir cómo encajan unas piezas con otras.

Podemos dejar este tema para más adelante por una razón: en la mayoría de casos, esa definición de cómo deben encajar unas piezas con otras no es ni más ni menos que el problema de definir la solución de una parte de “alto nivel” como la del ejemplo. Así que, igual que con otras partes, cuando haga falta podremos asumir que ya la tenemos solucionada.

Nota: En realidad el diseño de interfaces y protocolos, la tarea de establecer cómo serán las “conexiones” entre diferentes partes, necesita un poco más de consideración y no siempre podremos “asumir tan despreocupadamente” que ya la solucionaremos. O por lo menos no del todo. Pero… ya lo veremos.

Identificación

Otra buena herramienta a la hora de ir trazando nuestra solución es la identificación. Se aplica a la vez que la descomposición.

Se trata simplemente de para cada uno de las partes que vayamos esbozando, tomar una serie de notas identificativas. ¿Qué dificultades presenta esa parte de la solución? ¿Qué cosas necesitaremos resolver? ¿Qué dificultad tiene? ¿Cómo de clara tenemos la solución? ¿Qué partes desconocemos? ¿Cómo de importante es esta parte dentro de la solución completa?

Hacernos estas preguntas -y más- nos ayudará mucho a la hora de identificar dificultades. Es importante, por ejemplo, ir anotando todos los temas que desconocemos y que, de alguna forma, deberemos investigar. También es importante por ejemplo identificar si una parte es más o menos difícil o si es más o menos importante. Querremos tener en cuenta la dificultad para ir planificando el esfuerzo que tendremos que aplicar antes o después. A veces ocurrirá que queramos solucionar alguna parte difícil primero porque eso nos guiará en otras partes y otras veces ocurrirá que si primero solucionamos otras partes más fáciles, eso nos ayudará a reducir la dificultad de la otra parte. En cualquier caso es interesante saberlo. En cuanto a la importancia… bueno, está claro que, en cierta medida, todo es importante; si no, no lo incluiríamos en nuestra solución. Pero también está claro que algunas partes serán más importantes que otras en algún aspecto. Hay partes, por ejemplo, cuyo funcionamiento apenas afecta a un área relativamente pequeña del problema. Otras, sin embargo, terminarán interactuando con casi todas las demás, haciendo que cualquier dificultad en ellas, pueda suponer mucho trabajo en todo el conjunto de la solución.

El ejemplo del comunicador Morse es, en principio, bastante sencillo y, generalmente no identificaremos partes demasiado conflictivas. Pero por ejemplo, puede ocurrir que no sepamos cómo se escribe el código Morse, así que será buena idea tomar nota de esa dificultad como algo que debemos investigar más a fondo.

Otra parte de la identificación, sobre todo en lo que se refiere a importancia o relevancia de las partes es la de identificar qué parte del problema resuelven. Generalmente tendremos una parte o partes que están muy directamente relacionadas con la esencia del problema. Esto es lo que solemos llamar el dominio del problema; en él con seguridad es donde encontraremos los conceptos más intrínsecamente relacionados con el problema original. Siguiendo con el ejemplo del comunicador de Morse, el dominio es la parte que se encarga de traducir los mensajes. En esa parte manejaremos los conceptos de mensaje, frase, palabra, símbolo, etc. Otras partes, en cierto modo estarán situadas alrededor del dominio. Podemos tener así el interfaz de entrada de datos, o de salida, funciones auxiliares, otro tipo de utilidades… Estas partes no carecen de su propia importancia, por supuesto5), pero suele ocurrir que sean más “intercambiables” e independientes del núcleo o esencia del problema. En el comunicador Morse está claro que necesitamos alguna forma de que el usuario pueda introducir sus textos; tendremos así en nuestra solución algún tipo de interfaz. Ahora bien, este interfaz podría tener muy diversas formas -podría ser una página web, un parámetro que se pase al programa al ejecutarlo desde línea de comandos, una ventana con una caja de texto para escribir, podríamos leer el texto de un fichero…- y esto no afecta al funcionamiento esencial del problema.

Diseñando la solución

¿Qué es lo que queremos producir en esta fase del desarrollo? Cuando hacemos esta descomposición e identificación, ¿qué hacemos? ¿Escribimos documentos? ¿Dibujamos? ¿Escribimos código?

De manera general, lo que buscamos en esta fase inicial de diseño de la solución es, una vez más, conocimiento. De nuevo, esto nos debería llevar a hacer algún tipo de diagrama o dibujo o a tomar notas, hacer alguna lista. La forma exacta en que lo hagamos no es lo más importante. Conozco personas que hacen listas, otras que escriben con detalle, otras hacen esquemas con cajas y palabras. Yo mismo no tengo una única forma. A veces, dependiendo de cómo sea de complicado o de nuevo o de grande el problema que quiero resolver, uso una u otra. Suelo dibujar cajas con palabras y flechas y anotaciones. A veces incluso en diferentes colores.

Como digo no es muy importante en un primer momento. Sin embargo, también es buena idea que según vayamos refinando nuestras ideas y teniéndolas más claras, escribamos o dibujemos algo un poco más “ordenado”. Podemos llevar esto hasta hacer algún pequeño documento de diseño, más o menos informal.

Hay que ser conscientes de que aún estamos en una fase bastante temprana. Sí, ya hemos conocido y analizado el problema. Y ahora, además, hemos hecho un primer diseño de nuestra solución propuesta. Sin embargo todavía podremos encontrar muchos puntos desconocidos. De hecho, algunos ya los habremos descubierto y sabemos que son desconocidos, y también es posible que surjan más. Con esto lo que quiero decir es que tampoco merece la pena hacer un documento muy elaborado o que suponga un esfuerzo importante, porque es muy probable que la solución final varíe en cierta medida respecto a lo podríamos escribir ahora.

Pero, por otro lado, es muy recomendable tener “algo”. Más o menos informal, más o menos aproximado. Pero en cualquier caso algo que nos sirva a la vez de guía o ayuda y de recordatorio de todas las cosas que ya hemos pensado.

Si trabajamos solos, esto será una comunicación con nuestro yo del futuro para que no se le olvide ningún detalle importante y para que no pierda el tiempo en volver a analizar cosas que ya hemos hecho. Si trabajamos en grupo, es una forma de comunicación con el resto del equipo; es una base para compartir nuestras ideas y poder transmitirlas mejor y luego discutirlas.

Sobre documentación

Sé que existen una serie de tendencias y metodologías actuales que… quitan importancia a la documentación. O por lo menos tratan de poner otras cosas por delante de ella. Hay que entender que estas metodologías surgen como una respuesta muy directa a otras anteriores que cometían el error de dar quizá demasiada importancia a la documentación.

Personalmente creo que la documentación es importante y por eso no conviene, como ocurre en ocasiones, rechazarla o desecharla por completo. Lo que hay que hacer es saber situarla. Es decir, tenemos que tener claro para qué sirve un cierto tipo de documento. Solo entonces le podemos dar la importancia adecuada, que puede ser mayor, menor o simplemente diferente a la de otras actividades.

En el caso que hablaba en la sección anterior, debemos tener claro que no se trata -por lo menos en este momento- de ningún documento formal o con ningún formato estricto. No es, tampoco, un documento cerrado, sino más bien una primera versión de la solución general que hemos planeado implementar y que, muy probablemente, iremos refinando y actualizando. Por eso mismo hablo de hacer algo que requiera poco esfuerzo. Pero a la vez también es una herramienta tanto para nosotros mismos ordenar las ideas que tenemos como para los demás comunicarles esas ideas.


1)
Pronto, pronto llegaremos a eso. De verdad de la buena!
2)
Estamos encerrados cada uno a un lado de un muro de metacrilato disfuso. Es imposible escribir suficientemente grande como para que se pueda leer desde el otro lado, pero sin embargo, un destello/sombra sí que es distinguible. Oh, venga, da igual el motivo. Solo es un ejemplo y es divertido hacer un sistema de comunicación en Morse!
3)
o con una pantalla
4)
o con una webcam
5)
si no las necesitáramos no las pondríamos en nuestra solución

Discusión

Escribe el comentario. Se permite la sintaxis wiki: