viernes, 24 de enero de 2014

Agregando lógica de negocios a una aplicación existente.


Post-Análisis, como herramienta para analizar mejor una nueva funcionalidad.

Como punto de arranque y a modo de entrenamiento toma una funcionalidad que hayas implementado a un sistema existente, una específica, la mas clara que tengas, analízala, mira qué hiciste para llevarla a cabo, qué pudiste haber hecho mejor, y muy importante: qué usa el cliente dentro de todo eso que le diste con tanto detalle y lujo: quizá use el 20%. Eso se llama: "post-análisis de casos de uso".

Enfrentas una nueva lógica de negocios a ser aplicada a un sistema existente.

Cuando has hecho este post-análisis entonces serás cada vez mas capaz de hacer un pre-análisis (un análisis) de lo que el cliente quiere, teniendo las reglas de negocio claras, harás una planificación en papel y pizarra (sin estruendosas aplicaciones de planificación, a mano) y solo cuando tengas las reglas de negocio muy claras te darás cuenta que puedes proveer al cliente de una solución entregándola a la aplicación en forma de extensión (y ahí entra Yii), te darás cuenta que todo lo que has analizado es "comprobable" y ahí entra TDD.

Cuando haces un sistema o implementas una lógica de negocios a la aplicación existente y no aplicas éste esquema de análisis al cual me refiero en este post entonces se esta enfrente de un adefesio, un software monolítico, una pieza que no es extensible y que a duras penas podrás ser hecha en colaboración, y menos aun con TDD.

Es orientada a objetos ? de verdad ?

No se trata de crear una "clase" y meterle 500 metodos, luego inyectarle un ruidoso TDD para decir que tu aplicación "es" orientada a objetos. No lo es, es un adefesio, quizá duela pero yo también alguna vez las hice así y se muy bien cómo hacer un adefesio y cómo hacer una aplicación bien organizada.



TDD (Test Driven Development)


TDD no es algo "raro" ni algo a que temer. TDD tampoco es "una cosa que se hace con Eclipse" ni tampoco se aplica de una sola manera.  Como bien dice el nombre es: Test Driven Development, o Desarrollo Guiado por Pruebas, es muy claro el objetivo de TDD.


TDD implica que harás la nueva lógica de negocios pensando en piezas verificables una a una y luego una contra la otra.  El objetivo final es que todo pueda verificarse mediante un programa de pruebas, este programa no es sino un nuevo programa que construyes para que pruebe la extensión que estas fabricando.


TDD es análogo a cuando en una fábrica hacen un motor. Tantas piezas que tiene el motor, quiza todas de primera, pero en conjunto cómo funcionan ? se recalienta el motor ? se quema ? se prende en candela y explota ? Porquee !! si todo funcionaba de maravillas, dirías.  Tu aplicación de pruebas o programa de pruebas es análogo a conectar al motor en un banco de pruebas (siendo tu programa de pruebas la analogía a este banco de pruebas del motor).  Se diseñan pruebas en dos niveles basicamente:


Pruebas unitarias, que verificarán que funciones básicas hacen lo que se espera. Debes construir varios casos para probar cada función, aunque esto no garantice que "el motor no se prenda en fuego", al menos tienen un objetivo claro: "saber que las funciones hacen lo esperado". Es análogo a que en tu banco de pruebas del motor de ejemplo tengas un "tester electrónico" que verifique que la corriente no pasa de 10 amperios, pero solo hasta ahí.

Pruebas funcionales, que prueban todo el conjunto, verifican estados, cómo todo anda en conjunto. Es análogo a que en ese banco de pruebas del motor ficticio al que me refiero antes hagas un cableado que supla un encendedor para el motor, un acelerador y un termómetro. Quizá este cableado que suple estas interfaces para probar el motor no sea el que llevará el motor en su implementación final, pero aseguran que: el motor enciende cuando se le pide, que acelera y que no se calienta.

Cómo detectas un error con TDD ?



Generando excepciones:  throw new Exception("error");  , simplemente la siguiente prueba no se ejecuta hasta que no repares la que genera el error.


Ejemplos:

1. El siguiente archivo de código muestra cómo se hace un banco de pruebas para comprobar el funcionamiento de una parte de la extensión: las funciones básicas, pruebas unitarias y funcionales pero del api básica de la aplicación, en otra palabras de las funciones que se ofrecen como base para otras cosas de mas alto nivel.

https://github.com/christiansalazar/yii-billing/blob/master/YiiBillingTest.php

2. Este programa de pruebas esta hecho para comprobar que las funciones básicas en conjunto trabajan bien, eso si posándose sobre la idea de que las funciones básicas del API hacen lo esperado (enlace anterior).


https://github.com/christiansalazar/yii-billing/blob/master/YiiBillingPaymentsInAdvanceTest.php


Ambos enlaces hacen pruebas funcionales y unitarias por si solos, pero el primer enlace se encarga de que lo básico funcione bien y el segundo de que lo avanzado funcione bien también.
 
Cuando piensas en hacer una aplicación con TDD piensas en comprobación, es decir: cómo probar que lo que voy a hacer realmente funciona.


Evitar las Hiper-dependencias y dependencias recursivas.

Es muy fácil caer en la hiper-dependencia, o dependencia espagueti, una hiper-dependencia es cuando A depende de B quien depende C que a su vez depende de B y de A. Existen mucha teoría de software para evitarlas, son muy daniñas y la mejor manera de evitarlas es cumpliendo la ley de python: "be explicit", es decir, componentes que requiren datos explicitos sin extraerlos "magicamente" de otro componente bajo la mesa. Muchas veces cuando A depende de B y a su vez B depende de A entonces es necesaria un tercer componente: C, el cual recibe a A y B hace el trabajo requerido y evita la dependencia recursiva.


Lee mas acerca de cómo implementar Inyección de Dependencia para evitar las hiper-dependencias.

Ejemplo de una lógica de negocios nueva para una aplicación existente

Esta extensión permite mostrar cómo implementar la facturación a una aplicación existente sin romper o fragmentar la aplicación existente, de un modo extensible, realmente orientada a objetos y con TDD.

https://github.com/christiansalazar/yii-billing 

Ejemplo de cómo se ataca un error con TDD en una capa de negocios.

 https://github.com/christiansalazar/yii-billing/issues/4



No hay comentarios:

Publicar un comentario