archivo

Archivo de la etiqueta: DSI

Comenta Kent Beck que “la planificación también es diseño”.

Si a esto le sumamos que el diseño no es solo la apariencia externa del producto, su arquitectura o en términos más teóricos, la concreción del análisis en una solución técnica, sino que también debería considerarse diseño la ejecución final del producto (es una visión más heterodoxa, pero muy en consonancia con la visión que del diseño tienen muchas personas en la industria, como por ejemplo Steve Jobs), llegaríamos a la conclusión de que la planificación y el diseño son dos elementos horizontales o transversales en el proceso de desarrollo.

Y es que la planificación lo condiciona absolutamente todo, así como las sucesivas decisiones que modifican la misma vía feedback de los desarrollos o por contingencias externas al proyecto. La planificación llega incluso al día a día, qué hemos hecho ayer y qué vamos a hacer hoy. Y si el diseño abarca desde la concepción del producto hasta la propia ejecución, se verá afectado como no podía ser de otra forma por la planificación y a su vez afectará a la misma, ya que el diseño impondrá restricciones que hará más simple o más complicado el proceso de adaptación al cambio.

Una máxima en el desarrollo de software debe ser la búsqueda de la solución más simple que satisfaga las expectativas del usuario y con la menor deuda técnica posible.

La búsqueda de esa solución no es fácil ya que implica tener una importante capacidad de abstracción, una experiencia significativa en el desarrollo de sistemas de información para el tipo de cliente y proceso de negocio con el que se está trabajando y tener la capacidad de entender que el producto final no es para que lo utilicemos nosotros, sino para que lo utilicen un conjunto de usuarios y que por tanto, su opinión resulta muy importante y se tiene que materializar en las sucesivas iteraciones del producto a partir del feedback obtenido de los mismos.

Cuando olvidamos este propósito o ponemos por encima de él nuestro espíritu creativo es cuando se corre el riesgo de entrar en este antipatrón en el que el producto gana en complejidad en proporción directa al nivel de ego satisfecho por parte del arquitecto o analista orgánico que definen la arquitectura y el diseño del sistema de información.

Defiendo absolutamente la posibilidad de que en una organización se pueda progresar horizontalmente de manera que técnicos que disfruten con la programación y con la ingeniería del software puedan tener la oportunidad de conseguir mejores condiciones laborales si su desempeño, experiencia y conocimientos les hace merecedores de ello.

Lo anterior es absolutamente compatible con una carrera profesional de índole más técnica orientada a la arquitectura del software.

Es posible que a un programador solo lo puedas vender dentro de un umbral precio/hora (es el reverso tenebroso de los proyectos tipo taxímetro o bolsa de horas), pero en proyectos donde prestas un servicio tener a desarrolladores altamente cualificados, motivados y productivos puede ser la diferencia entre ganar o perder dinero.

Un apunte: No hablo de sobredimensionar la cualificación de los equipos, ya que eso puede jugar incluso en contra del proyecto ya que puede provocar en algunos casos (proyectos de complejidad medio o baja) pérdida de motivación y de rendimiento, lo que unido a mayores costes, puede hacer que el proyecto no sea tan rentable como cabría pensar y encima tienes ocupado en el mismo a gran parte del potencial de tu organización.

Cuando el coste/hora y no la productividad es la que marca los pasos, se pueden llegar a tomar decisiones poco comprensibles como que arquitectos software o analistas orgánicos centren su esfuerzo en definir arquitecturas, frameworks o diseños y dejen a un lado el día a día de la programación.

Todos sabemos como evoluciona el mundo del desarrollo de software y eso hace que ese tipo de decisiones se consideren un antipatrón, ya que cuanto más alejado esté un arquitecto de la realidad de la codificación, más alejadas se encontrarán sus soluciones de las necesidades que pueda tener el equipo de programadores y el proyecto.

La creatividad desmesurada que nos caracteriza puede provocar que el arquitecto elija soluciones más teóricas (cuando no experimentales) que prácticas, alejando al proyecto del objetivo de simplicidad máxima que cumpla las expectativas del usuario. Este defecto lo tiene cualquiera que realice análisis, diseños o arquitecturas y empeora sensiblemente cuando se está alejado del día a día de los proyectos (un analista que no trata con usuarios y con sus problemas, tenderá a hacer soluciones más complejas).

Tal vez sea más conocido por “Esto no es la NASA”.

Alcanzar el justo medio en el análisis de una solución (ya sean requisitos, modelado de datos, arquitectura, etc…) no es sencillo, tanto es así que lo más normal es que en la mayoría de los casos nos aproximemos al mismo y exista una desviación en defecto o en exceso.

