El problema de los Singletons heredados, solucionado en PHP

La comunidad de desarrolladores de software está dividida en este debate: ¿conviene implementar el patrón de diseño Singleton en nuestras aplicaciones? O al contrario, ¿hay que evitarlo porque es un antipatrón?

El problema de los Singletons heredados, solucionado en PHP

Los detractores de Singleton argumentan así:

  • Las instancias Singleton están en el espacio global de la aplicación y eso es malo: utilizar variables globales es una mala práctica
  • Singleton introduce dependencias escondidas
  • Es difícil de probar con tests unitarios
  • Algunos desarrolladores lo implementan sin razón alguna, cuando sería mejor no hacerlo

Y los partidarios dicen:

  • Los argumentos anteriores no son concluyentes
  • Un patrón de diseño no debería dejar de implementarse por el solo hecho de utilizar una metodología de desarrollo de software determinada, como por ejemplo TDD
  • Tampoco hay para tanto, a Singleton se le tiene manía

Sea como fuere, si eres de los que por h o por b terminas utilizando varias clases Singleton en tu aplicación te acabarás encontrado con el siguiente problema.

Singleton solo se puede extender una vez

Este es el típico snippet de código Singleton que encontramos en sitios como PHP: The Right Way:

Pero solo va bien cuando lo hereda una sola clase PHP:

No funciona si lo extienden varias clases: dos, tres o las que sean:

En tal caso se machacará el valor de la propiedad $instance porque solo puede alojar una instancia. Esto no es un problema de PHP, por cierto, también sucede en otros lenguajes de programación. Es una cuestión teórica sobre cómo está definido el patrón de diseño Singleton.

Pero ahora no discutamos cuestiones tan conceptuales, solucionemos el problema rápidamente:

Este patrón Singleton modificado almacena un array de instancias en lugar de una sola, de modo que ya podemos extenderlo tantas veces como queramos. Yo lo he probado en un par de aplicaciones de producción, ¡y a mí me funciona sin ningún problema!

¿Te gusta? La idea la saqué de aquí, y si te interesa puedes ver la solución Java en este enlace.

Ejemplo práctico de Singleton extensible

Mira cómo queda la implementación Singleton modificada en esta app de GitHub. Es el web crawler de esta aplicación real que sirve para analizar el contenido mixto de las webs. Fíjate que mi web crawler tiene tres clases (DB, Network y Crawler) que heredan de Singleton.

La app es sencilla y no está hecha con TDD, supongo pues que el uso de Singleton está justificado. Además, quería probar el experimento que comparto contigo en este post.

Esto es todo por hoy. Muchas gracias por haber leído este post, espero que te haya gustado y que lo compartas con tus amigos.

También te puede interesar leer esto…