Estoy trabajando en un proyecto en mi tiempo libre, que más que productivo es algo que siempre he querido hacer. Todas las pruebas están en su lugar y me tengo terminantemente prohibido adicionar código si no está cubierto y probado debidamente. Es algo en lo que creo, y me ha funcionado perfectamente. Las pruebas unitarias sin lugar a dudas, son la mejor forma de asegurar la calidad en el código.
Sin embargo, no hago pruebas unitarias para el código en mi trabajo. Así es. Ni una sola prueba, ni una sola vez. Aún peor: no hacía pruebas unitarias tampoco en mi trabajo anterior (de unos 3 años de duración), así que puedo afirmar sin temor a equivocarme, que en mis responsabilidades laborales de los últimos 4 años, ni una sola prueba unitaria ha sido desarrollada por mi. Ni una sola. ¿Cuál es la diferencia? ¿Por qué en casa sí y en la oficina no? Pues por que creo que son dos industrias diferentes, con especificaciones, requerimientos y prohibiciones completamente distintas y a las cuales hay que adaptarse si queremos sobrevivir.
Trabajo en una empresa que se dedica a producir software para terceros clientes. Estos llegan con una idea de sus necesidades, y en mi empresa se les hace una solución a la medida para resolverlas. Los clientes pagan por un producto en un tiempo determinado donde el código fuente no es parte del negocio, creando una relación a largo plazo durante todo el mantenimiento de la aplicación. Mi empresa anterior se dedicaba exactamente a lo mismo con un modelo similar de negociación, así que literalmente he estado trabajando por 4 años en esta industria.
Esta filosofía (y por consiguiente el modo en que debe enfrentarse) es completamente diferente o otros escenarios de desarrollo donde también he participado en otras etapas de mi carrera, y que sin pretender abarcalos todos, listo a continuación:
- Desarrollo y mantenimiento de uno o varios productos, donde el equipo emplea la mayor parte del tiempo enfocado en el desarrollo de estos, generando ventas recurrentes del mismo. Son las empresas que también se les conoce por vender "software general" (opuesto a las que venden "software a la medida").
- Desarrollo de aplicaciones para consumo interno, lo que significa que la empresa se "autoabastece" de los productos que necesita con equipos de desarrollo dentro de su fuerza laboral.
- Desarrollo de aplicaciones no comerciales con fines educacionales o de investigación, lo cual varía desde la implementación de pequeños algoritmos hasta programas muy complejos con requerimientos de precisión bien elevados en dependencia de su objetivo.
Volviendo al primer escenario, donde la empresa comercializa software a la medida, estamos hablando de uno de los modelos más difundidos, y por consiguiente, donde más competencia existe. En la era de los ordenadores, es literalmente imposible que alguna empresa quiera mantenerse alejada de estos, así que la demanda de software está cada día más en alza. Con la demanda por las nubes, más y más compañías quieren morder una parte del pastel, y tristemente no todas sobreviven el intento.
El cliente llega (y muchas veces -de forma agresiva-, hay que ir a buscarlo), pone su presupuesto sobre la mesa y un papel lleno de ideas. Aquel que sea capaz de implementarlas de la mejor forma posible, y por la suma de dinero indicada, gana la apuesta. Y recalco "dinero", sin dudas el factor fundamental en la mayoría de los casos. No todos tienen plata para quemar en un vertedero, provocando que los proyectos en la mayoría de los casos, se conviertan en maratones para hacer más con menos.
¿Y dónde entran las pruebas unitarias aquí? Precisamente en ninguna parte. Las pruebas unitarias requieren de un tiempo extra que puede resultar de vida o muerte para cumplir con las entregas planificadas. Cuando todo lo que se tienen son fechas de entrega, es imposible pensar en las pruebas. Todos sabemos que, a pesar de consumir un tiempo mayor al principio, las pruebas pueden ahorrarnos mucho tiempo durante el mantenimiento de un proyecto, pero precisamente es al principio donde este tiempo resulta vital. Cuando tenemos al cliente a bordo, todo es negociable, pero la velocidad en las primeras iteraciones de un producto son cruciales en este tipo de negocio. Ese es precisamente el conflicto con las pruebas.
Los clientes por lo general no tienen idea de qué beneficios obtienen si su codigo está respaldado con pruebas unitarias, por lo que es muy difícil negociar con ellos tiempo extra para ello. Tiempo y presupuesto son por lo general los dos temas principales, y todo aquel que no se ajuste, tiene la batalla perdida.
Ahora bien, decir que por estos motivos todo el software que se crea en este tipo de negocio no tiene calidad debido a que no tiene pruebas unitarias es algo completamente erróneo. En primer lugar, las pruebas unitarias no son garantía ninguna cuando no son bien desarrolladas. Una aplicación con cero pruebas unitarias puede ser mucho mejor que una con supuestamente 100% de cobertura. En segundo lugar, decir esto de una industria que genera trillones de dólares al año sería una afirmación completamente descabellada y fuera de lugar.
Todo tiene sus métodos, y nuestro trabajo es descubrir dónde estamos y cómo salir adelante en dicho contexto. Lo que funciona aquí, no funciona en todas partes. Lo que funciona hoy, mañana puede ser un error. Ojalá llegue el día donde las pruebas unitarias sean requisito obligado e indispensable. Hoy no es ese día, y el que no lo entienda de esa manera, sencillamente no podrá sobrevivir entre iteraciones rápidas dentro de una economía donde las reglas del mercado se imponen a todo lo demás.
Entonces aquí seguimos: haciendo pruebas unitarias para mi propio proyecto, brincando como loco para los clientes, y soñando con un mundo mejor... mientras llega, lamentablemente no me queda tiempo para más.
When Google Translate works well, it makes you sound like an English author, when it doesn't it makes you sound like a foreigner from a land far far away.
ReplyDeleteWhat, might I ask you, is a unit test? ... haha.. j/k. But seriously, until a business is on the verge of a total melt down, the idea of spending more to "get it right" doesn't jive with the management. Especially, when the ROI of unit testing has no formula unless losses have already accumulated. I think Windows 7 is the unit-tested version of Windows Vista. Microsoft must have at some point decided that unit testing might be a good idea for their long term existence. Now all they need is to re-think all of their confusing Control Panel links and icons. It looks like a scattered mess of options without any flow to it.
Love the idea of Windows 7 being the unit tested version of Vista :) At least nobody can't argue that it is a much better version (still crap though). Do you think the Control Panel has tests in place? lmao
ReplyDeleteBy the way, don't say anything about Google Translator. It could be better, sure, but at least gets the job done better than anybody else. You are reading my posts, ain't you?
ReplyDeleteUmm, no estoy de acuerdo con la afirmación de que las pruebas unitarias son para salvar tiempo en mantenimiento, eso NO es una afirmación correcta, las pruebas unitarias pueden salvar tiempo incluso en tiempo de desarrollo pues son bien rápidas de ejecutar, fáciles de implementar y te permiten probar casos extremos todo el tiempo.
ReplyDeleteSimular un caso extremo probando la aplicación a través de una ejecución y jugando con el UI no es buena idea, muchas veces inviertes HORAS tratando de detectar un bug probando interacciones con el UI para lograr el juego de datos que falla, cuando haciendo una prueba podrías detectarlo en minutos, entonces culpas el no hacer pruebas unitarias a que el tiempo estaba muy apretado, pero si en las partes complejas de la aplicación hubieses hecho pruebas quizás al final no tengas el deadline tan apretado y te es MUCHO mas fácil detectar bugs en lugares críticos.
Creo que estas mezclando dos cosas, una es la teoría que dice que mientras mayor cobertura mejor y lo ideal es tener 100% de cobertura y la otra es decir que hacer pruebas unitaria “retarda” el proyecto, si quieres full coverture entonces SI estas en un “problema” con el deadline y lo pongo entre pues incluso esa afirmación puede ser cuestionable, pero hacer pruebas unitarias en los lugares claves del proyecto hace que salves tiempo en la gran mayoría de las ocasiones.
Continuará...
Claro esta, si el proyecto esta mal diseñado, el acceso datos esta en la capa de negocios (como se plantea en uno de los artículos que publicaste), no hay inversión de control en el comportamiento de las reglas de negocio para poder falsear datos y probar reglas, entonces hacer un test unitario es mas complejo pero, no es culpa de los test unitarios sino de un mal diseño, que again hiciste o se hace mal en tu compañía por salvar tiempo, y esta mas que demostrado que salvando tiempo en diseño afecta negativamente el tiempo de entrega al final.
ReplyDeleteOtra vez voy con la teoría y la practica, en teoría 100% cobertura es lo ideal, en la practica y en mi experiencia eso no es posible en la mayoría de las ocasiones, pero negar la utilidad de las pruebas unitarias no importa el tamaño de la aplicación, el tipo de cliente, el deadline, el budget, es un ERROR, de hecho las metodologías ágiles como XP que están diseñadas precisamente para entornos dinámicos como los que describes con los clientes, basan muchas de sus funciones alrededor de los unit test, no estoy diciendo con eso que hagas lo que plantea XP de hacer primero el test y después el code , pues eso en teoría es muy bueno, funciona muy bien, pero en la practica si puede afectar el proyecto, pero no hacer ningún test significa o que la aplicación es un “Hello World” o que la aplicación no tiene buena calidad. Eso de decir que hay aplicaciones que tienen una super calidad sin test es correct, yo solo cambiaria la sentencia diciendo "Hay aplicaciones que tienen una calidad increíble sin pruebas unitarias, pero tendrías aun mas calidad si las tuvieran!!!!"
Nunca debes decir que como todo el mundo lo hace de una forma significa que esta bien, ahora no tengo los números pero se que el % de proyectos de software que se quedan en el camino es bien grande, no quiero decir que la causa es los test unitarios, pero..., en gran medida la causa es mal diseño, y no hacer test es el inicio de un mal habito que a la larga afecta a todos.
Continuara...
Por ultimo, si no hacen unit test imagino que en los proyectos que hablas no hagan test de aceptación, regresión test, que se hagan refactoring de los que hablas como solución y no se pruebe realmente que el refactoring no afecto el comportamiento, imagino que estés pensando que después de un refactor hecho correctamente no haya necesidad de probar, pero quien garantiza que el refactor no haya sido hecho inadecuadamente? Forma de probarlo, unit test, regestión test si los tuvieses hechos, pero en los proyectos que describes creo que no hay mas remedio que ir opción por opción a ver sí todo esta correcto. Ummmm crees que eso sea realmente una forma de “salvar tiempo”?
ReplyDeleteSiempre la consecuencia a esos errores al comenzar un proyecto por querer adelantar mas se traduce al final en “Clientes descontentos” y en un gran % de las ocasiones “Proyectos fracasados”. Incluso a ustedes muchas veces les escuche decir que el cliente estaba en estado de coma porque estaban atrasados y again mi complejo de teacher me hace hacerte otra pregunta escrita: No has pensado que entre muchas otras causas que atrasa un proyecto, el anti-patron de pensar que hacer test atrasa aun más el proyecto realmente té este atrasando el proyecto por no hacerlos?
1) Estamos de acuerdo en que no solo en tiempo de mantenimiento las pruebas unitarias ayudan a salvar tiempo. No lo limité a ese momento, sino que dije que es allí donde más ayudan, ya que es cuando una y otra vez tenemos que correrlas luego de cada cambio.
ReplyDelete2) Nada de acceso a datos en la capa de negocio. Ya expliqué que no es así lo que yo estoy haciendo.
3) No he negado la utilidad de los tests. Todo lo contrario. Ahora bien, como bien dice David más arriba, no existe una fórmula para determinar el ROI de los tests. Con eso en las manos, ¡buena suerte convenciendo a tu manager!
4) De acuerdo tambien que si existieran las pruebas las app tuvieran mas calidad.
5) Sin tests, obviamente cuando se hace un refactoring se pueden introducir bugs. Para nada creo que mágicamente se puede decir si el refactoring fue bien o no. Sin tests, nunca queda claro.
Como resumen, estamos metidos en un campo donde todo es "DEBE" - "PODRIA" - "CASI SIEMPRE", etc. Tú, yo, y cualquiere que haya leido sobre el tema de las pruebas unitarias, sabe sus beneficios. Estamos de acuerdo en que son 100% beneficiosas, pero de nuevo repito, no somos quien tomamos las decisiones.
Cuando tengamos la fórmula en tiempo ahorrado + calidad que las pruebas unitarias van a salvar, entonces ganaremos la batalla. Como dije en el post, ese dia no es hoy, asi que estamos fritos. En tu empresa tu tienes bandera abierta para hacerlos, en la mia no. Es triste, pero es la vida real.
Esa respuesta no me convence, estas al mismo tiempo hablando de aplicaciones a la medida, desarrollo ágil y después niegas todo eso, negando además no solo mi opinión que quizás no pueda tener el peso necesario sino la opinión de personajes como Martin Flower y otros GURUs del desarrollo ágil, bueno tu o tus managers que “prohíben” hacer unit test en tus proyectos.
ReplyDeleteVoy por parte a las respuestas:
1- De la forma que enfocas el articulo da la impresión en una parte de que las pruebas son útiles solo en el mantenimiento, en mi opinión son útiles todo el tiempo, mas si estamos hablando de desarrollo ágil. Aparte recuerda que en el desarrollo ágil una vez que terminas la primera iteración (que normalmente es una pequeña parte del proyecto) y pones eso en producción, automáticamente estas pasando esa iteración a mantenimiento.
2- Cuando me refiero a acceso a datos en la capa de negocios me refiero que la forma que implementas (según tu articulo) de introducir los datos en tu servicio no soporta inversión de código, y me baso en el ejemplo que me mandaste, eso quiere decir que para llamar al método sendNotificationToAllUsers (un ejemplo sencillo) el mismo va a necesitar leer de la BD los usuarios para mandarles un email con alguna información. Básicamente, eso es un error, ese método va a ser muy difícil de probar pues:
a. Depende de una información que no puede ser generada desde el exterior
b. De la forma que planteas que estas trabajando posiblemente no tengas acceso al contenido del mensaje en un test unitario pues el método directamente enviá el mensaje usando SMTP (me baso en lo que dices de over design)
Continuara...
3- No se por que haya que convencer a un manager de que un unit test es necesario hacerlo, si me dices que tu quieres hacerle unit test a todo, entonces si vas a tener que convencer al manager, pero si te topas con un caso que requiere unit test pues simplemente lo haces, un unit test para probar algo complejo es parte del proceso, no se debe considerar como algo extra, claro esta, si hacer el unit test es complejo (quizás por lo que planteo en el punto 3) entonces no vale la pena, pero..., si analizas el trabajo en los 4 años que mencionas, estoy seguro que hay varios lugares donde haber hecho una prueba te hubiese sacado de varios apuros y de seguro te hubiese salvado tiempo ejecutando y probando la aplicación. Ahora si has estado en dos empresas donde se “prohíbe” hacer unit test has tenido tremenda mala suerte, normalmente eso es algo que esta en el proceso y lo normal es que:
ReplyDeletea. Exijan unit test
b. Sea opcional hacerlos
Pero “prohibirlos”!!!! Umm en dos empresas consecutivas!!! Ummm has tenido mucha suerte (o mala suerte ;)), alguien debería halarle las orejas a tus managers, y deberias comenzar a convencerlos de que están en la era donde las computadoras se hacían con válvulas al vació.
4- Es lo que digo, y si haces integración continua desde el comienzo usando cualquiera de las herramientas existentes pues genial, y si incluyes QA test y regresión test, pues eres un genio sobrino!
5- Eso lo que digo ;)
Continuara...
Insisto, no trabajo en tus dos ultimas empresas (por suerte) pero me da que pensar en que esta pensando tus managers si ellos “prohíben” hacer unit test, eso no tiene sentido alguno, si es porque se consume mas tiempo, eso es un error garrafal pues lejos de eso un unit test te salva mucho tiempo en cualquier etapa del proyecto.
ReplyDeleteHablas también que los unit test no se le entregan a los clientes, es cierto que muchos clientes no saben siquiera de la existencia de esto, pero..., eso no quiere decir que no se hagan algunos al menos para probar las cosas complejas, y..., Siii, eso NO se entrega al cliente!, pero..., se le entrega a los infelices programadotes que bien:
1- Están desarrollando la aplicación
2- Van a darle mantenimiento a la aplicación
No estoy con esto diciendo que hacer unit test a todo sea mandatario (bueno lo ideal es hacerlos), de hecho yo NO los hago en todo momento (aunque reconozco que debería hacerlo), pero..., “SIN EMBARGO SE MUEVE”
A ver, vamos por partes pa no volvernos loco. En este comentario voy solamente con lo de los datos en las reglas de negocio. Veamos el ejemplo que yo puse en aquel post:
ReplyDeletemethod listadosDeUsuariosOrdenadosPorNombre : List
return accesoADatos.listadosDeUsuariosOrdenadosPorNombre()
end
En este caso, expliqué que "accesoADatos" es una entidad que se encarga de encapsular los detalles del acceso a los datos. Sus clientes no sabrán nada sobre el tipo de Base de Datos o la manera en que se accede a la misma.
En cuanto a lo de IoC, nunca hablé de eso en el post, pero supongamos que queremos probar ese método. Lo que tenemos que hacer es simplemente pasarle una instancia falsa de la clase accesoADatos y todo queda resuelto. En ningún momento se ve en ese ejemplo que no se soporte las pruebas unitarias, así que no entiendo tus comentarios del punto #2:
a. "Depende de una información que no puede ser generada desde el exterior"
NOT TRUE por lo que vimos arriba.
b. "De la forma que planteas que estas trabajando posiblemente no tengas acceso al contenido del mensaje en un test unitario pues el método directamente enviá el mensaje usando SMTP (me baso en lo que dices de over design)."
Aqui estas hablando de algun ejemplo que no recuerdo. No lo he podido encontrar entre los mensajes que te mandé.
En resumen con este tema, te pido please que vuelvas a leer pues a pesar que puede que me haya expresado mal, en ningun momento he dicho que los datos van juntos con el negocio. Fijate bien en el ejemplo que pongo y veras que se cumple todo lo siguiente:
1) Se puede isolar el codigo para probarse.
2) No están ligados la base de datos con las reglas de negocio
3) No se viola absolutamente ningún principio.
Vuelvo y repito, mi modelo tiene y usa las 3 capas del patrón: UI, BR, y DA. Lo que estoy diciendo es que NORMALMENTE muchas personas crean una 4ta capa y la nombran DataAccess (o DAO, o como sea) cuando en realidad están creando un burdo intermediario.
Ahora vamos a lo de las pruebas unitarias:
ReplyDelete1) A los managers no hay que convencerlos de nada. Ellos simplemente quieren seguir tu progreso cada minuto, y no van a permitir que bajo el nombre y los beneficios teoricos de los test unitarios pierdas el tiempo. Y ANTES QUE GRITES, yo se que no es perder el tiempo, PERO ELLOS NO.
2) Una cosa tiene que quedar clara BIEN clara. Los tests SI CONSUMEN TIEMPO. Un test puede ayudar a ahorrar tiempo, pero los otros van a tender a consumirlo. Aqui obviamente estamos hablando de tener un codigo con una cobertura decente de tests, no de hacer un tests cuando se necesite lo cual hace todo el mismo y muchos llaman AUTOMATION (voy a escribir sobre esto luego).
3) Si tenemos un proyecto con buena cobertura de tests, OBVIAMENTE sera mucho mas facil hacer modificaciones ya que el riesgo de regresiones y nuevos bugs se reduce. PERO lograr esta cobertura toma tiempo, y a pesar que es bueno, ESE TIEMPO no te lo da nadie.
4) Mi empresa gana dinero dandole a los clientes lo que estos piden. Hay clientes educados que piden test unitarios, pero la gran mayoria no los pide. Las empresas no prohiben los tests unitarios, no quise decir eso. Lo que digo es que los managers NO TE DEJAN emplear tiempo en algo que no sea lo que ellos llaman "avanzar".
5) Mi empresa no es rara ni mucho menos. Tengo muchos amigos que hacen mi mismo trabajo, y es una lastima que ninguno haya comentado aqui, pero te aseguro que el 99.9% no hace tests por razones similares a las mias. TU ERES QUIEN ESTA EN UNA EMPRESA RARA, donde estos tests se exigen... o simplemente te dejan programar en paz para que tu desarrolles lo que quieras. Apuesto a que tu trabajas para tu propia empresa (siendo esta tu cliente). Cuando yo trabaje asi en Cuba para ETECSA yo tambien hacia los tests.
6) Y retomando un punto del que ya hable en #2 arriba, hacer un tests para probar algo no es a lo que yo me refiero. En eso no se mete nadie jamas y no tiene sentido tocarlo. Hablo de una cobertura al menos por encima de un 80%, donde en realidad se ve el tiempo que toma, no solo crear todos los tests, sino mantenerlos cada vez que se hace un cambio.
Y por ultimo, VUELVO Y REPITO, yo estoy a favor de los tests 100%!!!!! Ain't me the problem bro. I would to 'em all the time if I could...
Voy a responder tus mensajes acerca del post en si después, pero para aclarar algo antes de hacer mi respuesta dime algo, en tu ejemplo que cosa es accesoADatos.listadosDeUsuariosOrdenadosPorNombre()?
ReplyDeleteDices que no es un DAO entonces que es? Mencionaste frameworks como hibernate para esa parte en alguna ocasión verdad? Crees que hibernate permita algo como accesoADatos.listadosDeUsuariosOrdenadosPorNombre()? Ummm no realmente!!!!
No he tenido el gusto de trabajar con SQL Link pero..., por lo que entiendo de tu mensaje si estas usando SQL Link, entonces quiere decir que tu capa de negocio esta acoplada con SQL Link verdad, donde "accesoADatos" es una instancia de una interfaz o clase que en algún momento acoplas al negocio y que depende de SQL Link no? De lo contrario, si "accesoADatos" (o sea la clase que representa esa instancia) no es de SQL Link pero contiene dentro el “COMO” comunicarse con SQL Link entonces es un DAO lo que lo renombraste a ponerle lo que quisiste y tu articulo se trata de alguien que quiere incluir dos DAO en un mismo proyecto (uno con el nombre de DAO y el otro sin el nombre de DAO pero DAOs los dos al final) proyecto lo cual es una animalada, necesito aclaración de eso!
Ahora lo otro en el post tu pones:
ReplyDeleteclass AccesoADatos
method listadosDeUsuariosOrdenadosPorNombre : List
var conexion = conectarseALaBaseDeDatos()
var listado = conexion.llamarProcAlmac("ListadoDeUsuarios")
return listado
end
y después pones
class ReglasDeNegocio
method listadosDeUsuariosOrdenadosPorNombre : List
return accesoADatos.listadosDeUsuariosOrdenadosPorNombre()
end
Después pones esto “Teniendo en cuenta esto, mis proyectos podían ser modificados renombrando mi capa de "Acceso a Datos" a "Reglas de Negocio" y eliminando todos los intermediarios”
Según textualmente dicho por ti entonces la capa de reglas de negocio quedaría de la siguiente forma:
class ReglasDeNegocio
method listadosDeUsuariosOrdenadosPorNombre : List
var conexion = conectarseALaBaseDeDatos()
var listado = conexion.llamarProcAlmac("ListadoDeUsuarios")
return listado
end
No?
Ahora mi turno, en la capa de negocios:
ReplyDelete1. Llamas a un metodo que se llama conectarseALaBaseDeDatos()
2. La regla de negocio sabe además que se va a llamar a un SP
Eso resuelve tu problema si, pero crees que una capa de negocio es realmente eso? Eso se le puede llamar cualquier cosa menos capa de negocios!!!! Porque de hecho en tu ejemplo la regla de negocio en realidad donde pudiera estar es en el SP.
Lo que les esta pasando es que están usando SP y están poniendo lógica dentro de los mismos lo cual es correcto, pero esto no es justificación para decir que una capa de negocios deba saber como conectarse a una BD y mucho menos que la misma sepa que hay un SP!!!, si lo vas a hacer asi ponle otro nombre pero no lo ligues con Business porque es incorrecto.
Si toda tu aplicación es hecha con SP entonces parecerá que la capa de negocios no tiene sentido, pero es solamente porque tu estas metiendo la lógica en los SP.
Pudiera decirse que entonces que cuando no se usen SP entonces se crea la capa de negocios y si no se hace como lo hiciste (Que no es una capa de reglas de negocio) pero…, quien garantiza que no uses los dos modelos, o sea que tengas lógica en un SP y en un momento determinado te haga falta implementar algo en el lenguaje?
Por ultimo y volviendo al principio de lo que dije, si la clase que representa a accesoADatos no esta desacoplada con el negocio a través de una interfaz y la misma depende de SQL Link, entonces el problema radica en que el negocio esta casado entonces también con SQL Link (o lo que sea) lo cual también es un error, pero a pesar de eso la clase de “accesoADatos” es un DAO y claro esta si incluyes otro DAO pues tienes dos DAO en el proyecto y no creo que a nadie se le ocurra hacer eso, ahora bien..., eso no es lo que dice el articulo!!!, el articulo dice explícitamente “Teniendo en cuenta esto, mis proyectos podían ser modificados renombrando mi capa de "Acceso a Datos" a "Reglas de Negocio" y eliminando todos los intermediarios.” Y el resultado de eso que me dices aquí no es lo que esta en el articulo!
ReplyDeleteNoooooooooooooo, ya veo cual es la confusion en todo esto chama. Si te fijas, mi ejemplo es un pseudocodigo que para nada puedes tomar literalmente. Por consiguiente:
ReplyDelete1) Yo no hablo de Procedimientos Almacenados alli. Eso es algo que no le concierne a la capa de reglas del negocio.
2) Donde digo "conectarseALaBaseDeDatos" me cuide mucho de usar un nombre de metodo real ya sea de ADO.NET o JDBC o cualquier otro para evitar esto mismo. Eso chama repito NO ES CODIGO REAL, es un PSEUDOCODIGO para ilustrar un concepto. Para nada eso lo puedes traducir a un SqlConnection o un Connection, o cualquier otra clase real.
Lo que sucede es que esos ejemplos eran mejor ilustrados en imagenes (con una flecha saliendo de el DAO hasta una BD) en vez del pseudocodigo que puse alli.
Lo otro es que no concuerdo que Linq to SQL sea un error usarlo desde el business rules. Es un error bajo el pretexto de "eso puede cambiar, blah, blah, blah". En la practica, solo sucede 1 en 100,000 veces.
ReplyDeleteTu codigo concreto dice que renombras el acceso a datos a el negocio y en esa clase tienes:
ReplyDeletemethod listadosDeUsuariosOrdenadosPorNombre : List
var conexion = conectarseALaBaseDeDatos()
var listado = conexion.llamarProcAlmac("ListadoDeUsuarios")
return listado
end
O sea, te estas conectando a una BD o conectando a algo y la pregunta es, por que el negocio se tiene que conectar a algo?, el negocio tiene que tener una fuente de datos y NO debe saber si hay o no que conectarse a ella, simplemete le pide cosas y es la fuente la que tiene que saber si hay o no que conectarse.
Y explisitamente llamas a un SP, segun el articulo es lo que la gente esta entendiendo, si quisiste decir otra cosa mejor pon un comentario con las correciones porque lo que me estas diciendo ahora no es lo que dice el articulo y lo que esta en el articulo tiene problemas!
Lo otro al final como es que queda? O sea tienes un business que se conecta con SQL Link que es el que provee los datos..., pero como lo hace? Porque si viras par atras y me dices que en el negocio lo que tienes es :
method listadosDeUsuariosOrdenadosPorNombre : List
return accesoADatos.listadosDeUsuariosOrdenadosPorNombre()
end
donde accesoADatos es SQL link estas cayendo en el mismo ejemplo que usamos en la universidad de UI/Business/DAO lo que en tu caso el DAO no tiene nombre de DAO pero sigue siendo lo mismo.
Si es asi entonces el error esta en crear un DAO despues de otro DAO pero..., no creo que a nadie se le ocurra semejante cosa, bueno al parecer ustedes lo estaban haciendo.
Con respecto a lo de SQL link y usarlo o no en el business, es algo de lo que podemos discutir largo tiempo, hasta donde se SQL link es como Ibatis, SQLJ, Hibernate etc etc, si es asi entonces apruebas el usar Hibernate en el layer de negocios?
ReplyDeleteAl usar hibernate en el layer de negocios estas cayendo en Two Tier, que es lo que tu estas haciendo, eso es aceptado pero..., trae problemas a medida que la aplicacion se va haciendo grande!
ReplyDeleteOK, vamos a ir para atrás. Indiscutiblemente el pseudocodigo no transmite la idea que yo queria, asi que ya lo cambie. Ahora está usando algo COMPLETAMENTE AGNOSTIGO a una DB porque el objetivo no es ilustrar una tecnologia determinada, SINO poner un ejemplo.
ReplyDeleteLo otro es, y esta pregunta no tiene solución, pues la respuesta es DEPENDE. ¿Por qué es incorrecto usar Hibernate en business rules? La respuesta que vas a dar es: Porque estas mezclando lo que no puede ser con las reglas de negocio... porque las pruebas... porque etc etc etc Y YO TODO ESO LO SE. Y ademas, ESTOY DE ACUERDO... desde un punto teórico.
Pero...
La mayoria de las veces tratamos de matar mosquitos con escopetas. Tener la mente FIJA en algo como esto todo el tiempo es lo mismo que implementar un HELLO WORLD usando 4 patrones.
Mi filosofia, y es la que he tratado de imponer en cada uno de los posts de este blog es la de HACER LO MAS SIMPLE POSIBLE... pero eso no indica que haya que hacerlo mal. Hay veces donde HIBERNATE no puede ir en el Business Rules. Hay veces donde no hay problemas. La diferencia entre tu teoria y la mia es que tu siempre asumes que no puede ir. Yo asumo que puede, y solo lo cambio cuando haga facil.
Ninguno de los dos approach es incorrecto. Tu empiezas siempre con un width=100%. Yo empiezo con width=1px hasta que la vida me demuestre lo contrario. Tu approach tiene 100 ventajas, el mio tambien.
A las 12:01 (dentro de 5 horas y algo) vas a ver un post que explica mas esto. Se llama CIRUJANOS Y PARAMEDICOS. Estoy seguro que con solo el nombre ya sabes de lo que trata.
La verdad es que no entiendo bien el ejemplo que pusiste, que es: contexto.Usuarios.devolverListado()? Contexto? Eso no es un DAO? Si no lo es que me maten!!!! Y si es un DAO volvemos a lo mismo, estas criticando a proyectos hechos por ustedes que ponen dos DAO en un mismo proyecto y eso es claro que es una animalada. El hecho que se llame SQL Link, "Contexto" o como sea y que se use de la forma en que lo planteas es un tipo de DAO aunque no tenga DAO en su nombre, y claro esta si lo tienes, por que crear otra capa?.
ReplyDeleteCon respecto a usar hibernate en business rules hay que ir a la evolucion, monolitico, dos capas, tres capas, ahi esta la respuesta y no hay que entrar en esos detalles de nuevo ya eso esta MAS que discutido por millones de personas y ni tu ni yo vamos a aportar nada nuevo. Hibernate usa HSQL para las queries y entonces vas a tener queries en el negocio? Puedes usar criterios pero la version de JBOSS de hibernate no los tiene asi que caes de nuevo en el HSQL.
Yo no estoy cerrado a que las cosas son blanco y negro, se que hay proyectos y proyectos, pero de la forma que haces el articulo, aparte de los problemas que hay en el :), parece que es una regla y creeme que esta bien lejos de serlo.
Yo creo que voy a dejar por cerrada esta discusion porque estamos cayendo en lo mismo, solo espero que las personas saquen sus propias conclusiones y que traten de hacer las cosas bien al menos que los managers exijan que las hagan "no tan bien"!.
Solo 3 cosas:
ReplyDelete1. Creo que no cabe la duda que estos dos tigres son los que mas dinero ganan en este momento como para darse el lujo de escribir mierd.. cantidad (perdon, quise decir millones de lineas). Repito, no me alcanza el tiempo siquiera para leerlas todas.
2. Me parece bien esta invitacion al debate que nos hace santiago con sus reflexiones, mejor o peor logradas, no importa.
3. Mi opinion:
Como casi siempre, no voy a los extremos, el que le encuentre utilidad que las haga. Yo realmente tuve mala experiencia con el mismisimo Santiago con un proyecto que le dirigi justo cuando le empezo por dar la fiebre de las pruebas.
Quizas no estuvieron bien diseñadas pero me traia los cambios que le pedia, con 60 pruebas unitarias corriendo OK, y cuando lo validaba a mano explotaba el codigo. Quizas no te acuerdes de eso, pero yo si porque lo sufir (Proyecto GNF).
Soy de una idea: los bugs surgen durante una modificacion (generalmente) porque la aplicacion alcanzo un estado que nunca se previo. Entonces como rayos sere capaz de crear una prueba unitaria para un escenario que no exisitira???
Bajo ese principio, no las he necisitado antes y no creo en el futuro.
DRD, no estoy de acuerdo, pero creo que ya se habló suficiente al respecto en este mismo post. De todos modos, como sé que es un tema candente, prometo hacer otro post en un futuro cercano donde podamos concentrarnos en una idea más específica y no en algo tan general como en este caso.
ReplyDeleteEsta batalla no tiene para cuando acabar.
Santiago al fin estamos de acuerdo al menos en no estar de acuerdo con algo :D.
ReplyDeleteDRD, solo espero que Martin Flower y la pandilla de GURUs de agile no sepan leer español porque los podemos perder de infartos masivos si leen estos comentarios!
Boys, hay códigos cochinos, malos, sin tests, sin pruebas de aceptación, proyectos que ponen cosas en producción y prueban los cambios en caliente, pero..., no podemos hacernos con esto el anti-patron de que eso es correcto, una cosa es que a veces tenemos que lidiar con ese tipo de proyectos, sobre todo en empresas pequeñas (pero no en todas!!, al menos no en mi experiencia) y donde la inconciencia de las personas que dirigen (o de los programadores) llevan a hacer ese tipo de cosas y otra muy diferente es hacernos a idea de que es correcto hacerlo! A veces necesitamos el trabajo (traduzco,..$$) y tenemos que “morder” con cosas como esta, pero..., siempre estén dispuestos a plantear que es erróneo hacerlo aunque nadie los escuche, al menos yo puedo dormir tranquilo cuando lo hago, y me queda mi conciencia limpia de que al menos dije “eso es tremenda cacona”!!
Like I promised, I'm gonna write about this later again.
ReplyDeleteRealmente no es que yo vaya al extremo, siempre lo aclaro. El problema puede radicar en que aplicar Test Unitarios a ambientes (NO MVC) es engorroso y muchas veces casi imposible.
ReplyDeleteCuando hablo de MCV no me refiero a una implementacion especifica sino al patron como tal. Como hacer un Test para algo que depende de las entradas o flujo de acciones del Usuario? Quizas por ello es que han fracasado algunas experiencias que he observado. Evidentemente no estaban bien diseñadas o no habia forma de que lo estuvieran, quizas.
Pero bueno, aclarar que aunque no haya tenido que usar Test Unitarios no quiere decir que usemos nuestros proyectos y sus modificaciones no esten sujetos a un riguroso esquema de diseño, pruebas y validaciones, antes de su publicacion final.
------
Nota aclaratoria:
------
En un comentario mio anterior escribi:
"escribir mierd.. cantidad (perdon, quise decir millones de lineas)"
Ese comentario no pretende ser ofensivo en ningun momento pues esta dirigido a dos grandes amigos mios que lo leyeron sin ningun problema y lo entienden. Aunque nadie me ha llamado la atencion por ello, lo quiero aclarar por si acaso para que nadie vaya a pensar que estamos violando buenas normas de comunicacion y debate.