jump to navigation

Antipatrones en arquitecturas de varios niveles Enero 25, 2010

Posted by ravelus in Informática.
add a comment

Cuando se trabaja con arquitecturas de varios niveles, hay ciertas consideraciones a tener en cuenta que tienen que ver con la consistencia de los datos, el uso de objetos distribuidos y la concurrencia, que de no estudiar apropiadamente pueden dar más de un quebradero de cabeza durante el mantenimiento de la aplicación.

Lo primero a tener en cuenta es la diferencia entre capa y nivel. Habitualmente una aplicación bien diseñada tendrá varias capas con dependencias cuidadosamente definidas. Dichas capas pueden estar ubicadas en un sólo nivel o estar diseminadas en varios niveles. Digamos que una capa es un concepto organizacional de la aplicación, mientras que un nivel denota una separación de componentes que pueden estar (o de hecho están) separados en distintos soportes físicos.

Toda aplicación que interactúa con una base de datos tiene más de una capa, a no ser que la base de datos esté embebida en el propio proceso de la aplicación. Otro ejemplo de arquitectura multinivel sería una aplicación web que involucra a una base de datos, un servidor y un navegador.

Sin embargo, no nos referiremos a estos ejemplos tan simples como arquitecturas multinivel. El primero de los ejemplos es un caso muy simple y común, y no se suele considerar a efectos prácticos un caso multinivel por estar presente casi siempre. El segundo caso plantea una situación también muy común, además a todos los efectos el servidor web y el cliente pueden ser entendidos como un nivel de cliente.

¿A qué casos nos referimos, pues? A casos donde participan servicios web u otro tipo de servicios que se proveen entre distintos módulos. Típicamente, una arquitectura multinivel constará de, como mínimo, un nivel de base de datos, un nivel intermedio que expone un servicio y un nivel de cliente.

Planteados estos conceptos, el primer consejo sobre la distribución de objetos en arquitecturas multinivel viene de la mano de Martin Fowler en su libro “Patterns of Enterprise Application Architecture” (Addison-Wesley, 2002): ¡No distribuyas tus objetos!. Bien; si tomamos esta afirmación como cierta cerramos el artículo y nos vamos a tomar un café.

No, no nos vamos a tomar un café, y no es que vengamos a afirmar que Martin Fowler está equivocado, sino que simplemente hay situaciones donde esta ley debe quedar a un lado. Sí es cierto que es muy recomendable considerar y controlar los objetos que se distribuyen entre los distintos niveles y reducirlos en cantidad y tipología en la medida de lo posible, pero reducirlos a cero lo dejaremos como una utopía que no es viable en muchas situaciones. Vamos, pues, con los antipatrones:

Fuerte acoplamiento

Todos sabemos que el acoplamiento entre subsistemas, paquetes y en general módulos de nuestros sistemas debe ser el mínimo posible y lo llevamos a la práctica, ¿verdad? De acuerdo. Sin embargo, aunque seamos tan buenos arquitectos software hemos de reconocer que mantener un acoplamiento bajo conduce a soluciones complejas y en ocasiones poco eficientes. ¿Por qué introducir una dependencia mediante una interfaz cuando podemos simplemente crear una instancia del objeto de la clase directamente? Sin embargo, los beneficios de un acoplamiento bajo vienen a la larga, cuando nos movemos en los términos de mantenibilidad y extensibilidad.

Cuando trasladamos el problema del acoplamiento a sistemas multinivel, el problema se hace más grande. Imaginemos que tenemos que cambiar un nivel, pongamos el nivel medio. ¿Qué ocurre si el acoplamiento de nuestro sistema afecta al nivel de cliente? Habremos de cambiar todos los clientes… El truco aquí está en identificar grupos de módulos que cambian con una frecuencia similar; es imposible evitar que haya dependencia entre niveles, pero si agrupamos correctamente los niveles, podremos mantener una afectación entre niveles mínima.

Asumir requisitos estáticos

Bueno, ya conocemos que los requisitos son cambiantes, pero tampoco podemos vivir con fobia a los requisitos. ¿Qué es susceptible de cambiar?

Según el autor, hay dos aspectos fundamentales que suelen hacerse mal cuando se considera la estabilidad de los requisitos: pensar que el cliente es fiable e inamovible por un lado; por otro, hacer que el servicio que provee el nivel intermedio asuma que el cliente será implementado utilizando una determinada tecnología.

El primer problema se hace patente cuando, por ejemplo, se validan datos únicamente en el cliente, asumiendo el nivel intermedio que lo que le llega es pescado fresco del día, procesándolo y enviándolo a la base de datos. Esta consideración acarrea más problemas de los que se pueda pensar, más aún cuando el servicio que ofrece el nivel intermedio puede ser utilizado por más clientes de los cuales no teníamos constancia previamente.

En cuanto al segundo caso, sabemos que la tecnología siempre cambia. Protege tu arquitectura para que si el día de mañana el nivel de cliente deja de ser un navegador web para ser una aplicación para teléfono móvil o una aplicación Silverlight no trastoque todo tu sistema.

Concurrencia no manejada

Un error en la concurrencia es el típico problema que sólo se detecta cuando el sistema ya está en producción. De los divertidos. Y si el problema se manifiesta como un fallo con luces de colores y pantallazos con mensajes de error, vamos listos. Lo mejor es cuando estos fallos producen corrupción en los datos y el problema perdura en el tiempo hasta que finalmente es detectado.

La gestión de la concurrencia suele hacerse de forma optimista: en el supuesto caso de que varios clientes tuvieran que acceder a la base de datos simultáneamente, el número de veces que tienen que modificar la misma entidad surgiendo conflictos de consistencia es muy pequeño.

El Entity Framework da un soporte de concurrencia bastante optimista; mediante el seguimiento del valor original del valor a modificar cuando dicho valor es consultado y buscando conflictos antes de realizar un update. El problema en una arquitectura multinivel estriba en que este proceso es transparente siempre y cuando se utilice una misma instancia de ObjectContext desde el cual se consulta el valor hasta que éste es almacenado con SaveChanges. Si se serializan entidades de un nivel a otro lo recomendable es pasar el contexto entre niveles mientras dure la llamada al servicio que provee el nivel intermedio. De esto se desprende que debería crearse un nuevo contexto para cada llamada al servicio.