Este antipatrón se produce cuando ante una situación que requiere un análisis y en la que hay que dedicar un tiempo y esfuerzo para realizarla de manera adecuada se decide prescindir del mismo, ya que al fin y al cabo “esto no es la NASA” y tampoco es necesario una solución prácticamente perfecta.

Tan malo es intentar alcanzar algo que no se puede conseguir (la perfección) como prescindir del estudio de un problema, asumiendo que las diferentes contingencias que nos vayamos encontrando las iremos superando y que cualquier aspecto que no se haya definido tendremos conocimientos y bagaje suficiente como para completarlos por nosotros mismos (aplicando por ejemplo otros antipatrones como “el martillo de oro“, “bala de plata” o “introducción de dificultad por analogía“).

Existe la tentación, cuando se hace uso de la técnica de tarjetas CRC de aprovechar e incluir en la misma la implementación de la clase (aunque sea en pseudocódigo), convirtiéndose automáticamente la tarjeta CRC (Class-Responsibility-Collaboration) en CRCI (Class-Responsibility-Collaboration-Implementation).

Pues bien, esa práctica se considera un antipatrón, ya que se considera que se puede estar perdiendo el tiempo realizando la implementación de una clase, cuando todavía no está totalmente diseñado el sistema y por tanto no se tiene una visión todavía a nivel de detalle del mismo, lo que obligará más que probablemente a tener que rehacer la implementación especificada en la tarjeta en reiteradas ocasiones.

La utilización de tarjetas CRC (Class-Responsibility-Collaboration) es una técnica de diseño orientado a objetos propuesta por Kent Beck (introductor de la metodología de programación extrema) y Ward Cunningham (también muy conocido entre otras muchas materias, por sus aportaciones a dicha metodología).

El objetivo de la misma es hacer, mediante tarjetas, un inventario de las clases que vamos a necesitar para implementar el sistema y la forma en que van a interactuar, de esta forma se pretende facilitar el análisis y discusión de las mismas por parte de varios actores del equipo de proyecto con el objeto de que el diseño sea lo más simple posible verificando las especificaciones del sistema.

Un esquema típico de tarjeta CRC puede ser aquel en el que se indiquen los siguientes datos:

– Nombre de la clase.
– Nombre de las superclases y subclases (si procede).
– Las responsabilidades de la clase.
– Las clases con las que va a colaborar para poder realizar las responsabilidades indicadas.
– Autor, fecha, etc…

He insistido en diferentes artículos que gran parte de la suerte del proyecto se juega antes de que comience. Una mala negociación, una mala venta condiciona todo lo demás (pudiéndose partir de una situación de Death March Project) y solo produciéndose determinadas circunstancias ideales: un equipo de proyecto motivado y de calidad y un cliente y unos usuarios que facilitan las tareas, pueden paliar las pérdidas del proyecto, tangibles (en dinero), como intangibles (de pérdida de imagen con el cliente ante un proyecto de ejecución deficiente).

Sin embargo, la venta inicial del producto es solo una de las variables que condicionan el posterior desarrollo del proyecto, la elección de una mala metodología ya sea por parte del proveedor o impuesta por el cliente puede hacer estragos en el trabajo realizado, en el coste y en los resultados.

Lo mismo si no se delimita de manera adecuada el alcance (ya sea antes de la venta o antes incluso de empezar a recoger requisitos).

Y después toca el análisis. Si la metodología condiciona un desarrollo en cascada la realización de un análisis excelente es esencial, si bien, todo se puede ir al traste en el momento en que cambia algunas de las variables del proyecto (interlocutores, procesos, etc…) y es que los modelos predictivos tienen ese problema.

Si la metodología es ágil o al menos iterativa incremental (como RUP), las tareas de análisis también son de gran importancia, aunque desarrollos iterativos y evolutivos dan un mayor margen para la corrección de deficiencias en la captura e interpretación de los requisitos y en el modelado de la solución.

Por tanto, independientemente de que en función de la metodología aplicada la realización de un buen análisis tenga una mayor importancia, en todas condiciona el resto del proyecto y muchísimo.

Un mal análisis, si se detecta en etapas tardías (en muchos casos, cuando el producto ha llegado a producción), provocará un más que probable fracaso de la puesta en marcha del sistema y un más que probable esfuerzo económico importante para resolver esta circunstancia, mediante mantenimientos correctivos y evolutivos, que podrían ser incluso no asumibles si la deuda técnica del desarrollo es elevada.

