Tag Archives: desarrollo

¿Qué se busca conseguir en un desarrollo?

La respuesta rápida y obvia podría ser: que lo desarrollado cumpla con los requisitos pactados.

La realidad, muchas veces, nos demuestra que esto no su cumple, ya que, o los requisitos pactados se engordan, o nos fijamos más en que se cumpla el tiempo pactado, lo cual realmente no es un requisito, en muchos casos. Al final, parece que premia más el tiempo invertido y el dinero gastado que lo que se ha adquirido.

Imagina que vas a comprar unos pantalones, quieres unos pantalones para diario, simples, pero dado que es invierno, que te los puedas pasar sin pasar frío. Ese es nuestro valor a conseguir. Si vamos a comprar los pantalones y hablando con el encargado los pedimos: que sean azules oscuros, con un diseño radical, moderno, de mi talla, … ; quizás al final tengamos unos pantalones que sean como unas mayas… ¡a ver quién se las pone en invierno!, pero claro, por el dinero que dábamos, lo que pedíamos, y el tiempo que le dábamos al encargado para que los buscase… pues es normal.

En desarrollo de software pasa igual. Al principio, el cliente tiene la idea de un software, por ejemlo, para gestionar su almacen. Después piensa que, si se va a invertir mucho tiempo en su desarrollo, entonces puede pedir que venga con sistema de nóminas, contabilidad, gestión de pedidos a mayorista y generación de facturas a clientes… y por el camino, mientras ve algunos proyectos de portfolio, pues se le ocurre pedir también un sistema de carro de compra para internet… y todo eso en el tiempo que se tiene para hacer solo la primera idea… ¿saldría bien?… ¡no!

Volviendo a la pregunta inicial, la respuesta después del planteamiento desarrollado, sería, más concretamente: busco que resuelvan un problema específico que tiene mi empresa, el cual no le permite crecer al ritmo que queremos que crezca.

Por ello, el desarrollo de una aplicación de software debe realizarse siempre con la idea clara en mente de que, el desarrollo, va a cubrir una necesidad detectada, o a automatizar una tarea, que ya se realiza, pero se necesita realizar de forma automática para que los trabajadores puedan realizar más tareas a lo largo de un día. Si el software desarrollado no cumple esta espectativa, no solo no aporta valor, sino que es posiblemente un lastre para la empresa.

Cuánto cuesta un Proyecto de Software

Hoy ya hace unas semanas que en la empresa en la que trabajo se ha comenzado un movimiento positivo en favor de medir lo que cuesta realizar desarrollos de software, dentro del departamento de desarrollo, lo cual es positivo desde el punto de vista del desarrollador, del programador y de los directivos.

Hay que tener siempre presente que, cuando se realiza un trabajo, ya sea el que sea, si lo realiza una persona ajena, no de la empresa, se paga una factura por sus servicios, en los que viene detallado, normalmente, la mano de obra, que suele cobrarse en factor de tiempo empleado.

El coste asociado de emplear a una persona que está en nómina, dentro de la propia empresa, puede ser menor, pero no cero. Si un empleado cobra en bruto unos 2000 euros mensuales y le mandamos hacer un trabajo para lo cual gasta todo un mes, es de lógica pensar, que ese trabajo me ha costado esos 2000 euros, ya que es lo que ha hecho el empleado. Si el proyecto al final solo hace ingresar a la empresa 200 euros, la empresa ha perdido con ese desarrollo 1800 euros.

En el caso de que un proyecto se desarrolle en dos semanas de ese trabajador, por redondear, damos que son 1000 euros el coste y se consiguen 1200 euros. La empresa ha conseguido con su labor 200 euros… pero si el desarrollo ha sido deficiente, por el poco tiempo empleado, y el programador tiene que ir invirtiendo horas, que al final resultan ser días (en suma) y llegan a ser otras dos semanas, tendremos que esos 200 euros se convierten en 800 euros de pérdidas.

El las metodologías ágiles se hace hincapié a dar valor, es decir, realizar el desarrollo por iteraciones, siempre haciendo lo que más valor dé al cliente. Por ejemplo, si tenemos 10 requisitos en un proyecto, impuestos por el cliente, pero los más importantes son los 2 primeros, podemos negociar con el cliente el hacer esos dos primeros, valorarlos con el tiempo que toma el realizarlos y, en caso de querer el resto de requisitos, o algunos más, volver a realizar otra petición.