El problema viene porque mientras se trabaja en este modo “en-desconexión” (desconectado en el sentido de que las entidades están desconectadas de su contexto tras la consulta, enviadas a otra capa y después reconectadas cuando hay que modificar los datos mediante un update) ocurre lo siguiente:

1.- Se consulta la entidad y se serializa al nivel de cliente.

2.- El cliente recibe la entidad, realiza los cambios que tenga que hacer y envía de vuelta la versión modificada a la capa intermedia.

3.- Ya que nadie mantiene una traza de la concurrencia o de las propiedades que han sido modificadas, el servicio vuelve a consultar a la base de datos para conocer el estado actual de la entidad, creando un nuevo contexto para dicha consulta.

Después se comparan los valores de la entidad guardada y la que llega del cliente.

4.- El servicio llama a SaveChanges, que verifica si ha de hacer persistentes los cambios o no.

De este flujo surgen dos problemas fundamentales:

El primero es que cada vez que se modifica una entidad, hay que leer de la base de datos dos veces su valor, con el coste que eso supone.

El segundo y más importante es que el valor “original” utilizado por el Entity Framework para verificar si la entidad ha sido modificada en la base de datos viene de una segunda consulta en lugar de la primera consulta. ¿Qué ocurre si entre los pasos 1.- y 3.- alguien modifica el valor?

El sistema no detectará esta situación, detectará un cambio en el valor leído y tratará de almacenar el nuevo valor.

La solución para ambos problemas pasa por realizar una copia del valor leído en el cliente y enviarlo de vuelta junto con el valor modificado al nivel intermedio. Cuando dicho nivel recibe ambos valores, compara y decide.

Servicios con estado

Del antipatrón anterior se deduce que una buena idea para solucionar algunos problemas de concurrencia es pasar el contexto entre las distintas capas.

Lo que ocurre es que esta solución puede convertirse en una pesadilla rápidamente cuando se traslada a la práctica. Colisiones, manejo de múltiples contextos… Cada vez que se realiza una llamada al servicio, el nivel intermedio debe procesar la llamada, solicitar los recursos necesarios, y después liberar dichos recursos. Si podemos hacer que dicha información se mantenga en el cliente en lugar de en el nivel intermedio, de modo que no haya problemas con el manejo de múltiples sesiones (de múltiples llamadas) el cliente se encarga de liberar los recursos y gestionar sus propias llamadas, y además no se consumen recursos del servidor para dar servicio a un cliente.

Dos capas que pretenden ser tres

Simplificar el proceso: Si creamos un ObjectContext en el nivel de cliente, ejecutamos una consulta para cargar las entidades en dicho contexto, modificamos dichas entidades y después las guardamos mediante SaveChanges (lo que provocará un update), ¿para qué tener el nivel intermedio?

Ten siempre en cuenta la ley de Fowler. La única razón para tener una arquitectura multinivel es porque realmente es necesario: bien porque necesitas más seguridad o la posibilidad de escalar en múltiples servidores, o lo que sea. Si no, no utilices arquitecturas multinivel.

Puedes estar perdiendo todo el tiempo que quieras modelando una arquitectura meticulosamente diseñada, con múltiples niveles, totalmente independientes y todo lo que se te ocurra. Pierdes todo el tiempo creando una infraestructura superior y te das cuenta de que no has dedicado un segundo en trasladar un valor realmente útil a los usuarios.

Céntrate en tus objetivos y considera si es necesario una arquitectura multinivel. En ocasiones una arquitectura de dos niveles es suficiente.


Referencias
“Anti-Patterns To Avoid In N-Tier Applications”
Danny Simmons
MSDN Magazine
Junio 2009

Solución al problema de los filósofos comensales con la biblioteca Asynchronous Agents Enero 13, 2010

Posted by ravelus in Informática.
add a comment

La librería Asynchronous Agents de Visual C++ 2010 permite dar solución al problema de los filósofos comensales sin utilizar semáforos, monitores, bloqueos ni nada de esto directamente, sino simplemente utilizando un sistema de paso de mensajes síncronos y asíncronos. Esto facilita mucho la implementación puesto que podemos centrarnos en las abstracciones del problema y despreocuparnos bastante de los problemas de concurrencia y bloqueo mutuo.

Los filósofos comensales

Empecemos repasando el problema de los filósofos comensales. Recordemos que este problema planteado por Djikstra planteaba una mesa a la cual se sienta un determinado número de filósofos que se pasan el tiempo pensando o comiendo, de forma alternativa, de un gran bol de arroz que se encuentra situado en el centro de la mesa. Para ello, los filósofos necesitan tomar un par de palillos, uno que se encuentra a su izquierda y otro a su derecha. El problema es que no hay palillos para todos, de manera que a cada lado de cada filósofo se encuentra solamente un palillo. Hasta que un filósofo no tiene los dos palillos no puede empezar a comer. Cuando un filósofo desea pensar, deja cada palillo a cada lado, y deja de comer. El problema del bloqueo mutuo en este planteamiento viene si todos los filósofos cogen uno de los palillos, puesto que jamás podrán coger el otro palillo, que está ocupado por otro filósofo, produciéndose una espera indefinida. ¿Cómo coordinamos a los filósofos para que puedan comer y pensar sin problema?

Cómo resolver el problema con Asynchronous Agents

En este problema, los filósofos serían hilos independientes que tratan de acceder a un recurso compartido, representado por los palillos. Cada filósofo solamente tiene constancia de los dos palillos que hay a ambos lados de su plato, siendo el resto invisibles para él.

El problema así puede ser resuelto con cuatro entidades:

  • Una clase Chopstick, que representa a cada uno de los palillos situados en la mesa.
  • Una clase ChopstickProvider, que se encarga de mantener los palillos en la mesa y asignárselos a los filósofos.
  • Una clase Philosopher que es responsable de pensar y comer y es consciente solamente de dos ChopstickProviders.
  • Una clase Table que representa a la mesa y que contiene un conjunto de Philosopher, otro de Chopstick y otro de ChopstickProvider.

