Lo que no se debe hacer con el Software

Este es un informe en el cual doy mi opinión acerca de cómo no llevar un proyecto de desarrollo de software adelante y la forma de programar basándome en experiencias satisfactorias en anteriores trabajos y colaboraciones.

El porqué

Me ha tocado trabajar con una persona xxx con quien no estoy de acuerdo en dos aspectos fundamentales para el desarrollo de software como pueden ser:

  • La forma de llevar el proyecto adelante, es decir coordinar el trabajo de los programadores.
  • La forma de programar.

La forma de llevar el proyecto adelante

En el primer caso hay muchas carencias que en mi humilde opinión son imprescindibles para un correcto desarrollo del módulo o módulos que le toque a cada programador. La primera y más importante de todas es la falta de información: un programador no puede desarrollar algo que no sabe que es lo que tiene que hacer. Xxx se basa en el diagrama E-R el cual tienen acceso todos los programadores y en un documento en el que teóricamente se describe la funcionalidad de la aplicación, el cual deben leer los programadores para saber cuál es su labor correspondiente. Dicho documento no es un SRD detallado donde están todos los módulos con descripciones detalladas con sus diagramas de flujo o sus diagramas de transiciones. Por el contrario es más bien un panfleto donde hay unas pocas capturas y muy por encima se comenta la funcionalidad general más bien orientada al usuario.

Si tenemos en cuenta que no se celebran reuniones entre el cliente y los programadores o entre los programadores y el coordinador y la única vía de comunicación es el documento la incertidumbre por parte de los programadores está garantizada: interpretaciones ambiguas, cosas a desarrollar poco claras, lagunas, etc. Esto es evidente que genera:

  • Pérdida de tiempo pensando que es lo quiere realmente el ingeniero releyendo el documento una y otra vez.
  • Pérdida de tiempo refactorizando cosas que se han desarrollado erróneamente por no tener claro que quería el ingeniero debido a ambigüedades.

Por eso propongo basar nuestro documento en un Documento de Requisitos de Software en el que a partir de unas reglas para elaborar el documento se desarrolle el mismo. No necesariamente tiene que ser el estándar, pero si hay cosas que son imprescindibles y que en el nuestro brillan por su ausencia las cuales se enumeran a continuación:

  • Requisitos funcionales: cada módulo especificado muy por encima con seudocódigo o lenguaje natural.
  • Descripción detallada del modelo (no solamente el modelo E-R), es decir si es una biblioteca y estamos con los libros, si hay alta, baja, modificaciones, consultas así como los diagramas de estados y datos.

Luego se podría mejorar o cambiar este documento agregando más detalles, pero a mi parecer eso debería ser como mínimo para evitar confusión.

La forma de programar

Xxx desarrolló un framework basado en la arquitectura mvc y si bien respeta dicha arquitectura no respeta los principios fundamentales de programación que son abstracción y modularizacion por lo que tenemos un código lineal sin métodos, sin encapsular nada (salvo el modelo).

Los actions de los controladores son archivos sueltos y al no estar encapsulados, están llenos de ifs hasta dar con la condición acertada y meter ahí un nuevo include que será la vista que vea el usuario, lo cual es un claro indicio de un diseño deficiente.

Como se ve todos los action están haciendo la función de dispacher. Esta lógica no debería estar en cada action, que son los métodos de los controladores que llaman a una vista o a un proceso, si no que se debería hacer uso de la herencia y/o composición y crear una clase encargada de esto la cual llame al controlador que le corresponda. El controlador xxx será el que implemente el action que corresponda. Por ejemplo si tenemos el controlador Usuario, tendrá un action que se llame listar, otro editar, otro nuevo, etc. Estos métodos se encargan de una tarea específica de Usuario por ejemplo listar: que llamará al modelo y pedirá los usuarios, estos usuarios se los pasara a la vista correspondiente y en esa vista se mostraran los usuarios, esa es la manera correcta de hacerlo. De esta manera al agregar un controlador lo único que hay que hacer es crear el controlador y crear la vista, sin duplicar código, sin copiar y pegar en cada action los tropecientos ifs e includes de código sin encapsular y sobre todo: sin tener el conocimiento de cómo funciona el dispacher, al controlador no le interesa. Esta técnica se llama composición en OOP que no deja de ser abstracción.

El no encapsular

Todo el diseño puede hacer sin OOP, se complicaría un poco pero se podría, eso si hay que encapsular en métodos (abstracción funcional) porque si no se hace se tiene código spaguetti que según Wikipedia es:

El código espagueti es un término peyorativo para los programas de computación que tienen una estructura de control de flujo compleja e incomprensible. Su nombre deriva del hecho que este tipo de código parece asemejarse a un plato de espaguetis, es decir, un montón de hilos intrincados y anudados.

Tradicionalmente suele asociarse este estilo de programación con lenguajes básicos y antiguos, donde el flujo se controlaba mediante sentencias de control muy primitivas como goto y utilizando números de línea. Un ejemplo de lenguaje …

