Hola a todos. Ya podéis descargaros de forma totalmente gratuita, el interesantísimo libro de Ivar Jacobson "Casos de uso 2.0", a través del siguiente enlace:
http://www.ivarjacobson.com/resources/resources/white_paper/
El autor, Ivar Jacobson, es más conocido por su participación en la creación de UML, RUP y la programación orientada a aspectos.
Feliz lectura.
Mostrando entradas con la etiqueta patrones. Mostrar todas las entradas
Mostrando entradas con la etiqueta patrones. Mostrar todas las entradas
domingo, 27 de abril de 2014
viernes, 4 de enero de 2013
Más Singletonitis
Recientemente, he escrito una entrada sobre la Singletonitis, y hoy me he encontrado con una entrada en un interesante blog, que habla también del tema, abordando incluso aspectos que había pasado por alto.
Al final, el abuso de los patrones está encontrando la horma de su zapato: lo que hoy nos parece una buena idea, mañana resulta contraproducente. El antiguo patrón singleton, tan sencillo, resulta ser un dardo envenenado a prácticas tan aceptadas como indispensables hoy en día como el uso de pruebas unitarias.
Sin embargo, la alternativa es difícil. El autor de este blog propone el uso de otro patrón de diseño, que si bien es similar funcionalmente (el llamado patrón monostate) , resuelve los problemas del Singleton (aunque a costa de una implementación compleja).
Fuentes: enlace.
Un saludo.
Al final, el abuso de los patrones está encontrando la horma de su zapato: lo que hoy nos parece una buena idea, mañana resulta contraproducente. El antiguo patrón singleton, tan sencillo, resulta ser un dardo envenenado a prácticas tan aceptadas como indispensables hoy en día como el uso de pruebas unitarias.
Sin embargo, la alternativa es difícil. El autor de este blog propone el uso de otro patrón de diseño, que si bien es similar funcionalmente (el llamado patrón monostate) , resuelve los problemas del Singleton (aunque a costa de una implementación compleja).
Fuentes: enlace.
Un saludo.
jueves, 20 de septiembre de 2012
Nos gusta programar pero no documentar
Efectivamente, no nos gusta documentar. Esta afirmación llevo muchos años oyéndola, diciéndola y sufriéndola.
¿Porqué no nos gusta documentar?
Pues porque no nos proporciona ningún beneficio aparente. ¿Me cambia en algo la vida si documento 1, 2 o 700 páginas? Probablemente no.
Pero claro, esto es porque lo afirmamos mientras documentamos. Documentar no da el mismo tipo de satisfacción a los programadores que tirar líneas de código. ¿Qué pasa si dejamos pasar los años y tratamos de mantener un sistema sin documentación? Pueden pasar dos cosas:
Ahí está la clave: no se comenta el código para tener documentación, sino para acelerar los cambios en el código siempre que el objetivo del mismo ni sus circunstancias cambien. Si las circunstancias, la interrelación entre componentes, los requisitos, etc cambian...de poco me sirve el código ni sus comentarios.
Me hace mucha gracia quien afirma que la mejor documentación es el código. Me preocupa y me hace dudar de si esa persona ha mantenido proyectos grandes y antiguos. Las realidades de la empresa cambian, los programas y módulos con los que interactuamos cambian...los sistemas físicos en la empresa cambian. Tener que tirar del hilo del código y sus comentarios para tratar de deducir decisiones antiguas es agotador...e inútil. Porque es el pasado.
Hay quien afirma y afirmará que el código documentado lo es todo gracias a las habituales "balas de plata": patrones de diseño y arquitectura, buenas prácticas, estándares de desarrollo...Eso está muy bien para pequeños cambios y proyectos no muy antiguos. Pero la realidad es que todo eso ha cambiado en el tiempo. Lo que hoy nos parece la piedra filosofal, mañana estará obsoleto y habrá otros patrones, estándares, etc. Mantener código antiguo nos suele llevar a criticar a su autor, simplemente porque no entendemos las "balas de plata" de aquel momento (bueno, de acuerdo, a veces también hay código antiguo realmente horrendo).
Otro problema está en la dispersión y el tamaño. Está muy bien mantener código con comentarios de módulos pequeños, o sistemas concentrados. ¿Qué ocurre si mi código tiene millones de líneas de código, miles de módulos distribuidos en docenas de aplicaciones? ¿Qué ocurre si no tengo siquiera visibilidad de parte del código o de las aplicaciones porque son de otras empresas?
Aquí de nuevo entran en juego la documentación y los estándares. El primer punto a documentar es siempre las APIs o interfaces. Tanto si son nuestras como si no. Un fallo en el código no sabremos si es porque está mal implantada una API, si está con una versión obsoleta...a no ser que tengamos la documentación actualizada de esa API o interfaz. Los comentarios y la documentación, han de satisfacer objetivos diferentes.
Otra razón ineludible de documentar es la esencia misma de la orientación a objetos: abstracción, encapsulación, etc. Una capa de la arquitectura no puede saber de otra. Lo mismo las funciones o módulos. ¿Entonces cómo rastreo las decisiones que abarcan varios elementos si están dispersos y no saben unos de otros? ¿O es que tengo que hacer un "meta-comentario" (comentario de comentarios)? En realidad, esto que acabo de decir, no es ni más ni menos que la documentación que queremos evitar.
La mejor documentación, es la que está orientada a complementar al código y sus comentarios. Habitualmente, se hace a través de los entregables típicos:
¿Estoy diciendo que estos entregables deben hacerse? No, para nada.
¿Tienen que ser 3? Pues tampoco. El hacer 1, 2 o 3 documentos dependerá del contexto. Incluso un breve correo puede ser un análisis funcional de un pequeño cambio. Y no necesitas más. Dependerá de la metodología que se haya definido para el proyecto, el tamaño del mismo, la experiencia...
Lo que digo es que los anteriores son entregables típicos y satisfacen una necesidad. Pero una metodología que obliga de forma rígida (las que por desgracia se implantan en muchísimas empresas), son la causa de las críticas que hay hacia la documentación y hacia las propias metodologías. Si la metodología no se adapta a la realidad del proyecto, será un obstáculo, no un acelerador del trabajo.
¿Cuál es el límite? ¿Hasta dónde documentar? Eso, por desgracia, lo da la experiencia. Yo suelo dar en mis formaciones una máxima: si el analista técnico tiene dudas, es que el funcional necesita más. Si el programador no sabe qué hacer, seguramente el diseño técnico cojea.
Ojo: tampoco quiero decir que no contestemos a la persona que ha de continuar el trabajo. Yo por ejemplo, en un cliente, revisaba la documentación técnica con los programadores, y o bien modificaba el diseño técnico sobre la marcha, o directamente les indicaba cómo quería realizar las cosas, y ellos por un lado, y yo por el otro, seguíamos cada uno haciendo código/documentos. De hecho, algunos programadores terminaban llevando a cabo una solución ligeramente distinta: ellos después me explicaban el motivo, y yo adaptaba el documento a su realidad. Cuesta tiempo llegar a este nivel de colaboración, pero es un placer trabajar así. Das libertad a quien está a pie de teclado soltando código, y al final, lo importante, es que la documentación y el código no se descuadren, y que el equipo sienta que hay cierta libertad de hacer las cosas.
Y un apunte final: todo lo dicho aquí, sirve para cualquier ciclo de vida: cascada, iterativo, RUP, scrum, etc, etc. Siempre alguien tendrá que empezar a trabajar partiendo de algo que le habrán dado: un documento, una servilleta, un post-it en una pizarra...
![]() |
| La documentación debe estar al servicio del proyecto y no al revés |
¿Porqué no nos gusta documentar?
Pues porque no nos proporciona ningún beneficio aparente. ¿Me cambia en algo la vida si documento 1, 2 o 700 páginas? Probablemente no.
Pero claro, esto es porque lo afirmamos mientras documentamos. Documentar no da el mismo tipo de satisfacción a los programadores que tirar líneas de código. ¿Qué pasa si dejamos pasar los años y tratamos de mantener un sistema sin documentación? Pueden pasar dos cosas:
- Yo mismo soy el autor del código, y dependeré de mi memoria. Esto apenas me ha pasado el 10% de las veces (el mantener mi propio código pasado mucho tiempo). Y mi memoria, sobre lo cual me considero una persona normalita, no es capaz de retener todas las decisiones funcionales y técnicas que dan lugar a cientos, miles de líneas de código en cada proyecto.
- El autor del código no está. Bajo mi experiencia, esto me ha pasado alrededor del 90% de las veces. Bien porque he cambiado de empresa y tengo que lidiar con las perlas de otros, o bien porque la persona que lo hizo o empezó ya no está, y ahora yo tengo que mantener lo suyo. En este caso, dependeré de lo bien que el autor o autores lo hayan comentado. Pero como veremos a continuación, tampoco será de utilidad.
Ahí está la clave: no se comenta el código para tener documentación, sino para acelerar los cambios en el código siempre que el objetivo del mismo ni sus circunstancias cambien. Si las circunstancias, la interrelación entre componentes, los requisitos, etc cambian...de poco me sirve el código ni sus comentarios.
Me hace mucha gracia quien afirma que la mejor documentación es el código. Me preocupa y me hace dudar de si esa persona ha mantenido proyectos grandes y antiguos. Las realidades de la empresa cambian, los programas y módulos con los que interactuamos cambian...los sistemas físicos en la empresa cambian. Tener que tirar del hilo del código y sus comentarios para tratar de deducir decisiones antiguas es agotador...e inútil. Porque es el pasado.
Hay quien afirma y afirmará que el código documentado lo es todo gracias a las habituales "balas de plata": patrones de diseño y arquitectura, buenas prácticas, estándares de desarrollo...Eso está muy bien para pequeños cambios y proyectos no muy antiguos. Pero la realidad es que todo eso ha cambiado en el tiempo. Lo que hoy nos parece la piedra filosofal, mañana estará obsoleto y habrá otros patrones, estándares, etc. Mantener código antiguo nos suele llevar a criticar a su autor, simplemente porque no entendemos las "balas de plata" de aquel momento (bueno, de acuerdo, a veces también hay código antiguo realmente horrendo).
Otro problema está en la dispersión y el tamaño. Está muy bien mantener código con comentarios de módulos pequeños, o sistemas concentrados. ¿Qué ocurre si mi código tiene millones de líneas de código, miles de módulos distribuidos en docenas de aplicaciones? ¿Qué ocurre si no tengo siquiera visibilidad de parte del código o de las aplicaciones porque son de otras empresas?
Aquí de nuevo entran en juego la documentación y los estándares. El primer punto a documentar es siempre las APIs o interfaces. Tanto si son nuestras como si no. Un fallo en el código no sabremos si es porque está mal implantada una API, si está con una versión obsoleta...a no ser que tengamos la documentación actualizada de esa API o interfaz. Los comentarios y la documentación, han de satisfacer objetivos diferentes.
Otra razón ineludible de documentar es la esencia misma de la orientación a objetos: abstracción, encapsulación, etc. Una capa de la arquitectura no puede saber de otra. Lo mismo las funciones o módulos. ¿Entonces cómo rastreo las decisiones que abarcan varios elementos si están dispersos y no saben unos de otros? ¿O es que tengo que hacer un "meta-comentario" (comentario de comentarios)? En realidad, esto que acabo de decir, no es ni más ni menos que la documentación que queremos evitar.
La mejor documentación, es la que está orientada a complementar al código y sus comentarios. Habitualmente, se hace a través de los entregables típicos:
- Requisitos. Recogen a alto nivel las necesidades del sistema desde el punto de vista de cliente/usuario. Son las necesidades básicas. Podemos de alguna forma asimilarlas a las historias de usuario a muy alto nivel. Deben aclarar el qué se espera.
- Análisis funcional: Contienen el qué debe hacerse para lograr lo que espera el cliente. Es suficiente con definir lo que la parte de la documentación de diseño técnico ha de desarrollar.
- Diseño técnico: Si se da trabajo a un programador, un diseño técnico puede contener la resolución a problemas técnicos que se han previsto (los comentarios en el código ya comentan los problemas imprevistos).
¿Estoy diciendo que estos entregables deben hacerse? No, para nada.
¿Tienen que ser 3? Pues tampoco. El hacer 1, 2 o 3 documentos dependerá del contexto. Incluso un breve correo puede ser un análisis funcional de un pequeño cambio. Y no necesitas más. Dependerá de la metodología que se haya definido para el proyecto, el tamaño del mismo, la experiencia...
Lo que digo es que los anteriores son entregables típicos y satisfacen una necesidad. Pero una metodología que obliga de forma rígida (las que por desgracia se implantan en muchísimas empresas), son la causa de las críticas que hay hacia la documentación y hacia las propias metodologías. Si la metodología no se adapta a la realidad del proyecto, será un obstáculo, no un acelerador del trabajo.
¿Cuál es el límite? ¿Hasta dónde documentar? Eso, por desgracia, lo da la experiencia. Yo suelo dar en mis formaciones una máxima: si el analista técnico tiene dudas, es que el funcional necesita más. Si el programador no sabe qué hacer, seguramente el diseño técnico cojea.
Ojo: tampoco quiero decir que no contestemos a la persona que ha de continuar el trabajo. Yo por ejemplo, en un cliente, revisaba la documentación técnica con los programadores, y o bien modificaba el diseño técnico sobre la marcha, o directamente les indicaba cómo quería realizar las cosas, y ellos por un lado, y yo por el otro, seguíamos cada uno haciendo código/documentos. De hecho, algunos programadores terminaban llevando a cabo una solución ligeramente distinta: ellos después me explicaban el motivo, y yo adaptaba el documento a su realidad. Cuesta tiempo llegar a este nivel de colaboración, pero es un placer trabajar así. Das libertad a quien está a pie de teclado soltando código, y al final, lo importante, es que la documentación y el código no se descuadren, y que el equipo sienta que hay cierta libertad de hacer las cosas.
Y un apunte final: todo lo dicho aquí, sirve para cualquier ciclo de vida: cascada, iterativo, RUP, scrum, etc, etc. Siempre alguien tendrá que empezar a trabajar partiendo de algo que le habrán dado: un documento, una servilleta, un post-it en una pizarra...
jueves, 6 de octubre de 2011
Refactoritis
Hoy vamos a tratar una enfermidad muy común de los programadores "experimentados": La Refactoritis.
La refactorización se lleva haciendo durante décadas. No es algo nuevo, a pesar de que siempre se cite al bueno de Martin Fowler como referencia, en su libro "Refactoring: Improving the Design of Existing Code". Si no conocéis a Martin Fowler y os dedicáis a la informática, no sé a qué esperáis para leer este libro y saber un poco más de este autor.
La refactorización se define en la Wikipedia como "técnica de la ingeniería del software para reestructurar un código fuente, alterando su estructura interna sin cambiar su comportamiento externo". Es en estos momentos cuando muchos de vosotros estaréis asintiendo con la cabeza y pensando en frases como "pues yo refactorizo mucho o poco", "yo no lo veo una enfermedad", etc, etc.
¿Y qué sería en ese caso la Refactoritis? Pues la podríamos definir como el "trastorno compulsivo que deriva en el uso excesivo de la refactorización del código". Vamos, cuando se le va la mano al programador y no para hasta que ha llegado al final del código, y lo ha dejado todo "a su gusto".
Como hemos visto antes, la refactorización no cambia la funcionalidad. Es decir, no se aporta valor al producto desde el punto de vista de los requisitos. En la metodología SCRUM, estaríamos dedicando horas de trabajo sin implementar ninguna "historia de usuario". En realidad, sería una forma de procrastinación: no hacemos algo que se haya solicitado, sino que estamos haciendo algo que nos gusta o nos parece subjetivamente agradable o necesario. Por supuesto que habrá ocasiones en que sí se ha creado una tarea a realizar de refactorización, pero en esos casos nos deberíamos preguntar si realmente no deberíamos atajar la causa del problema: no generamos código de calidad según estándares, lo que obliga a refactorizar después.
La refactoritis deriva en múltiples problemas. Veamos primero las necesidades que nos pueden llevar a refactorizar el código, y vamos a discutirlas una a una:
- Calidad. Esta suele ser una de las excusas más usadas. Estamos creando calidad, mejorando la calidad. Y como no sabemos medir la calidad, no hay límite para nuestras ansias de refactorizar. Podemos seguir refactorizando hasta que nuestra sensación subjetiva de calidad consuma el tiempo de desarrollo. Algunos autores defienden que el código de calidad es bueno, y que mientras se satisfagan las pruebas unitarias, no pasa nada. El problema, es que las pruebas unitarias no son perfectas, lo que puede derivar en que a pesar de que "todo parece ir bien" tras refactorizar, en realidad estamos introduciendo bugs en el código.
- Mala planificación. En ocasiones, se planifica en exceso. Los programadores cuando se encuentran con que han terminado una tarea antes de la fecha planificada pueden hacer varias cosas. O buscan una nueva tarea, o tratan de llenar el tiempo de la tarea terminada. ¿Cómo? Pues refactorizando: mejorando comentarios, encapsulando, quitando código duplicado, etc.
- Eficiencia. Supuestamente, un código refactorizado es más eficiente. Además, se supone que se entiende mejor y es más claro. Esto último es muy dudoso, ya que es muy fácil refactorizar código y dejarlo de forma que sea muy compleja de entender. En este caso, si no medimos la eficiencia, ocurriría lo mismo que con la calidad. Podemos pegarnos la vida intentando ser más eficientes, que como no se mide esa mejora en eficiencia...no hay límites a nuestra refactoritis.
- Evolución. A veces, cambios en las normas de programación, en requisitos de calidad, etc., hacen que debamos refactorizar el código para que se cumplan las nuevas normas. Debemos recordar que salvo excepciones, el cliente paga por funcionalidades, no por la refactorización del código. Si no tenemos claras nuestras normas de desarrollo...mal asunto.
- Evitar la reescritura de código. Es muy discutible que un código refactorizado sea mejor que un código reescrito. Deben establecerse las necesidades, y evaluar qué solución merece la pena en uno y otro caso. Si refactorizar es la alternativa a la reescritura de código, en realidad tenemos un problema mayor: el mero hecho de plantearnos reescribir el código significa que un tiempo invertido en el desarrollo "va a la basura". Los paños calientes y las vendas no van a ocultar que tenemos un problema mayor.
- No tocar el código que no se ha solicitado tocar.
- No tocar el código para el que no se han definido pruebas (automatizadas o no).
- No tocar el código sin antes realizar un análisis del coste (horas necesarias) para su refactorización, y definirlo como una tarea. Sólo así podremos controlar el tiempo necesario en rehacer las cosas una y otra vez. No deberíamos dedicar más horas de las estimadas a refactorizar, ni tocar más código del inicialmente identificado. Si no conocemos el alcance de nuestras acciones, no sabemos hacia dónde vamos.
- El código se debe refactorizar ANTES de pasar las pruebas, en la actividad de verificación. Las pruebas son muy costosas (incluso automatizadas), por lo que deberíamos pensar dos veces antes de tocar un código que ha pasado ya las pruebas.
- No tocar el código que afecte a otros desarrollos (en curso o en producción), sin antes hacer una evaluación del impacto y recibir la aprobación correspondiente. En muchas ocasiones, algo que funciona correctamente según las pruebas unitarias, al subirlo a producción ROMPE OTROS DESARROLLOS con los que interactuaba.
lunes, 27 de junio de 2011
Patronitis
Al final no me he podido resistir. No podía dejarlo para mucho más adelante. Si ayer lo nombraba, hoy me apetecía hablar de una de las enfermedades más comunes de los desarrolladores de software: "la patronitis".
No os molestéis. Este término no aparece en ningún diccionario oficial. Sin embargo, sí puede encontrarse en diversos blogs y libros editados ya hace algunos años. Pero es estos días cuando parece estar más de moda.
En algún blog podemos ver una definición como:
Patronitis: N. fem. Dícese de la enfermedad propia de programadores que consiste en querer aplicar patrones de diseño a todo.
Sin embargo, no considero esta definición del todo exacta. He podido observar esta enfermedad también en analistas, arquitectos, y otras categorías supuestamente más experimentadas.
Normalmente el problema se debe a nuestra naturaleza friki innata, que nos reclama el uso de todo aquello que hemos aprendido, independientemente de su adecuación al caso. ¿Que no aplica? Pues da igual, se mete, aunque sea con calzador. Y así nos van las cosas. ¿Que se pone de moda la arquitectura de 14 capas? Pues se usa. Luego ya iremos eliminando cosas que realmente sobren. Y el problema es que siempre encontramos un uso para algo.
Una vez me enseñaron una regla de oro, de las que no se deberían olvidar nunca: "Un software no está completo cuando ya no se pueden añadir más funcionalidades, sino cuando no se puede eliminar ni una sola más".
Y es que al final, no es la experiencia en el desarrollo de aplicaciones mediante patrones y la aplicación de las diversas tecnologías lo que nos da la experiencia suficiente para saber dónde está el límite en el uso de los patrones. Es al tener que mantener esas aplicaciones, bien desarrolladas por nosotros mismos, o bien por otros, cuando vemos cuán complicadas son las cosas. Un buen artículo (con algunos añitos a sus espaldas ya), está en: http://www.javahispano.org/contenidos/es/el_peligro_de_los_patrones/
Este artículo es bastante conocido por internet, y tiene muchos seguidores y detractores. Allá cada cual.
Finalmente, para los que os gusta visualizar y ejemplizar las cosas, ahí va una perla: (extraída de: http://odetocode.com/Blogs/scott/archive/2005/11/22/2499.aspx):
Design Patterns: A Love Story
Richard tilted his head to watch the waves push flotsam against the boat hull below. Up and down, the flotsam moved. Up and down.Richard had an idea.
“Virginia, my dear”, he said to the blond woman beside him. “We’ve been singletons on this ship for a long time”.
“I know, Richard”, she replied. “My mean step-mother, the intercepting filter that she is, denies me time with others.”
Richard paused for a moment, to contemplate strategy. Her father, with his pipes and filters, would return soon, and force them to communicate over his message bus. He glanced aft, and saw no one else around. Richard turned his front controller to face Virginia, and looked her in the eyes. She was close now, and Richard could feel his active record rising.
“Virginia”, he whispered. “There is no observer in sight. Let us run below deck. I want to peel away your façade, and tightly couple.”
“Oh yes, Richard”, she blushed, and leaned towards him. “I want you to give me a dependency injection”.
[Actualizado el 19/02/2015:]
Acabo de ver en el blog de Javier Garzás, un artículo que me ha recordado éste mío. Javier incide en la idea que intento hacer ver en este post, y es que no hay balas de plata, y que las herramientas sólo deben aplicarse cuando aplica. Pero incluso cosas que parecen tan básicas que las tenemos como los cimientos de todo (véase la orientación a objetos, uso de patrones, etc). Si no nos replanteásemos las cosas de vez en cuando...seguiríamos en la prehistoria.
Suscribirse a:
Entradas (Atom)