Es posible que a la hora de la implementación nos demos cuenta de que alguna de estas clases puede ser colapsada en una estructura de datos o algo más sencillo, dependiendo de la funcionalidad que pueda proveer.

Evitaremos de aquí en adelante todo detalle de implementación, limitándonos simplemente a decir cómo podemos utilizar la biblioteca Asynchronous Agents para resolver el problema de los filósofos comensales.

Envío de mensajes

Los ChopstickProviders pueden ser implementados utilizando colas de llamadas:

  • Concurrency::send para enviar un mensaje a una cola o buffer de mensajes; se espera un ACK del envío.
  • Concurrency::receive para recibir un mensaje; se bloquea hasta que recibe un mensaje.
  • Concurrency::asend, como send pero asíncrono.
  • Concurrency::try_receive, como receive pero no se bloquea hasta que haya un mensaje en la cola.

Los filósofos

Pueden ser implementados como agentes, derivar de una clase abstracta llamada Concurrency::agent, e implementar el método run(). Durante el ciclo de Comer() y Pensar() se puede realizar una espera aleatoria o cualquier otra cosa.

La sincronización

Viene provista de la llamada Concurrency::join, que puede soportar distintos tipos de fuentes de mensajes o solamente el mismo tipo de fuente; además puede realizar un uso glotón de los mensajes que llegan (consumiéndolos a medida que llegan) o no (esperando a que todos los mensajes requeridos lleguen). Es fácil ver que para esta solución necesitamos utilizar la alternativa de un simple tipo de fuente y no glotona, precisamente para evitar el problema del bloqueo mutuo.

Los detalles de la implementación de esta solución se encuentran en el artículo que se referencia debajo.


Referencias:

“Solving the Dining Philosophers Problem With Asynchronous Agents”
Rick Molloy
MSDN Magazine
June 2009

Moby Dick Enero 5, 2010

Posted by ravelus in Cultura.
3 comments

Por fin terminé esta novela de Herman Melville que me ha llevado meses terminar.
Lamentablemente tengo que decir que la excusa de semejante tardanza es lo tremendamente aburrida que me ha parecido. Y es que a veces los clásicos a veces son un tostón, por muy trascendentales que hayan sido después en la historia de la literatura. De este libro lo único que destaca, bajo mi ignorante punto de vista, es su enorme influencia en obras posteriores, destacando sobre todas ellas la de Ernest Hemingway, El viejo y el mar, una obrita que no va de policías y ladrones, códigos y da Vincis, sino de sentimientos, anhelos y metas que uno se impone en la vida; cómo se lucha por llegar a dichas metas, y cómo a veces todo se acaba yendo a la mierda.

Comencé precisamente a leer esta obra por el enorme poder que ha tenido sobre obras posteriores, el omnipresente personaje de Ahab (¿quizá un juego de palabras con el rey Acab, uno de los muchos pérfidos reyes hebreos que surgieron tras la época dorada del rey David y su hijo, Salomón?) como el del viejo chiflado, pero un chiflado peligroso, pues arrastra al resto de la tripulación del Pequod a su trágico destino, del cual un marinero poco más que grumete, Ismael, reflejo del propio autor, se salva. La intención es buena, pero el libro se convierte en un tostón de casi quinientas páginas y cientoveinticinco capítulos en los cuales se explica las diferencias entre la ballena y el cachalote, su caza, su fisonomía,  su comportamiento y hasta la forma que tiene el chorro de agua que emite de su válvula dorsal; encuentros con otros barcos balleneros, tradiciones balleneras en otros países y demás eventos sin la mayor relevancia.

Si algo positivo de ello saco es que he aprendido cómo se cazaban ballenas en la época; probablemente no me vaya nunca a sacar de un apuro, y tampoco te importe un comino, amable lector, pero te vas a joder y te lo voy a contar: resulta que no se lanzaban arponazos desde el propio barco ballenero, como pensaba yo, sino que cuando se avistaba una ballena se bajaban unos botes empujados por un grupo de remeros, liderados por un piloto que dirigía el remo de timón y exhortaba al resto, y uno o dos arponeros. Los arpones, por tanto, se lanzaban desde los propios botes, e iban atados con una cuerda cuyo otro extremo iba a parar al propio bote, de manera que una vez el arpón alcanzaba al animal, éste remolcaba al bote durante unos cuantos cientos de metros hasta que finalmente moría. Tras su muerte el animal flotaba, y la tripulación esperaba al barco ballenero para poder remolcar e izar el enorme bicho al barco, como buenamente podían, para evitar lo que de otro modo sería un festín de tiburones.
Como se puede imaginar, cada fase de la caza de la ballena era tremendamente complicada y arriesgada, desde remar a más no poder para alcanzar al titánido marino, sin olvidar el peligro de remar entre tiburones que solían circundar por tales lares, mordisqueando los remos en ocasiones, como ofrecer una buena posición desde el bote para que el arponero pueda atacar a su presa, sin olvidar los posibles coletazos del animal que en innumerables ocasiones acababa con más de un marinero nadando entre tiburones o con el bote partido en dos. Después había que descuartizarlo en cubierta, con la bestia levantada por una especie de grúa, mientras un marinero experimentado desollaba al animal sujeto en vilo por una cuerda enrollada alrededor de su cuerpo que era sujetada por otro marinero en cubierta, el cual, a su vez tenía la cuerda enrollada a su cintura. Si la polea fallaba, los dos acababan en el mar, desdedonde tendrían seguramente el placer de nadar entre tiburones, siempre presentes ante la sangre y la carroña. De este modo se aseguraban que cada uno hiciera su cometido con la mayor presteza posible y no se le ocurriera hacer el gracioso.

