martes, octubre 03, 2006

Diseño sencillo contra implementación correcta

Diseño elegante y sencillo frente a implementación correcta. No siempre están enfrentados, pero muchas veces si.

El tema me ha surgido leyendo un blog muy interesante, Thinking parallel, en el cual se discute si los mutex recursivos son buenos o no, que apunta a un excelente post en comp.programming.threads Recursive mutexes by David Butenhof. Las dos tesis contrapuestas son:

  • Los mutex recursivos son buenos, porque ayudan a modularizar y a abstraer (diseño elegante y sencillo)
  • Los mutex recursivos son malos: Del post de Butenhof:"Un diseño correcto y bien pensado no requiere mutex recursivos" (implementación que puede ser no correcta)
Lo cierto es que la tesis de Butenhof está muy bien argumentada y nos da pistas de cuando estamos haciendo las cosas mal:
El problema más grande de todos los problemas de los mutex recursivos es que animan a perder la pista de tu esquema de bloqueos y su ámbito (scope). Esto es mortal. Nefasto. Es el "comedor de threads". Has de coger los mutex durante el tiempo más corto posible. Punto. Siempre. Si estás llamando a algo con un mutex cogido es porque no sabes si está cogido o porque no sabes si la llamada lo necesita, entonces lo estas cogiendo demasiado tiempo.

Abstrayendo... ¿Que caracteriza (entre otras cosas) un buen diseño?

  • No se repiten conceptos (fácilmente modificable)
  • Es elegante (desde lejos, desde arriba, a nivel de relación entre objetos, módulos ...)
  • Es sencillo (en lo posible, para no complicar o entorpecer la implementación)
¿Que caracteriza (entre otras cosas) una buena implementación?
  • No se repite código (mantenible)
  • Es elegante (el código, de cerca, a nivel de función)
  • Es correcto
  • Es óptimo


Entre la sencillez del diseño y la optimización y corrección de la implementación es donde suele haber más problemillas. En lugar de rediseñar cuando se detectan errores de rendimiento el camino más fácil son los hacks, que cuando no son excelentes suelen embarullar el código y distorsionar el propósito del diseño.
En estos casos no habría que tener miedo de refactorizar el código y rediseñar si es preciso, aunque en un caso ideal habría que haberlo tenido en cuenta antes, como requisitos no funcionales, pero sin caer en la sobreingeniería. Difícil verdad ;)

Se podría decir que los mutex recursivos son un hack y por ese motivo usarlos con mucha precaución. Como dice el propio Butenhof (extensible a todos los hacks)

Los mutex recursivos son un hack. No hay nada erróneo si se usan, pero son una muleta. ¿Tienes una pierna rota o una librería? Bueno, usa una muleta. Pero al menos sé consciente de que la estás usando y porqué.



La misma entrada en BP