1.9. Análisis y diseño

El paradigma orientado a objetos es una nueva forma de pensar sobre programación y a mucha gente le cuesta al principio saber cómo abordar un proyecto POO. Una vez que se sabe que, supuestamente, todo es un objeto, y a medida que aprenda a pensar más al estilo orientado a objetos, puede empezar a crear «buenos» diseños que aprovechen todas las ventajas que ofrece la POO.

Un método (llamado a menudo metodología) es un conjunto de procesos y heurísticas usados para descomponer la complejidad de un problema de programación. Desde el comienzo de la programación orientada a objetos se han formulado muchos métodos. Esta sección le dará una idea de cuál es el objetivo que se intenta conseguir cuando se usa una metodología.

Especialmente en POO, la metodología es un campo de muchos experimentos, así que antes de elegir un método, es importante que comprenda cuál es el problema que resuelve. Eso es particularmente cierto con C++, en el que el lenguaje de programación pretende reducir la complejidad (comparado con C) que implica expresar un programa. De hecho, puede aliviar la necesidad de metodologías cada vez más complejas. En cambio, en C++ podrían bastar otras más simples para un conjunto de problemas mucho mayor que el que podría abordar usando metodologías simples con lenguajes procedurales.

También es importante darse cuenta de que el término «metodología» a menudo es demasiado pretencioso y promete demasiado. Lo que hace ahora cuando diseña y escribe un programa es un método. Puede ser su propio método, y puede que no sea consciente de ello, pero es un proceso por el que pasa cuando crea un programa. Si es un proceso efectivo, puede que sólo necesite un pequeño ajuste para que funcione con C++. Si no está satisfecho con su productividad y con el resultado de sus programas, puede considerar adoptar un método formal, o elegir trozos de entre muchos métodos formales.

Mientras pasa por el proceso de desarrollo, la cuestión más importante es ésta: no perderse. Es fácil que ocurra. La mayoría de los métodos de análisis y diseño pretenden resolver los problemas más grandes. Recuerde que la mayoría de los proyectos no encajan en esta categoría, así que normalmente puede tener un análisis y diseño exitoso con un subconjunto relativamente pequeño de lo que recomienda el método[19]. Pero algún tipo de proceso, por limitado que sea, generalmente le hará avanzar mucho mejor que simplemente empezar a codificar.

También es fácil quedarse estancado, caer en análisis-parálisis, donde sentirá que no puede avanzar porque no tiene atado cada pequeño detalle de la etapa actual. Recuerde, no importa cuánto análisis haga, hay algunas cosas sobre el sistema que no se revelan hasta el momento del diseño, y más cosas que no se revelarán hasta que esté codificando, o incluso hasta que el programa esté funcionando. Por eso, es crucial moverse bastante rápido durante el análisis y el diseño, e implementar una prueba del sistema propuesto.

Este punto merece la pena enfatizarlo. Debido a la historia de los lenguajes procedurales, es encomiable que un equipo quiera proceder con cuidado y entender cada pequeño detalle antes de pasar al diseño y a la implementación. Desde luego, cuando crea un SGBD (Sistema Gestor de Bases de Datos), conviene entender a fondo las necesidades del cliente. Pero un SGBD está en una clase de problemas muy bien planteados y bien entendidos; en muchos programas semejantes, la estructura de la base de datos es el problema que debe afrontarse. El tipo de problema de programación tratado en este capítulo es de la variedad «comodín» (el término es mío), en el que la solución no es simplemente adaptar una solución bien conocida, sino que involucra uno o más «factores comodín» -elementos para los que no hay solución previa bien entendida, y para los que es necesario investigar [20]. Intentar analizar minuciosamente un problema comodín antes de pasar al diseño y la implementación provoca un análisis-parálisis porque no se tiene suficiente información para resolver este tipo de problema durante la fase de análisis. Resolver estos problemas requiere iterar a través del ciclo completo, y eso requiere comportamientos arriesgados (lo cual tiene sentido, porque está intentando hacer algo nuevo y los beneficios potenciales son mayores). Puede parecer que el riesgo aumenta al «precipitarse» en una implementación preliminar, pero en cambio puede reducir el riesgo en un proyecto comodín porque está descubriendo pronto si es viable un enfoque particular para el problema. El desarrollo del producto es gestión de riesgos.