Sin embargo, a pesar de que el hilo argumental es lento a más no poder, hay otra cosa a destacar del libro, aparte de lo que he aprendido sobre el mundo marino: los tres últimos capítulos: “La caza, primer día“, “La caza, segundo día” y “La caza, tercer día“, donde por fin la acción se desencadena cual vehículo de carreras sin frenos, sucediéndose todo el meollo de la novela vertiginosamente, magistralmente, en un cúmulo de descripciones que nos transporta mágicamente al lugar, a sentir lo que los personajes sienten, arrepentimientos, miedos, osadías, valentías, respeto y muerte. Para un lector que desee conocer la obra, realmente no tiene más que leer estos tres últimos capítulos. No conocerá a los personajes, pero creo que no será un inconveniente demasiado importante. Merece la pena realmente leer estos tres últimos capítulos porque vienen a significar, realmente, por qué Moby Dick está entre los grandes clásicos.

Por cierto, una nota para la gente de Edicomunicación S.A.: revisen mínimamente sus publicaciones, hablen con la traductora responsable o con quien sea; es rotundamente inaceptable que un libro de menos de 500 páginas tenga más de 3000 erratas, algunas sin sentido en absoluto. Lamentable.

Monitorizar el uso de memoria de nuestras aplicaciones .NET Diciembre 29, 2009

Posted by ravelus in Informática.
add a comment

En aquellas aplicaciones de cierto tamaño, donde el consumo de memoria se convierte en un tema a tener en cuenta, es importante que se considere el consumo de memoria desde las primeras fases de diseño de la aplicación, o las consecuencias después serán peores y más difíciles de arreglar, como veremos a lo largo del presente artículo. Típicamente, las aplicaciones se pueden clasificar en pequeñas (<20Mb e consumo de memoria RAM), medianas  entre 20Mb y 50Mb) y grandes (>50Mb). Cuanto mayor es el consumo de memroria de una aplicación, más  mportante es tenerlo en cuenta desde las primeras fases de diseño de dicha aplicación.

¿Cómo afecta el uso de memoria al desempeño?

Recordemos que un computador normal tiene al menos 3 niveles de memoria: L1 y L2 que son típicamente cachés on-chip, de baja capacidad y muy rápido acceso, una posible L2 on-board y la propia memoria RAM. Después está el disco, pero si estamos contando con él como sistema de memoria estamos perdidos, pues su velocidad de acceso es  0.000 veces más lento que el de una RAM.

Existen tres tipos de cuellos de botella a tener en cuenta para toda aplicación:
- Rutas de acceso a datos que se utilizan continuamente, y que deberán ser traídos continuamente como operandos a las cachés. Si estos conjuntos de datos son muy grandes, no podrán ser ubicados en las cachés de una forma más o  menos permanente y útil para el desempeño.
- Primer arranque de una aplicación. Lo que se conoce como “arranque frío”. El problema de este arranque es que  todos los datos del programa deben ser traídos de disco. El desempeño se ve afectado aquí por los datos e  instrucciones que utiliza el propio programa, no la memoria que va a utilizar, el montículo o la pila de llamadas, detalles que son gestionados por el sistema operativo.
- Cambios de aplicación. En un entorno típico multitarea donde conviven varias aplicaciones en memoria y se dan los fenómenos de concurrencia y planificador en la CPU, cada vez que se cambia de aplicación por parte del usuario para trabajar en dicha aplicación se produce un robo de memoria entre aplicaciones, lo cual se traduce en un intercambio a disco de las páginas que deben ser desalojadas para que sean utilizadas por la nueva aplicación que tiene el “foco”. Este consumo afecta no solamente a los datos del programa e instrucciones como ocurría en el caso anterior, sino a  toda la memoria que utiliza un programa, pues las páginas que se trasladan contienen datos, pila, etc.

¿Qué puedo hacer para mejorar el consumo de memoria de mis aplicaciones?

Existen tres modos en los que se puede pellizcar un poco el uso de memoria. Todos ellos se ven afectados por el  diseño de los propios algoritmos, que son los que dictan cómo se accede a memoria.
- Ejecutar menos código al inicio, lo cual favorece el arranque frío.
- Tocar menos datos, lo cual favorece el primer factor que explicamos antes.
- Modificar las estructuras de datos para utilizar otras más eficientes, que también favorece el primer factor.

La mayor parte de las veces lo que se suele hacer es optar por la tercera solución, lo cual implica retocar sensiblemente el código, con los costes que ello conlleva, no sólo de rediseño, y desarrollo sino que también de  testing. Es por esto por lo que es importante pensar en la eficiencia de la memoria desde las primeras fases de desarrollo si preveemos un consumo de memoria importante, porque luego pueden venir los problemas.

Monitorizando procesos

Para monitorizar procesos, se puede utilizar el Task Manager como primera aproximación. Esta herramienta nos aportará valiosa información de cada proceso, como PID, memoria compartida y memoria privada.

La memoria compartida de un proceso se refiere generalmente a las instrucciones, que son de sólo lectura. La  memoria privada, por otro lado, está constituida principalmente por los datos locales de cada proceso, que son datos de lectura y escritura. Sin embargo, hay un tipo de memoria que no aparece en el Task Manager y que hay que tener en cuenta, precisamente porque es el mayor cuello de botella de todo proceso: el sistema de ficheros. Cada vez que se accede al sistema de ficheros se incurre en una penalización notable en el rendimiento del proceso que en muchos casos es inevitable.

Otra herramienta más avanzada para la monitorización del uso de memoria es VADump, que aporta información hasta el nivel de DLL’s.
En el artículo que se referencia más abajo encontrará más información acerca de esta herramienta.

El recolector de basura de .NET.

El recolector de basura elimina regiones de memoria que no son utilizadas más por un proceso. Existen algunas posibilidades de manipulación del recolector que permite mejorar el consumo de memoria. Para ello hay que entender cómo se organiza dicho recolector en .NET.

Una optimización muy importante es que el GC no busca en todo el montículo de objetos cada vez que es ejecutado, sino que divide el montículo en tres “generaciones”:

- GC0: la más pequeña y rápida, solamente busca candidatos a limpiar entre las nuevas localizaciones ocupadas de memoria tras la última pasada del GC. Idealmente, el tamaño de esta generación es menor que la L2.
- GC1: selecciona las localizaciones que sobrevivieron a la última pasada del GC. Es más lento de ejecutar que la GC0.
- GC2: recorre todos los objetos. La más lenta, por tanto, de hecho el tiempo que tarda en pasar es significativo. Este tiempo que tarda en recorrer todos los objetos crece de una forma más o menos lineal con el tamaño del montículo. El coste real depende de la cantidad de memoria que sigue estando ocupada por el proceso, el número de punteros del GC a dicha memoria y cómo de fragmentado esté el montículo.

Una herramienta que permite monitorizar con precisión el uso del GC es PerfMon. Para más información acerca de dicha herramienta, léase el artículo que se referencia al final.


Referencias:
“Memory Usage Auditing for .NET Applications”
Subramanian Ramaswamy & Vance Morrison
MSDN Magazine
June 2009

Antipatrones: el blob Diciembre 20, 2009

Posted by ravelus in Informática.
add a comment

Sigo leyendo e informándome acerca de patrones. El libro que estoy leyendo, cuyo título aparece referenciado al final del artículo, es de los mejores que he leído de informática y gestión de proyectos, estoy encontrando cosas muy interesantes y creo que se le puede sacar bastante partido. Publicaré todos los antipatrones que pueda, al menos los que encuentre más ilustrativos y curiosos.

El Blob (*)

Yo lo llamo el “monstruo” o el “bicho”, porque viene a ser precisamente eso, una cosa gigantesca y poco manejable. Una evidencia de que estamos ante la presencia de un Blob es cuando alguien dice “esta es la clase que representa el núcleo de la arquitectura“. Malo. Desconfiar de ello.

El blob se encuentra en sistemas donde una clase monopoliza el procesamiento y el resto de las clases básicamente se limitan a encapsular datos. El problema es que la mayoría de las responsabilidades están contenidas en una sola clase. Esto provoca que modificar el blob implique modificar otras muchas clases.

Al final, el blob se convierte en una clase procedural disfrazada de orientación a objetos. Puede ser resultado de una localización inapropiada de los requisitos. Suelen aparecer como clases controladores o manejadoras / gestionadoras.

También puede aparecer en prototipos evolutivos, al crecer éstos. No se reparten responsabilidades y un módulo va asumiendo todo. Además, debido al mantenimiento, se va acumulando código útil mezclado con código que ya no sirve para nada. Esto mismo se da en sistemas incrementales, por la misma razón.

Síntomas

- Clases con muchos atributos y/o métodos.

- Dispar colección de atributos / métodos sin aparente relación entre sí (falta de cohesión).

- Una única clase controladora asociada con clases simples de datos.

- Ausencia de diseño orientado al objeto. El blob parece más bien un Main().

- Un diseño legado que no ha sido correctametne refactorizado en una arquitectura orientada a objetos.

Consecuencias

- El blob es típicamente demasiado complejo como para ser reutilizado y probado.

- Puede afectar gravemente al rendimiento al cargar un objeto tan grande en memoria probablemente utilizar un gran número de recursos.

Causas

- Falta de arquitectura orientada al objeto, o de una arquitectura consistente y estable en general.

- Intervención limitada: cambios en el código tienden  a añadir sobre lo que ya hay, en lugar de crear nuevas clases y rediseñar / refactorizar.

- Especificación inadecuada: captura de requisitos incompleta o no adecuada.

No es una mala práctica porque…

Es aceptable cuando se adaptan sistemas legados no orientados a objetos. No se requiere refactorizar el código, sino hacerlo más accesible al sistema legado.

Solución refactorizada

Mover código fuera del blob. Identificar y categorizar atributos y operaciones, según la cohesión. Buscar alojamiento para dichos atributos y métodos en clases apropiadas. Eliminar redundancia en las asociaciones que ya no son necesarias y reducir el acoplamiento. Extraer herencia y abstracción allí donde sea necesario. Estudiar las comunicaciones entre clases, paso de parámetros, etc.

Variaciones

- Transformar el blob en una clase coordinadora, que gestiona cómo hacen el trabajo los demás, delegando dicho trabajo en las clases de este modo coordinadas. De manera que el blob no es un ejecutor, sino un coordinador.

- El blob puede presentarse también como un centro de almacén de datos compartido por muchas clases, aunque no realice procesamiento alguno con dichos datos;  algo así como un repositorio de datos en memoria, una sección de memoria compartida gigantesca e inapropiada.

(*)No confundir con el tipo de datos para el almacén de objetos binarios en una base de datos; no tiene nada que ver.


Referencias:

Anti Patterns – Refactoring Software, Architectures and Projects in Crisis, varios autores.

De artistas, cantantes y cantamañanas Diciembre 10, 2009

Posted by ravelus in Crítica social.
add a comment

La última polémica de este Gobierno que tantas polémicas suscita en la Red y tantas líneas me permite rellenar en este blog (gracias, Presi), está en los derechos de autor e Internet. Bueno, no es la última ya que está el caso Haidar al que quizá dedique otras cuantas líneas, pero hoy hay otros pitos que tocar.

Al margen de manifestaciones, gente en la calle, un sinfín de blogs y portales publicando un manifiesto al cual apoyo y demás escándalos, fue realmente impresionante ver a una pandilla de vagos de abrigo de bisón y chalé en la Moraleja diciendo que “se mueren de hambre”. Con la que está cayendo. Familias en paro, hipotecas, créditos, deudas, EREs y demás temario y cuatro muerdealmohadas se quejan de que “se mueren de hambre”… escuece sólo oirlo.

Quizá es que cuando se lleva un modelo de vida en el cual los lujos están a la orden del día, ir al spá, a la sauna, bañarse en la piscina, tomar baños de rayos UVA y daiquiris varios, resulta que cuando vienen mal dadas y hay que comprar yogures de Hacendado jode un montón. Yo les comprendo, señores “artistas”, su “arte” vale mucho, mucho más que los cuadros de Picasso, Van Gogh, Goya o Sorolla. Ellos no cobrando por cada foto que aparece en los libros de arte, ni por los muchos cuadros que se han inspirado en aquellas magistrales obras, pero es que no les llegan a ustedes ni a la suela de los zapatos; donde esté un “uyuy mi gato hace uyuyuyuyuyy” de Rosario Flores que se quite Dalí, Mozart y la Filarmónica de Berlín.