¿Qué conseguimos con esto?

  • Que el cliente pida lo que necesita, únicamente.
  • Que el precio que se pague sea el justo y necesario, e incluso no muy desorbitado para el cliente.
  • Que la estimación de tiempo sea más ajustada a la realidad, siendo los plazos de desarrollo más cortos.
  • Que el cliente consiga su producto, su valor, antes.

Por lo que recomiendo a todos los que trabajan en nómina en una empresa, y su jefe (o siendo jefes) no se lleven el cómputo de horas invertidas en proyectos, incidencias, etc., que lo hagan, porque es una moneda de cambio muy útil para cuando se quieren conseguir cosas importantes, dentro de la empresa.

¿”Ingeniería” del software?

El creador de menéame, Ricardo Gallí, escribió hace unos días un artículo en su blog bastante interesante sobre lo que respecta a la llamada Ingeniería del Software. Ricardo sostiene que el título de “ingeniería” ha sido dado de forma errónea al desarrollo de software y, en muchos aspectos, tiene razón.

Rescato la lista que él mismo recopiló de Tom DeMarco, sobre un artículo de opinión publicado bajo el título Software Engineering: An Idea Whose Time Has Come and Gone? (Ingeniería del Software: ¿Una idea cuyo tiempo pasó?), hablando de su libro:

Controlling Software Projects
T. DeMarco; Prentice Hall PTR 1986

  • Hoy en día todos comprendemos que las métricas de software cuestan dinero y tiempo, y que deben ser usadas con moderación.
  • El desarrollo de software es inherentemente diferente de las ciencias naturales tales como la física, por lo que sus métricas son mucho menos precisas para capturar lo que deben describir.
  • La frase más citada del libro es No puedes controlar lo que no puedes medir. Esta frase contiene una verdad real, pero cada vez me sentía más incómodo con el uso que hice de ella. Está implícita en la frase (y en título del libro) que el control es un aspecto importante, quizás el más importante, de cualquier proyecto de software. Pero no lo es.
  • Muchos proyectos se han realizado sin demasiado control pero han generado productos maravillosos tales como Google Earth o la Wikipedia.
  • Esto nos lleva a la desagradable conclusión: el control estricto es algo que importa mucho en proyectos relativamente inútiles y mucho menos en proyectos útiles. Sugiere que mientras más te enfoques en el control aumenta la probabilidad de que estás trabajando en un proyecto que se esfuerza por generar algo de valor relativamente menor.
  • ¿Estoy diciendo que está bien ejecutar proyectos sin control o con un control relativamente menor? Casi. Estoy sugiriendo que deberíamos seleccionar primero los proyectos cuyo control preciso no importe demasiado.
  • Estoy llegando gradualmente a la conclusión: el momento de la ingeniería del software vino y se fue.
  • En los últimos 40 años nos hemos torturado por nuestra ineptitud en acabar proyectos a tiempo y con el presupuesto previsto. Pero como sugerí antes, no debería haber sido el objetivo supremo.
  • El objetivo más importante es la transformación, crear software que cambie el mundo, o que transforme una empresa, o la forma en que se hace negocio.
  • El desarrollo de software es y será siempre algo experimental. Lo construcción real de software no es necesariamente experimental, pero sí lo es su concepción. Allí deberíamos enfocar nuestros esfuerzos. Allí es donde deberíamos haberlo hecho siempre.

Esto nos indica que el software debe de realizarse con un fin concreto, con una utilidad en mente y, el hecho de prefijar, fijar o realizar unos requisitos sobre él, no son más que el ejercicio de la práctica y las necesidades reales que quieran cubrirse de forma eficiente. Cambiando algo significativamente.

Otro aspecto que se enfatiza es el tema del control. ¿El control excesivo es perjudicial para un proyecto de “ingeniería” del software?

Lo que es casi obvio para la mayoría de profesionales, es que el desarrollo de proyectos en cadena es bueno emplear metodologías tradicionales, puesto que son cosas que se han podido medir durante mucho tiempo, no suelen cambiar mucho y se realizan siempre de la misma forma. E igualmente, el equipo humano, su creatividad y destreza no son tan importantes como el procedimiento marcado para realizar el programa en el tiempo estimado.