Pero es que un mal diseño también tiene consecuencias y muy importantes en el resultado final del software.

Por eso destaco siempre que, además de contar con buenos programadores, disponer de buenos analistas funcionales y orgánicos permite que el trabajo de los que codifican brille más y sobre todo, sea útil.

De ahí la importancia de realizar testing desde el principio, fundamento este que dió lugar, por ejemplo a las metodologías de testing en V o en W.

En resumen, aunque muchos piensen que el partido se juega en la construcción del software, si no se han realizado de manera adecuada las etapas anteriores, el partido se habrá perdido antes de que el árbitro de el pitido inicial.

Si en el nivel 3 de CMMI se entra en el detalle de cómo obtener los requisitos resulta razonable que no ignore los procesos de diseño y construcción y de esto trata este área de proceso.

Es muy importante no caer en la trampa de definir procesos poco flexibles que no permitan una adaptación a la tipología de sistemas de información y circunstancias que pueden producirse en el desarrollo y mantenimiento de los mismos. Puede ser razonable hacerlo en entornos controlados, pero en entornos variantes (como son la mayoría) hay que establecer una serie de pautas que normalicen el proceso de diseño y construcción de manera que lo que se marque sea un camino con la suficiente anchura como para elegir dentro de él la trayectoria más adecuada al proyecto pero lo suficientemente estrecho como para tener un control de la manera en que se diseñan y construyen los sistemas.

Dentro de este área de proceso se determina en qué condiciones se deben ofrecer alternativas de solución y cuál es la información que se debe suministrar en cada caso, qué criterios utilizar para seleccionar una de ellas, qué criterios, técnicas, estrategias, precondiciones, etc… tener en cuenta a la hora de realizar el diseño del sistema, qué circunstancias se deben tener en cuenta a la hora de elegir la opción más ventajosa para obtener la solución que se demanda (comprar, reutilizar o construir), qué prácticas se deben seguir para realizar la construcción del sistema y para escribir la documentación de soporte.

¿Se basa este proceso en tener y seguir un libro blanco? Hay aspectos de este área de proceso que escapan de un libro blanco convencional, como aspectos de un libro blanco convencional que van más allá de este área de proceso, no obstante para imaginarnos qué contenido tendría un proceso como este es una buena aproximación, si bien equipararlos, tal y como acabo de comentar sería caer en el error.

El papel lo aguanta todo. Sería estupendo que todo lo que se diseña, todo lo que se imagina después se convirtiera en realidad. El problema del diseño es que después hay que ejecutarlo y el proceso real de construcción puede estar lleno de problemas que den al traste con el planteamiento inicial y/o que demuestre que ese diseño que parecía perfecto se alejaba mucho de las expectativas del usuario.

La solución a este problema no es prescindir de un diseño. El Cowboy coding no es la solución. Un proyecto sin una metodología adecuada a sus características, sin una guía que determine dónde y cómo dirigir el esfuerzo, es un proyecto sin cabeza y que solo con suerte puede salir adelante en unas condiciones aceptables y creo que, en un mundo como este, con la competencia que hay, con los presupuestos tan ajustados que existen, hay que dejar a la suerte o a la casualidad el menor pese posible.

Sobre este asunto me parece muy acertada la siguiente reflexión de Assaad Chalhoub: “El diseño sin código es solo un sueño. El código sin diseño es una pesadilla”.

¿Cuántas veces hemos escuchado al usuario comentar qué por qué el sistema le solicita una información que ya se encuentra almacenada en el mismo o por qué no le proporciona información calculada que se podría obtener con los datos ya introducidos?

Quitando aquellos casos en los que el usuario se equivoca (porque realmente el sistema no tiene almacenado los datos que él pensaba) es un problema que se produce en muchas ocasiones y que se traduce en la necesidad de un mantenimiento evolutivo del sistema.

Un buen diseño de modelo de datos es muy importante ya que permite que los datos se almacenen de forma que su posterior recuperación o su utilización para devolver datos calculados sea lo más sencilla posible. Un mal diseño del modelo de datos provocará consultas complejas para obtener aquellos datos o información más utilizados en el sistema.

Pero tan importante resulta tener un buen diseño del modelo como conocerlo de manera adecuada. A lo largo de la vida de un sistema diferentes personas habrán participado en el diseño y si no se conoce de manera adecuada dará lugar a un redundancia de datos, un incremento de la complejidad del modelo, un manejo deficiente de los datos, etc…

Sobre esto hay una cita de Rick Lemmons que viene muy bien para exponer este caso: “No hagas que la interfaz de usuario proporcione información que el sistema ya sabe”.