De hecho, deberían patentar dichas expresiones y de este modo, cada vez que alguien diga “uyuyuy”, “depende” o “tengo el corazón partío” les pague a ustedes un plus. Qué coño, deberíamos pagarles un plus en cualquier caso, porque aunque no lo digamos, seguro que lo hemos pensado, que la gente es mú mala. Cada vez que un grupo componga una sola canción en la que algún acorde recuerde a alguna tonadilla de Bunbury, debería pagarle a éste un… un momento, no, bueno, esto mejor no, que Bunbury ya tiene sus propias fuentes de inspiración, perdone usted, Enrique.

El caso de Bunbury me jode profundamente, porque todavía recuerdo oírle aquello de “la piratería y las descargas no acabarán nunca con la música; acabarán con la industria discográfica, que es muy distinto; pero puede retornarse a algo como lo que ocurría con los juglares en la Edad Media, a la música en vivo, que al fin y al cabo es la música de verdad, y es donde de verdad se ve si un músico vale o no vale”. No voy a citar la fuente porque la desconozco, y este texto no es exactamente como lo dijo, pero les puedo asegurar que dijo semejante belleza. Y ahora apoya a sus coleguis de compaña. No sé si es por apoyar a un amigo en estos duros momentos de profunda demagogia (artistas comunistas reconvertidos al más puro capitalismo-socialismo) o es que este tipo es un redomado hipócrita. De verdad que me jode hacer una crítica tan insultante de alguien a quien admiro musicalmente, pero es que lo que no está bien, no está bien. Y hay mucho músico por ahí que ante su público dice una cosa y luego actúa de forma muy diferente.

Pero vamos al meollo, porque al final se está consiguiendo lo que todo político desea, ya veo a ZP y a Rajoy frotándose las manos: que la sociedad se enfrente entre sí. Cuando a un hombre lo presionan, éste se rebela, y no dudo que los artistas estén presionados, en ningún modo. La puta demagogia que vivimos día a día hace que las víctimas de nuestras preocupaciones seamos nosotros mismos, o nuestro prójimo si se me entiende mejor, y nos demos de hostias en cruel guerra civil en lugar de buscar a los auténticos responsables: políticos y empresarios capitalistas que se forran a costa del talento de otros.

Y lo que ocurre es que Internet (de momento y gracias a Dios) es libre de todo esto. Internet nos hará libres, muchachos. Internet no entiende de capitalismos, demagogias y otra cosa que no sea libertad de expresión. Por ello Internet les toca tanto la moral a esos empresarios de Montecristo en ristre y Longines en muñeca. Y la consecuencia de nuestra rebelación, de nuestra lucha por la libertad la pagaremos nosotros, en forma de cánones y leyes que se basan en dar leña al ciudadano y limitar su libre albedrío.

Que no, señora Sinde, que no voy a ir a ver ni una puñetera bazofia que se llama cine español en el cual sólo se ven tetas y culos sin argumento y sin sentido, que no quiero ver esa porquería ni gratis, películas subvencionadas que en el mejor de los casos han llegado a las carteleras y en el peor de los casos no han llegado ni a rodarse (¿dónde está la pasta de la subvención, entonces?); esto ocurre por vivir en un país en el que se premia la imbecilidad en lugar de la excelencia; hártense a Goyas hasta que les salgan por las orejas, otórgense premios los unos a los otros, cuélguense medallas, métanselas por donde les quepan. Ahora bien, no nos tomen por idiotas, joder.

Antipatrones Software Noviembre 22, 2009

Posted by ravelus in Informática.
add a comment

Un patrón software es una solución común, adaptable y probada para un problema conocido. Algo así como una plantilla de encaje que se ajusta a según qué condiciones (fuerzas y contexto) de manera que aporta una solución (diseño) implementable y ejecutable (software).

Un antipatrón es precisamente lo contrario. Dicho así de pronto parece claro que es algo así como un “lo que no hay que hacer” y que por tanto lo que voy a tratar aquí es un compendio de malas prácticas. Pero un antipatrón no es exactamente esto. Existen muchos libros que tratan de buenas y malas prácticas: en análisis, en diseño, en implementación, en pruebas… Un antipatrón no es una mala práctica, aunque su consecuencia es un mal diseño y por tanto puede abocar al fracaso de un producto software.

Un antipatrón es la aplicación de un patrón software bajo unas precondiciones erróneas, es decir: la aplicación de un patrón software en un contexto equivocado. Es algo así como decir: “tu intención era buena peeero no estudiaste bien las fuerzas y el contexto que intervenían en tu situación particular, y por ello tu solución es inadecuada”.

Bueno, esto parece diferente a lo que tradicionalmente considerábamos como mala praxis en el desarrollo software, y parece tener algo de atractivo. En estos momentos estoy leyendo un librito que trata este tema, y a medida que encuentre temas interesantes que pueda publicar lo haré. Veamos si no es un palabro más inventado para escribir libros y ganar dinero.

Lo que expongo a continuación es un breve resumen de patrones y antipatrones extraídos de la fuente que anexo al final del artículo. Para ir abriendo boca.

Patrones:

Cultura de reutilización: trata precisamente de establecer una política de reutilización de software y de que todo el equipo desarrolle pensando siempre en que sus artefactos son susceptibles de ser reutilizados.

Artefacto robusto: un elemento bien documentado, construído para alcanzar los objetivos y necesidades generales en lugar de limitarse simplemente a los objetivos específicos.

Generalización automotivada: Tratar de pensar en la generalización a la hora de desarrollar, en facilitar elementos que se puedan utilizar as-is.

Ingeniero senior de reutilización: es aquel que pone en práctica los patrones anteriores.

Antipatrones:

Artefacto no reutilizable: No sólo es aquel que no es reutilizable porque no se pensó en ello, sino que también es aquél que se pretendió que fuera reutilizable pero que en realidad no lo es (y esto último es más importante y más grave).

Reutilización orientada a repositorios: La creencia de que simplemente por crear una especie de almacén de piezas software que se pueden reutilizar, la reutilización viene de forma automática.

