Diseño reincidente (I) - IntroMix 2010, filosofía zen, las articulaciones y el bambú
Más o menos a mediados de la década de los noventa del siglo pasado mi conocimiento del inglés era nefasto. Finalizada la primera década de este siglo no puedo decir que sea mucho mejor, aunque hoy en día puedo decir que entiendo bastante bien lo que leo e, incluso, lo que escucho. Pero entonces me costaba mucho más. Cediendo finalmente al deseo vocacional (originalmente quise estudiar Matemáticas Y —importante ese «y»— Física, pero decantándome por Ingeniería Industrial), acabé metido en Informática y, como todo buen «amante» de la misma, abracé temprano la Orientación a Objetos. Tan temprano como tuve conocimiento de ella (como una década y pico después de su «invención»). Y de esa manera un tanto atropellada y particular en la que yo abrazo las cosas, claro.
Dos libros fueron relevantes en esos tiempos: ‘Design Patterns: Elements of Reusable Object-Oriented Software’ y ‘Object-Oriented Software Construction’. El segundo lo pude sacar de la biblioteca de la escuela, mientras que al primero tuve acceso únicamente vía el préstamo de libros entre universidades y tras fotocopiarlo frenética y completamente en el plazo de los tres días que tenía para devolverlo a la universidad de Barcelona. Hoy en día tengo las versiones en castellano de ambos libros que apenas hojeo, pero que me gusta tener ahí como recordatorio de que fueron libros importantes en su momento. De hecho no descarto leerlos nuevamente, esta vez comprendiendo plenamente (espero) lo que cuentan. Confieso que he estado tentado de pedir las versiones originales por petardeo nostálgico.
Júntense ganas de aprender, juventud marcada por un desorden de capacidad de atención no diagnosticado (o con hormonas insaciables a la par que insatisfechas) y que la fuente de conocimiento estaba escrita en lengua bárbara y casi ininteligible, y no ha de resultar descabellado, impensable ni insólito que en mi cabeza se conformaran unas interpretaciones de los patrones de diseño [@ Wikipedia] y del diseño por contrato [@ Wikipedia (en)] bastante particulares que poco, o nada, tenían que ver con los originales. Exagero un poco, que ya se sabe que soy heredero de andaluces (y alemanes/holandeses e italianos, además de canariones, pero que no apartan demasiado a mi deseo perenne de exagerar). En el fondo creo que algo sí que entendí.
Mi juvenil testa se llenó de ideas un tanto alocadas que, a la primera de cambio, empecé a aplicar. Cuando en 2002 me encomendaron —en realidad casi me encomendé yo mismo aprovechando que era el jefe del proyecto— la tarea de diseñar el sustrato de un producto en el que trabajaríamos durante los siguientes años, empecé a aplicar todas esas ideas malinterpretadas, a la par que maravillosas, que se fueron concretando, en los siguientes años, en una serie de arquitecturas específicas. Cada una refinaba la anterior dejando atrás lo que no me gustaba y añadiendo lo que iba descubriendo/aprendiendo en el transcurrir de los meses. Puedo afirmar que los años comprendidos entre 2002 y 2005 fueron muy buenos años en lo referente a aprendizaje acelerado y exponencial de todas estas cosas que tanto me atraían.
Fue también en 2002 cuando empecé a abrazar, de la mano de Jose Miguel Santos —espero algún día escribir una entrada en su honor—, la filosofía de los test unitarios [@ Wikipedia (en)]. Entonces aún no había escuchado/leído nada de Mocks [@ Wikipedia (en)] ni de Stubs, así que acabé ingeniándomelas para montar tests que pudiesen cambiar/usar piezas de la arquitectura por otras que no hicieran gran cosa o que, en su defecto, trabajasen sobre versiones de datos embebidas. De hecho, los primeros desarrollos de las aplicaciones siempre las basábamos en Bamboo.Prevalence [@ Sourceforge], una adaptación para .Net de la idea original que tuvo Klaus Wuestefeld [su idea] y que se concretó en System Prevalence [@ Wikipedia (en)] de persistencia. De esta forma, además de forzarnos a pensar en las operaciones del sistema como comandos [@ Wikipedia], podíamos posponer las preocupaciones de las las particularidades del diseño usando un sistema de almacenamiento relacional. (¿A alguien se le escapa a estas alturas que Hibernate [Pagina oficial] intenta precisamente solventar el salto semántico entre el modelo de orientación a objetos y el modelo relacional?)
Otra de las cosas que sucedieron en 2002 fue que caí —en este caso era reacio a abrazar— en las redes de .Net. Yo quería a toda costa hacer el proyecto con Java, pero el entonces presidente de la compañía en la que trabajaba dijo que C# «era el futuro». Cosas peores se han dicho y afirmado durante la Historia de la Humanidad (del estilo «¡La virgen se me ha aparecido y me ha hablado!»), pero he de reconocer que al final a mí me gustó mucho C# y le agradezco que me forzara y me violentara en aquella ocasión y de esa forma. Aunque luego demostró equivocarse en todas las demás predicciones que preconizó. Y fueron muchas. Anecdóticamente, pasados unos años, llegó un día, levantando los brazos cual predicador que dirige su discurso a un Dios magnánimo que lo ilumina e impregna de sabiduría, y exclamó que Java era el futuro y que C# era un subproducto de Microsoft. «Vete a tomar por donde amargan los pepinos», fue mi respuesta.
El gradiente resultante de la multiplicación de todas estas fuerzas se concretó en el uso a destajo de las interfaces. Venía de varios años programando en Delphi [@ Wikipedia] y apenas había tenido tiempo de profundizar ampliamente en Java cuando me vi arrastrado a usar C#. Me enamoré de las interfaces tan pronto las comprendí (las de Delphi entonces no eran verdaderas interfaces). Y, por mucho que digan los que lo defienden, una clase abstracta no es lo mismo. Ya explicaré por qué yo creo que no son lo mismo, aunque reconozco que hay un elemento de gusto particular en ello. Solo para empezar, y dados los lenguajes de los que estamos hablando (C# y Java), la herencia múltiple no existe y te queda usar interfaces. Pero yo no uso apenas herencia múltiple.
Con este plan, lo primero que hago siempre es escribir todas las interfaces de todos los elementos que creo son susceptibles de presentar algún cambio y de las entidades arquitectónicamente relevantes. Hablando un día con Esteban [HCoder.org], en nuestros años de universidad, usó una de las mejores metáforas que he escuchado hasta la fecha para explicar la flexibilidad que se puede conseguir con un buen diseño orientado a objetos. Ponía como ejemplo las articulaciones del cuerpo humano y que un buen diseño tenía que ser articulable para ganar en flexibilidad. Imaginen un brazo que únicamente tuviera un hueso que uniese el hombro con la mano pero respetase la longitud total. Para que se hagan una idea, intenten rascarse la nariz con el brazo recto (como si estuviera escayolado de extremo a extremo) sin doblar el codo. Con suerte, dada la longitud, con un brazo tan poco flexible llegarían a rascarse el culo, pero habría que pedirle a otro que te rascara la nariz.
A la metáfora anterior yo le suelo añadir otra que me contó otro amigo, Juan Manuel, cuando apenas teníamos dieciséis o dieciocho años y que, por las edades de las que hablo, no tenía nada que ver con la programación ni la orientación a objetos y sí mucho con los desamores de juventud. Era esa del roble, el bambú y la tormenta. Internet está plagada de adaptaciones de la parábola al alcance de un googlazo (acabo de acuñar un nuevo término), así que no necesito profundizar más.
Cuando explico a alguien la importancia del diseño y de las decisiones tomadas, la conclusión es que el software (el código) supera mejor la adversidad (la tormenta) cuando es flexible. Esto significa que no necesariamente hay que recubrirlo de capas y de capas de robustez para que sea impenetrable. Simplemente hay que hacerlo crecer entre tormentas frecuentes (los tests unitarios) para que gane en sabiduría y fortaleza. La sabiduría es el conocimiento destilado hasta alcanzar la utilidad imprescindible para ser aplicable, desproveyéndolo de toda terquedad e información innecesaria. El código fuente no deja de ser una forma de conocimiento tácito (un modelo escrito de cómo funcionan las cosas), por lo que un código fuertemente testado es un código que desarrolla los elementos justos y necesarios, y no más, para funcionar en condiciones adversas. Por eso mismo empiezo siempre escribiendo únicamente las interfaces, que meto todas —a modo de licencia poética de inspiración meyeriana— dentro de un subdirectorio que denomino “contratos”. Todas esas interfaces representan las articulaciones, los elementos funcionales susceptibles de ser ampliados, modificados o eliminados en el transcurrir de las siguientes decisiones (también en 2002 comencé a abrazar la filosofía ágil [@ Wikipedia]). No escribo nada sin tener la interfaz antes. Matizando lo que defiende la idea del «Test First» [@ Wikipedia], yo hago «Interface first, then Test… Or not». Pero eso es otra historia.
[Continuará …]
Esta entrada ha sido importada desde mi anterior blog: Píldoras para la egolatría
Es muy probable que el formato no haya quedado bien y/o que parte del contenido, como imágenes y vídeos, no sea visible. Asimismo los enlaces probablemente funcionen mal.
Por último pedir diculpas por el contenido. Es de muy mala calidad y la mayoría de las entradas recuperadas no merecían serlo. Pero aquí está esta entrada como ejemplo de que no me resulta fácil deshacerme de lo que había escrito. De verdad que lo siento muchísimo si has llegado aquí de forma accidental y te has parado a leerlo. 😔