Por otro lado, los proyectos a medida, que se realizan con una especificación de requisitos variable y que pueden ir modificándose en el tiempo con la necesidad del cliente, requieren de otro tipo de metodologías que den otro tipo de control a los desarrolladores y mayor libertad a los programadores. En este caso sí es muy importante que los desarrolladores (analistas) sepan cercanamente lo que se hace y cómo se hace, que sepan lo que cuesta realizar el trabajo y, sobre todo, que sean los programadores los que digan lo que van a tardar en cada tarea. Aproximadamente.

Esta última forma es el que más proyectos genera para la industria de creación de software y, dado que la llamada ingeniería es tan liviana en este caso, quizás sí, quizás el nombre no sea todo lo acertado que debiera… quizás necesitemos otro nombre para nombrar lo que hacemos.

Lo justo y lo estándar

Desde hace unos meses, he estado envuelto en algunos proyectos, en los que he intentado dar un enfoque basado en patrones y estándares, para facilitar y simplificar los problemas. Solo que, hay patrones y sistemas, o frameworks, que son algo incompatibles entre sí.

Por ejemplo, el uso de un sistema BPM, puede ser compatible con un sistema REST como Ruby on Rails, mientras se mantenga la idea de REST… en cambio, si se modifica por intentar realizar un poco interoperatibilidad entre otros sistemas, a los cuales no se les quiere cambiar mucho la forma… se convierte en un infierno.

Al final, lo mejor, es mirar la piezas con las que queremos contar, por ser afines a los resultados que queremos obtener y, emplear única y exclusivamente, los patrones que se puedan ajustar bien a esas piezas.

En este caso, por ejemplo, Ruby on Rails, combina bien con sistemas BPM que sean REST, e incluso con bases de datos que sean REST, pero le quita características bastante deseables que sí tiene otro patrón como ActiveRecord, ante lo cual, se establece un sistema de preferencias y prioridades… ¿REST o ActiveRecord?… como es lógico, optando por ActiveRecord, desaparece BPM como tal, ya que ActiveRecord está hecho para su acceso directo a base de datos.

Pero al final, la base de datos, bien mirada, termina siendo nuestro sistema BPM y, con ayuda de procedimientos almacenados, triggers, usuarios y demás… es un sistema, no tan potente como otros, pero sí lo suficiente como para cumplir con las especificaciones básicas.

Bueno, al final, me doy cuenta de que, al igual que cuando se programa, se debe de decidir bien la estructura, los elementos a emplear, la forma y demás… cuando se desarrolla, se ha de tener especial cuidado con las metodologías, patrones de diseño y estándares, puesto que hay que comprobar que coordinen bien entre sí.

La liebre y la tortuga

En este cuento voy a intentar explicar lo que significa programar rápido y lo que significa programar de forma ágil. La primera forma sería la que se considera comenzar lo antes posible, para terminar lo antes posible… pero ciertamente, sin planificación, dar palos de ciego a ciertos niveles de implementación, es más lento que planificar la estrategia de desarrollo a priori. Vamos a verlo con el cuento de…

La liebre y la tortuga

En Silicon Valley, había un programador tan rápido que podía escribir cientos y miles de líneas de código en cuestión de pocas horas, trabajaba rápidamente y, por ello, era conocido como la liebre. Aunque era un poco alocado, se lanzaba directamente a programar y no planificaba bien los proyectos.

No obstante, todos lo admiraban por lo rápido que hacía aparecer código en tan poco tiempo.

Por otro lado, estaba otro programador, algo más lento, que planificaba en papel y lentamente todos sus desarrollos, con lo que en un día obtenía muy pocas líneas de código. Este programador era conocido, por esto mismo, como la tortuga.

La liebre y la tortuga trabajaban en la misma empresa y, ante la fuerza que la admiración del resto ejercía sobre el primero, por su característica totalmente opuesta a la del segundo, la liebre instigaba e intentaba siempre perjudicar a la tortuga.