Síndrome del No-Está-Hecho-Aquí: Los desarrolladores desconfían del trabajo hecho por otros y tienden a desarrollar por sí mismos artefactos software que ya están hechos.

Reusabilidad declarada: La creencia de que algo es reutilizable simplemente porque lo digo yo o lo dijo alguien…

Reusabilidad orientada a incentivos: Una vez más, ofrecer incentivos para que los desarrolladores hagan software de mayor calidad (en este caso, reutilizable) no es el camino, pequeño saltamontes…

Producción antes de consumición: Algo así como que la reutilización vendrá por sí sola en cuanto empieces a pensar en desarrollar artefactos reutilizables. La realidad es que es necesario invertir fuertemente para que la reutilización sea un hecho probado: dedicar recursos y soporte.

Reutilización solamente de código: Creer que lo único susceptible de ser reutilizado es el código.

Reutilización orientada a proyectos: Limitar la generalización que lleva a construir artefactos reutilizables solamente como decisión que incumbe al ámbito del proyecto para el cual se desarrolla dicho artefacto.

Referencias:

http://www.sdmagazine.com/uml/thinking/s0002to.shtml

Revista Dr Dobb’s, actualmente la fuente no está disponible. El artículo lo encontré por ahí… lamento no poder facilitar más las cosas.

HowTo: Connect to a VPN in Linux Noviembre 10, 2009

Posted by ravelus in Informática.
2 comments
Nota: Este pequeño artículo se debe a una reciente investigación que tuve que realizar en el trabajo; como la publiqué en inglés he decidido no tomarme la molestia de traducirlo; al fin y al cabo quien lo necesite será alguien que trabaja con ordenadores y estará más que acostumbrado a leer textos en inglés; por otra parte creo que el artículo es sencillo…

Foreword

The following steps works fine in Ubuntu 8.04 Hardy. You should not have any problem in other versions.

Install required packets

First of all, we need to know which is the VPN infrastructure to connect. Depending on it, we’ll distinguish between 3 different cases:

A) – openVPN.

B) – Windows VPN

C) – Cisco VPN.

Once we certainly have this information, we can download the appropiate package:

A) – sudo apt-get install network-manager-openvpn

B) – sudo apt-get install network-manager-pptp

C) – sudo apt-get install network-manager-vpnc

If your distribution is not Ubuntu, try to search those packets in Synaptics, YaST or whatever.

After installing them, you should see a net icon in the status bar. Click on it and create a VPN connection. Introduce all the information provided to connect to your server and proceed as you would do in Windows.

When you have finished, click again in the net icon in the status bar and select your connection. The system will ask for your credentials. Type them and enter. Quite simple.

Useful links

http://www.cs.umn.edu/help/offsite/vpn.php#ubuntu_config

This is a useful link with a very simple tutorial including snapshots. In the examples it explains how to connect to a Cisco VPN, but the other cases are quite similar.

https://wiki.ubuntu.com/VPN

Here you can find information about packages to install and things like that.

Escaparate Nacional Octubre 31, 2009

Posted by ravelus in Crítica social.
add a comment

En las últimas fechas, periodistas y otras clases de seres vivos afines se frotan las manos, pues más que tiempos de crisis lo que estamos viviendo son tiempos de cosecha: cosecha de uva, cosecha de cereal, cosecha de la fruta y cosecha del membrillo. Tiempos de vacas gordas para algunos, mientras al resto sólo nos queda tomarnos la vida con un poco de buen rollo, de qué le vamos a hacer, y de que no nos venga algo peor.

A Obama le conceden el premio Nobel de la Paz; que no voy a decir yo que el tipo no me cae bien, que tiene cara de ser un cachondo (mental), pero es que tiene más tirón que la Hannah Montana, Paris Hilton y Belén Esteban juntas, tenemos a Obama hasta en la sopa, parecemos lelos, todos atentos a ver que hace, como cuando la familia mira a un recién nacido, atentos todos a cada uno de sus gestos, a ver si el niño estornuda y aplaudimos como idiotas. No sé, no sé, pero como Obama algún día haga algo, pero algo de verdad, esto ya sí que va a ser la repolla, vamos.  Esto nos pasa por vivir en la Edad Lela, en la cual nos tragamos todos lo que nos den por televisión, nos domestican cual perrillos de aguas y nosotros aplaudimos encantados. Qué bonito todo. Aun así, debo admitir que hay gente muy capaz, capaz de vender algo como bueno sin siquiera haber demostrado su eficacia. Esto es, el comercial absoluto llevado a la hipérbole.

El PP se desmorona cual castillo de naipes;  periodistas y cada vez más gente pide la cabeza de Rajoy cual populacho enfervorecido ante el patíbulo de turno; la corrupción salpica distintos puntos de España cual rostro de adolescente con acné. En medio de esta trifulca, todavía hay quien desea salvar su culo a tiempo, como Montserrat Nebrera, que deja el PP por decencia y abandona sus cargos públicos por honradez y por coherencia. He de reconocer que cuando leí la noticia me resbaló una lágrima de felicidad por la mejilla, y volví a tener esperanza en el ser humano. Todavía hay personas que bien merecen un aplauso, una ovación sincera, una admiración absoluta… o es que salvan el culo como buenamente pueden. En cualquier caso, un gesto que la honra. El presidente del PP vasco, Antonio Basagoiti, clamando al cielo por los valencianos corruptos; en algún momento pensé: si a este le sueltan con Correa, Camps y el resto del ganado, los lincha a hostias. Pagaría por ver espectáculo tal. En Madrid, la lucha por CajaMadrid alcanza cotas insospechadas; ¿alguien se cree de verdad que las cajas deben estar politizadas para que no se desvíen de sus “fines sociales”? Cada vez que oigo esto me quedo con el culo torcido, con una expresión que se sitúa entre el más profundo de los  asombros y el de voy a mirarme la cara en un espejo a ver si pone “Vicentín”. El secretario general del PP en Madrid, Francisco Granados, otra de las caras que hace uno pensar que el ser humano aún puede salvarse, no sabía ni qué decir el otro día en la cadena SER; avergonzado y asqueado, lamentaba el espectáculo circense ante el pueblo, oh, sí, el pueblo, esos lerdos que están para votar en las elecciones.

