Singletons are glorified global variables. El patrón de diseño se creó para los idiomas en los que las variables globales son difíciles o imposibles, o donde se consideran malas prácticas. (De hecho, la mayoría de los patrones de diseño comunes están diseñados para lenguajes restrictivos. Un gran número de ellos son simplemente innecesarios en otros lenguajes.)
PHP tiene variables globales. Las variables globales de PHP generalmente son una mala práctica, pero existen si necesita usarlas.
Sin embargo, hay algunas razones por las que querría un Singleton en PHP.
Los Singletons son útiles cuando la llamada a getInstance
(el nombre canónico para el método que devuelve la instancia única de Singleton) podría hacerme en cualquier punto del script. Hasta ese punto, el objeto no necesita existir. Si el objeto era una variable global en su lugar, o bien debería existir, o el código que trata de hacer referencia al objeto primero tendría que crear una instancia. De hecho, en cualquier lugar donde se pueda usar, necesitaría ser instanciado correctamente. Al centralizar la creación del objeto único en getInstance
, evita tener que crear el texto repetitivo de copiar y pegar cada vez que necesita hacer referencia al objeto.
Objetos de base de datos generalmente se crean muy temprano en la vida útil de la solicitud, por lo que se desperdiciaría el beneficio específico de Singleton-ness.
Existen otras alternativas a Singleton que pueden hacer el trabajo de otras maneras. Un ejemplo es dependency injection, un término sofisticado para pasar objetos externos de los que dependería un nuevo objeto (como un identificador de base de datos) al objeto en tiempo de construcción. Sin embargo, esto puede ser complicado o molesto. Hacerlo bien podría implicar la inyección de un lote de los mismos objetos cada vez.
Otra alternativa es el Registry pattern, que es efectivamente un contenedor para cosas que de otro modo serían globales. Si no te gustan las variables globales, pero no te importa que sean efectivamente espacios de nombres, esta sería una solución que te gustaría.
Al final, elija una forma de hacerlo, y quédese con eso de una manera a lo largo de su código base. Personalmente, soy un fanático de que el objeto de base de datos sea global.
Si utiliza algún caché, puede suceder que no se necesita la conexión de base de datos. Además, como el singleton se usa en una clase, es posible usar la carga automática. No creo que Singleton sea malo para el manejo de bases de datos en PHP. – Savageman
Muy cierto. Si tiene una capa de almacenamiento en caché completa entre su código y su base de datos, es muy posible que nunca necesite abrir una conexión al menos una parte del tiempo. – Charles
El punto acerca de las pruebas es muy válido. El principal problema con singleton es que no solo lo restringe a una sola instancia (¿qué hay de dos conexiones de db separadas para separar dbs?) Sino también a una implementación específica. Si desea probar, debe reemplazar su conexión de db con otra cosa. La abstracción se vuelve más difícil porque no es posible extender su singleton. El registro aborda muchos de estos problemas. – igorw