En la sala de trabajo, un día, cuando la tortuga ya se cansó de tanta hostilidad, aprovechó la oferta de un trabajo de programación importante, con un nivel de desarrollo importante y grande, para retar a la liebre: tú que eres tan rápido, te desafío a desarrollar este programa más rápido que yo.

Toda la sala quedó estupefacta, salvo el director de proyectos, que disimuladamente sonrió, agregando: sería interesante verlo. A lo que el resto de la sala agregó más risas.

El director de proyecto se dirigió a la liebre y le preguntó: ¿serías capaz de desarrollar este proyecto en menos tiempo que la tortuga? A lo que la liebre respondió sin dudar: ¡claro que sí! Pues os doy a ambos una semana para el desarrollo del proyecto, quien antes lo termine cumpliendo con los requisitos especificados, será el ganador.

La liebre comenzó a reir, aceptó el trato, al igual que la tortuga y fue a seguir riendo con sus compañeros durante largo rato mientras la tortuga marchó a su puesto de trabajo. La tortuga analizó el proyecto e inmediatamente localizó una serie de patrones claros que seguir, tomó los requisitos y trazó los diagramas que le harían cumplir con los mismos de la mejor forma, para seguir con una planificación ajustada al tiempo que tenía para cumplir con el proyecto. Se puso manos a la obra y comenzó el diseño.

Mientras tanto la liebre, se tomaba su tiempo y, mientras hablaba con sus compañeros decía: si ya sé cómo lo voy a hacer, es una chorrada de proyecto, ¡muy fácil!

En el segundo día, la tortuga terminaba su diseño con diagramas de UML, marcaba la división y los patrones que integrarían cada una de las clases, así cómo los detalles del diseño de interfaz y otras características a tener en cuenta en diagramas de secuencia.

Al tercer día, la liebre comenzó a codificar, en poco tiempo, tenía un trozo de código que cumplía los primeros requisitos y reía a gusto creyendo saber que conseguiría su propósito. Mientras, la tortuga, acababa de sentar el esquema de clases y la estructura básica, la arquitectura de soporte y preparaba todo para comenzar la codificación al día siguiente.

En el cuarto día, la liebre comenzó a encontrarse los primeros problemas, algunos requisitos chocaban directamente con muchas de las partes ya desarrolladas y en funcionamiento, así como datos ya implementados en la base de datos, con lo que se veía obligada a rehacer la estructura de datos, eliminar todo el código que no le servía y volver a escribir código nuevo. La tortuga comenzaba la codificación con la estructura de clases autogenerada por las herramientas CASE que usaba y trazaba las líneas de código de acceso a datos y lógica de negocio, escribía las pruebas unitarias para asegurar que todo salía bien y seguía adelante.

El quinto día, para la liebre, comenzaba el stress, la desesperación, se acerca el final del proyecto, aún no están todos los requisitos y se han vuelto a encontrar problemas. Como no hay una visión global, no sabe cuantos problemas más puede llegar a encontrar y, para los ya encontrados, la recodificación es algo pesada. Con lo que parece que solo lleva, de forma constante la mitad del proyecto. Por otro lado, la tortuga ha terminado la parte de lógica de negocio y manejo de datos, así como la parte de seguridad y acceso, el controlador, con lo que solo le restan las vistas, con las pruebas funcionales para acabar el proyecto.

El sexto día, cuando se había previsto la entrega del proyecto, la liebre había pasado toda la noche en su puesto de trabajo, intentando, con chapuzas, terminar a tiempo el proyecto, haciéndolo de forma muy deficiente y sin probarlo. Sin embargo, la tortuga, ya acababa la vista, haciendo siempre la ejecución de las pruebas de regresión para probar la integración de cada una de las partes, junto con las funcionalidades pedidas y el entorno en sí.

A la entrega del proyecto, la liebre presentó un proyecto con fallos, que no terminaba de funcionar y que tenía implementados los requisitos solicitados de forma dudosa, mientras que la tortuga entregaba un proyecto bien pensado, con un resultado limpio y funcional.

Ante los resultados, el director de proyectos se dirigió a la liebre y le dijo: no es cierto que es más rápido quien más rápido programa, sino quien, con menos código y menos trabajo, consigue hacer lo mismo en menos tiempo; y con ello, la tortuga ha demostrado, que es más rápido que la liebre.