Y dicen que Zapatero enviará un jamón de Guijuelo a toda la cúpula del partido popular, porque gracias a ellos ya nadie se acuerda de la crisis.

En Cataluña también hay corrupción, y es que como dijo hace escasos días Anguita, allí donde fueres… esto ya es un espectáculo que bien podría merecer un Nobel, y no el de Obama. ¿Cuándo dije yo que si se pusieran a investigar saldría mierda hasta del ayuntamiento de mi pueblo? Y ésto último es verídico, créanme.

Finalmente, Sinde no decepciona. Aquellos que teníamos fé, aquellos que confiábamos en el potencial de este portento humano del bien, no hemos salido trasquilados. Saw 6, una película Disney, podría ser emitida en horario cachondo, cual película X. Mientras tanto, estreno español que sale, estreno español que enseña teta española: Mentiras y gordas, Dieta Mediterránea… eso no es porno, señores, eso es Cine Español (pronúnciese la ñ con mucha intensidad, como en los tiempos de Franco, sólo que esta vez mola más porque lo dicen los caraduras de la ceja doblá, esos que se lo llevan todo calentito). Basura televisiva, señores, el 95% del cine que se hace en España sigue siendo maldita basura, el dinero que se llevan estos sinvergüenzas de mis impuestos es para hacer basura (cuando la hacen; otra cosa es llevarse subvenciones y no hacer ná; luego dirán de los especuladores de la construcción…). El otro 5% es cine de Amenábar, de auténtica calidad, y de algún otro director novel, pobres inconscientes y virginales que desconocen aún cómo se cuecen las habas in Spain. Señora Sinde, no se preocupe por el pirateo; no creo que nadie quiera siquiera descargarse la bazofia que se produce en este país ni aunque le pagen, descuide. Puede meterse el cánon por donde le quepa.

Lanzarote, fuego por dentro Octubre 18, 2009

Posted by ravelus in Cultura, Experiencias.
add a comment

Hace poco menos de un mes estuve con mi novia de vacaciones en Lanzarote, una de las islas que, como todos saben, conforma el archipiélago canario. Disfrutamos de un tiempo espléndido, visitamos lugares muy interesantes y cenamos a cuerpo de rey. Quería compartir aquí mi experiencia desde un punto de vista más o menos objetivo, para que futuros visitantes de la isla puedan tener un punto de referencia acerca de qué ver, qué comer y dónde hospedarse.

Hospedaje

Nosotros elegimos un apartotel por la privacidad de tener nuestra propia casita y el precio de este tipo de hospedajes. Encontramos una buena oferta en Sun Park en régimen de alojamiento y desayuno, por 16€ cada persona. Un precio muy asequible teniendo en cuenta que las habitaciones incluyen una pequeña cocina con todos los utensilios necesarios para preparar comida. Además el complejo hotelero tiene varias piscinas, salas de reunión, parques para los críos y demás. Situado en Playa Blanca, al sur de la isla, en dirección a Playa Papagayo.

Qué comer

Algunos días cenamos en los numerosos restaurantes que se ubican en el paseo marítimo de Playa Blanca, con vistas al mar y todo el pastel. Alguna vez elegimos pescado del día, como no podía ser de otra manera, y no nos decepcionó en absoluto. Cherne (como allí llaman al mero) fino, suave al paladar, aunque es más típica la Vieja. Los precios varían entre restaurantes levemente, pero en general se come barato y bien.

Qué ver

Montañas de fuego.

Vista del parque nacional de Timanfaya y el Atlántico al fondo

Vista del parque nacional de Timanfaya y el Atlántico al fondo

En pleno parque nacional de Timanfaya, en el centro de la isla, existe una ruta en autobús, por 8€ que le mostrará el árido y virgen desierto rojo de la isla, suelo protegido por la Unesco como Reserva de la Biosfera. Es algo fuera de lo común para los que vivimos en la península, y puede merecer la pena por ello; pero van a ver eso mismo: desierto.

La Cueva de los Verdes.

Un paseo de aproximadamente 1km por el interior de cuevas rehabilitadas por César Manrique, artista polifacético y gran defensor de la isla. En su interior no veremos las típicas estalactitas y estalagmitas, sino marcas de los ríos de lava que quedan de las últimas erupciones de la isla, allá por el siglo diecinueve. Todo decorado con luces de colores, da un aspecto bastante curioso. Lo del nombre de los Verdes es algo muy curioso que… no, es mejor que vaya y se lo cuenten. Cuidado con los desfiladeros, en algunos, inexplicablemente, no hay barandilla… Precio: 8€.

El volcán de Caldera blanca.

Ruta de senderismo a través de Timanfaya, por un auténtico pedregal que desemboca en los volcanes de Caldera Pequeña y Caldera Blanca más adelante, los volcanes con mayor altitud de la isla, a unos 500m de altura. Muy recomendable llevar bastón y calzado adecuado, esto es: botas de montañismo, no zapatillas deportivas. Dificultad: media, por la ascensión al cráter y el suelo pedregoso, no apto para tobillos frágiles.

Interior del volcán de Caldera Blanca

Interior del volcán de Caldera Blanca

Jameos del agua.

Bueno, pues otra bajada a una gruta con un estanque subterráneo donde se aloja una especie endémica de cangrejo canijo y blanco. Los jameos son precisamente las salas subterráneas que la lava fue creando a su paso por debajo de la tierra y que después han quedado al descubierto al derrumbarse los techos de roca. Incluye un pequeño centro de interpretación donde aprenderemos cómo funciona el asunto del volcanismo, la formación de la isla y demás. Precio: 8€.

Jardín de cactus

Jardín de cactus

Jardín de cactus.

Alberga miles de especies de cactus recogidas de todos los rincones del planeta, a cada cual más curioso. Precio: 6€.

Y para terminar…

… puede dar un paseo en camello por las áridas arenas de Timanfaya; el precio es de 12€ el alquiler del camello, en el cual pueden montar dos personas.