Nótese que he resaltado un montón de hilos intricados  y anudados y goto. En efecto es muy difícil de seguir porque hay que empezar en la línea 1 y acabar en la línea que se quiere modificar cada vez que se quiere debuguear o cada vez que se quiere mantener. En cuanto a goto se ha resaltado porque es similar al problema de los ifs con los includes: hay que ir saltando por todos los ficheros incluidos.

El otro problema de la no encapsulación es que se corre el riesgo que muchas variables se usan en las primeras líneas de código y luego se usan más abajo. Claro si no hay encapsulado cualquier parte de los cientos de includes que hay a lo largo y ancho de nuestro plato de spaguettis puede estar modificando el contenido de la variable sin que lo note el programador.

El lado oscuro del conocimiento

Lo comentado en el párrafo anterior es simple y llanamente por la falta de abstracción, lo que deriva en que hay que conocer cómo funciona todo el software, por ejemplo el caso de la variable: supongamos que tenemos una variable que se llama url la cual es del propio framework  y nosotros como programadores nos mandan hacer una modificación que permita actualizar la lista de usuarios que puede que contenga un atributo url , pues fácil url = “ lo que sea” y chachan programa roto y no sabemos porque , porque no he desarrollado el framework o no me acuerdo, que hay una variable que se llama url para hacer funcionar mi aplicación y que estoy sobrescribiendo. La consecuencia directa de esto es debugguear código, con la pérdida de tiempo que ello supone.

El acoplamiento

Al no haber encapsulamiento el acoplamiento es máximo, es ya a nivel de control. Como se ha expuesto los módulos son difíciles de extender, depurar y modificar con la consecuencia del acoplamiento alto: una modificación en uno de ellos afecta bastante el resto.

La falta de Cohesión

Cada action en nuestro framework no lo podemos describir con una simple frase de un verbo por ejemplo “imprime los usuarios”, cada action en nuestro caso, hace muchas cosas con lo que tenemos un hibrido de cohesión baja del tipo secuencial , temporal y coincidental.

Comprensibilidad

La alta cohesión y el bajo acoplamiento es lo que favorece la compresión del código para futuros programadores que trabajen en dicho proyecto. Esto favorece que:

  • Haya una identificación univoca de la entidad o método
  • Que la documentación sea más concisa, por ende se leerá con detenimiento
  • Simplicidad: los algoritmos largos son difíciles de entender y modificar

Es poco producente que lleve el mismo o más tiempo tratar de entender el código hecho que el desarrollo de la nueva actividad.

Conclusión y propuesta de mejora.

Se propone un diseño orientado a objetos del framework basado en patrones de diseño que subsane todos los puntos débiles previamente resaltados. Para dicho diseño se tendrá en cuenta la extensibilidad y escalabilidad del mismo así como la fácil comprensión por parte de los futuros programadores.

El dispacher se hará fuera del controlador como debe ser para evitar baja cohesión y alto acoplamiento entre el controlador y dicha tarea.

Los controladores serán clases y los actions serán métodos públicos de estas lo que favorecería la comprensión, escalabilidad y mantenibilidad así como un bajo acoplamiento entre las tareas que son propias del controlador a otras que son propias del framwork. Recordemos que el diseño actual cada vez que se quiere agregar una funcionalidad , hay que copiar y pegar la lógica de dispacher a cada action.

Esto hace que el programador que esté realizando un mantenimiento ya sea correctivo, adaptativo o perfectivo no tendrá que leer todo el código del framework si no que trabajara en su módulo específico básicamente porque no le haría falta.

El modelo quedaría igual, está bien estructurado en clases siguiendo un diseño Orientado a objetos coherente.

Resultados y satisfacción con el cliente

No puedo opinar la satisfacción con el cliente ya que es un organismo público y nunca he participado en reuniones con él.

En cualquier caso puedo afirmar:

Mi primer trabajo en esa empresa fué realizar un mantenimiento correctivo en un proyecto ya con algunos meses en funcionamiento con dos consecuencias importantes debido a la mala praxis del código:

Dedicar mucho tiempo a aprender todo lo que hace el programa completo, es decir leer el código spaguetti y debuguear. Todo este tiempo viene dado por las razones expuestas anteriormente que son poca comprensibilidad debido al alto acoplamiento y baja cohesión . Además debido al alto acoplamiento cada vez que modificaba algo, rompía por muchos sitios y muchas veces con errores no visibles, por ejemplo el caso de la variable comentado anteriormente, por lo que tenía que probar todas las operaciones una y otra vez. No podía aislar el modulo y probar contra ese modulo que tenía que reparar porque simplemente no lo había.

Finalmente la pobre documentación del proyecto.

Que conste que en un buen diseño, no es necesario saber cómo funciona todo el programa, sino que lo normal es que solo baste saber que tiene que hacer un módulo ( que puede ser una clase , o conjunto de ellas) .

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s