Conclusión: usar metodologías ágiles acelera realmente el desarrollo, porque optimiza el proceso de creación.

Pruebas Unitarias

Después de haber estado adentrándome en TDD, muy poco a poco, he visto que el primer paso para hacer más fácil esta doctrina, son las pruebas unitarias.

Las pruebas unitarias son pruebas que se realizan sobre unidades aisladas de código, generalmente objetos, para asegurar que, con unos ciertos valores de entrada, siempre se reciben los mismos valores de salida, o los valores de salida que se esperan.

Para implementar las pruebas, según el lenguaje que se use, existen las siguientes librerías o métodos:

  • Java: el proyecto junit podría considerarse el primero en tener este tipo de framework para realización de pruebas, es de los que más activo tienen su desarrollo, la última versión publicada es de hace unos meses.
  • C: el proyecto CUnit no se actualiza desde 2006, pero parece que el desarrollo quedó muy avanzado y es útil para realizar las pruebas.
  • PHP: el proyecto PHPUnit se sigue actualizando y sigue creciendo poco a poco, es bastante maduro y apto para su uso en proyectos de PHP, ya sean de la versión 4 ó 5.
  • Ruby: el nombre del proyecto para ruby, a diferencia del resto, es Test::Unit. En este caso se presenta como un módulo para la realización de pruebas unitarias. Esto es porque en Ruby, no solo están disponibles este tipo de pruebas, sino también pruebas funcionales y de integración… pero eso será otro tema ;-) . El uso del módulo resulta muy similar al resto de frameworks.
  • Python: el proyecto recibe el nombre de PyUnit. Este proyecto hace tiempo que no recibe actualizaciones, pero está en un estado maduro. En su página se dice que se usa para las pruebas de Zope, que es, posiblemente, la mayor pieza de código escrita en python.
  • Perl: en las instalaciones desde CPAN, para instalar módulos de Perl, siempre que se descarga el módulo se ejecutan las pruebas unitarias del mismo, para asegurarse de que se cumplen todas las dependencias y que el código, en ese entorno, reacciona como se espera. El proyecto es PerlUnit.

En la mayoría de casos, cada uno de los proyectos ha sido motivado por junit, con lo que el uso, la ideología y la forma de trabajar es muy similar.

Ahora, después de comentar los proyectos, vamos a comentar lo que realmente importa, las ventajas:

  • Pruebas exhaustivas: el desarrollo de pruebas unitarias tiene como ventaja principal que el código se prueba con datos planteados con detenimiento e intentando cubrir todos los casos posibles, por lo que, es muy útil para descubrir si nuestro software cumple con las especificaciones marcadas (requisitos).
  • Facilita el probar reiteradamente: es decir, si necesitamos realizar pruebas sobre un componente, y ese componente no reacciona como esperamos, en lugar de ir alimentando la entrada de datos cada vez que lo probemos, podemos realizar una batería de pruebas específicamente para él, e incluirlo en la batería de pruebas global.
  • Fase de Calidad: el agregar las pruebas unitarias y ejecutarlas al final, cuando ya se ha terminado de desarrollar el código, no indica que el código sea infalible, pero si las pruebas se han desarrollado cubriendo todos los casos de uso triviales y posibles fallos que se puedan suceder, asegura que el código funcionará como se espera.

Por tanto, el desarrollo de estas pruebas, ya sea a priori, como indica TDD, o a posteriori, como elemento de QA (quality asurance, garantía de calidad), o ambos, resulta una herramienta indispensable que nos puede ahorrar la mayor parte de incidencias que se abren una vez el proyecto está en producción o entregado al cliente.

REST: Representational State Transfer

Después de haber usado durante unos años sistemas RPC para la compartición de la información, XML-RPC, SOAP y Elm; llego a REST, un concepto que mencionó primero un compañero de trabajo, Juanse, y después vi en profundidad en un curso de Ruby on Rails que se organizó en la empresa en la que trabajo (gracias Dani por ese curso tan completo).

El sistema REST se basa en usar las entidades de datos como recursos. Por ejemplo, si tenemos usuarios y queremos hacer un sistema de gestión de usuarios, mediante una URL, podemos establecer el recurso como:

http://bosqueviejo.net/users