A menudo se propone que «construya uno desechable». Con la POO, todavía puede que tenga que tirar parte de él, pero debido a que el código está encapsulado en clases, durante la primera iteración inevitablemente producirá algunos diseños de clases útiles y desarrollará algunas ideas válidas sobre el diseño del sistema que no hace falta desechar. De esta manera, la primera pasada rápida al problema no produce sólo información crítica para la siguiente iteración de análisis, diseño, e implementación, sino que además crea el código base para esa iteración.

Dicho esto, si está considerando una metodología que contiene un sinfín de detalles y sugiere muchos pasos y documentos, sigue siendo difícil saber cuándo parar. Tenga presente lo que está intentando encontrar:

  1. ¿Cuáles son los objetos? (¿Cómo divide su proyecto en sus partes componentes?)

  2. ¿Cuáles son sus interfaces? (¿Qué mensajes necesita poder enviar a cada objeto?)

Si sólo cuenta con los objetos y sus interfaces, entonces puede escribir un programa. Por varias razones podría necesitar más descripciones y documentos, pero no puede hacerlo con menos.

El proceso se puede realizar en cinco fases, y una fase 0 que es simplemente el compromiso inicial de usar algún tipo de estructura.

1.9.1. Fase 0: Hacer un plan

Primero debe decidir qué pasos va a dar en su proceso. Parece fácil (de hecho, todo esto parece fácil) y sin embargo la gente a menudo no toma esta decisión antes de ponerse a programar. Si su plan es «ponerse directamente a programar», de acuerdo (a veces es adecuado cuando es un problema bien conocido). Al menos, acuerde que ése es el plan.

También podría decidir en esta fase que es necesaria alguna estructura de proceso adicional, pero no todo el aparato completo. Es comprensible que algunos programadores prefieran trabajar en «modo vacaciones» en cuyo caso no se impone ninguna estructura en el proceso de desarrollo de su trabajo; «Se hará cuando se haga». Eso puede resultar atractivo durante un tiempo, pero he descubierto que tener unos pocos hitos a lo largo del camino ayuda a enfocar e impulsar sus esfuerzos en torno a esos hitos en lugar de quedarse atascado con el único objetivo de «finalizar el proyecto». Además, divide el proyecto en piezas más pequeñas y hace que dé menos miedo (y además los hitos ofrecen más oportunidades para celebraciones).

Cuando empecé a estudiar la estructura narrativa (para poder escribir algún día una novela) inicialmente me resistía a la idea de una estructura, sentía que cuando escribía simplemente permitía que fluyera en la página. Pero más tarde me di cuenta de que cuando escribo sobre computadores la estructura es lo bastante clara como para no tener que pensar mucho en ella. Pero aún así estructuro mi trabajo, aunque sólo de forma semiconsciente, en mi cabeza. Así que, aunque piense que su plan es simplemente ponerse a codificar, de algún modo pasará igualmente por las fases posteriores mientras se plantea ciertas preguntas y las responde.

Declaración de objetivos

Cualquier sistema construido, no importa cuán complicado sea, tiene un propósito fundamental, el negocio al que se dedica, la necesidad básica que satisface. Si es capaz de ver más allá de la interfaz de usuario, el hardware o los detalles específicos del sistema, los algoritmos de codificación y los problemas de eficiencia, finalmente encontrará el núcleo de su existencia, simple y sencillo. Como el así llamado concepto de alto nivel de una película de Hollywood, puede describirlo en una o dos frases. Esta descripción pura es el punto de partida.

El concepto de alto nivel es bastante importante porque le da el tono a su proyecto; es una declaración de objetivos. No tiene por qué conseguirlo necesariamente la primera vez (podría tener que llegar a una fase posterior del proyecto antes de tenerlo completamente claro), pero siga intentándolo hasta que le parezca correcto. Por ejemplo, en un sistema de control de tráfico aéreo puede empezar con un concepto de alto nivel centrado en el sistema que está construyendo: «El programa de la torre sigue la pista a los aviones». Pero considere qué ocurre cuando reduce el sistema a un aeródromo muy pequeño; quizá sólo haya un controlador humano o ninguno. Un modelo más útil no se centrará tanto en la solución que está creando como en describir el problema: «Llega un avión, descarga, se revisa y recarga, y se marcha».



[19] Un ejemplo excelente es UML Distilled, de Martin Fowler (Addison-Wesley 2000), que reduce el proceso UML, a veces abrumador, a un subconjunto manejable.

[20] Mi regla general para el cálculo de semejantes proyectos: Si hay más de un comodín, no intente planear cuánto tiempo le llevará o cuánto costará hasta que haya creado un prototipo funcional. Hay demasiados grados de libertad.