Este recurso será accedido por HTTP, mediante el método GET, lo cual retornará, en formato serializado (XML, JSON, YAML…) la información solicitada, el listado de usuarios. También podemos especificar, mediante la agregación de un identificador, en la URL, que solo queremos un usuario concreto:

http://bosqueviejo.net/users/admin

Como se puede apreciar, el sistema de localización, es claro y limpio.

Lo más interesante viene en las siguientes acciones. Para hacer una agregación a la lista de usuarios, es decir, para insertar o agregar un nuevo usuario, se puede emplear la misma URL, agregando los datos como cuerpo del mensaje HTTP y usando el método PUT.

Por ahora, no tenemos novedades con respecto al uso estándar de los sistemas web, ya que la petición de páginas se realiza mediante GET y el envío de formularios a través de POST. Sin embargo, para las acciones de inserción, por ejemplo, se emplea PUT, con la misma dinámica que POST, solo que reacciona como una actualización sobre los datos existentes, por lo que, la URL que se usará, deberá de ser de la segunda forma que se vió anteriormente.

Por último, para eliminar un dato, usando la URL concreta como en el caso de PUT y POST, pero empleando el método DELETE, se indicará al sistema REST que se desea eliminar el recurso solicitado.

Las ventajas que ofrece este sistema son claras. Al hacer uso de los métodos de HTTP, el servidor web puede ser usado a nivel de autenticación para restringir en modo todo o nada la modificación, eliminación y agregación de recursos a usuarios no autenticados o a ciertos usuarios, e incluso, en concordancia con la raíz de URL, limitar el acceso a ciertos recursos, con ciertos métodos, etc. Además, a nivel de log del sistema web, se tienen datos más concisos sobre el acceso y uso del sistema.

Los inconvenientes son que las acciones tienen que ser muy específicas y, para las cadenas de búsqueda, se hace necesario el uso de los parámetros de URL, lo cual hace que no quede tan claro y limpio el sistema.

Este sistema, bien usado, constituye un punto de partida muy válido para la comunicación con sistemas BPM y la instauración de sistemas de consulta tan potentes y configurables como SQL.

Business Process Management

Según se puede ver en la definición de la wikipedia BPM es una metodología empresarial cuyo objetivo es mejorar la eficiencia a través de la gestión sistemática de los procesos de negocio.

Cuando una empresa tiene una actividad comercial, por ejemplo, basada en un almacén, con varios sistemas que requieren acceder a la base de datos para su manipulación (administrativos, atención al cliente, empleados de almacén…), cada uno con una misión específica, se deben de centralizar esa actividad de alguna forma para no caer en el problema de repetirnos a nosotros mismos (incumplir DRY) codificando una y otra vez lo mismo en varios programas distintos.

Un sistema BPM muy arcaico y con posibilidad de error es el SGBD. Si se usa un sistema que pueda almacenar procedimientos y se detallan un conjunto de ellos para uso de los usuarios, propiamente dichos, se puede sistematizar bastante el sistema. Pero SQL no está del todo bien diseñado para mantener un nivel de seguridad, abstracción y acceso para toda una jerarquía de empleados. No sería imposible, no obstante, pero sí muy complicado de implantar y casi imposible de mantener. Además de la incidencia en el rendimiento que ello conllevaría.

BPM se suele implementar con el uso de SOA, las arquitecturas orientadas a servicios, las cuales le dan un soporte ideal mediante el uso de servicios web o sistemas RPC.

Por lo tanto, para tratar los datos, con acceso controlado, inteligencia de negocio y un desarrollo de esta capa de forma más fácil, en ciertos lenguajes se facilitan empleando sistemas como servicios web mediante protocolos como XML-RPC, SOAP o similares.

Centrar todos los procesos de negocio en un sistema de servidores con acceso RPC de algún tipo, con todas las funciones de negocio disponibles con acceso por máquinas que usan esa inteligencia y desarrollan una actividad de interfaz basada en usuarios u otros sistemas superiores.

A este respecto, C tiene implementaciones tan antiguas y aún usadas como Tuxedo; Java tiene sus EJB en servidores de aplicaciones tales como JBoss, Glassfish, Weblogic, …; Python tiene como servidor de aplicaciones a Zope; etc.