¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Design Patterns en PHP
  3. El patrón de diseño Singleton
Extrait - Design Patterns en PHP Los 23 patrones de diseño: descripciones y soluciones ilustradas en UML2 y PHP (2ª edición)
Extractos del libro
Design Patterns en PHP Los 23 patrones de diseño: descripciones y soluciones ilustradas en UML2 y PHP (2ª edición) Volver a la página de compra del libro

El patrón de diseño Singleton

Descripción

El patrón de diseño Singleton tiene como objetivo asegurar que una clase solo posee una instancia en memoria y proporcionar un método de clase que devuelva esta instancia única.

En ciertos casos puede ser útil gestionar clases que posean una única instancia. En el marco de los patrones de diseño de construcción, podemos citar el caso de la fábrica de productos (patrón de diseño Abstract Factory) de la que solo es necesario crear una instancia.

Ejemplo

En el sistema de venta online de vehículos, debemos gestionar clases que poseen una sola instancia.

El sistema de documentación que debe entregarse al cliente tras la compra de un vehículo (como el certificado de cesión, la solicitud de matriculación y la orden de pedido) utiliza la clase DocumentacionEnBlanco que solo posee una instancia. Esta instancia única referencia todos los documentos necesarios para el cliente. Se le llama documentación en blanco, pues los documentos a los que hace referencia están todos en blanco. El uso completo de la clase DocumentacionEnBlanco se explica en el capítulo anterior, dedicado al patrón de diseño Prototype.

La figura 8.1 ilustra el uso del patrón de diseño Singleton para la clase DocumentacionEnBlanco. El atributo estático instance contiene o bien null o bien la única instancia de la clase DocumentacionEnBlanco. El método de clase getInstance reenvía esta instancia única contenida en el atributo instance. Si este atributo está en null, se inicializa mediante la creación de la instancia única.

images/2figure8-1.png

Figura 8.1 - El patrón de diseño Singleton aplicado a la clase DocumentacionEnBlanco

Estructura

1. Diagrama de clases

La figura 8.2 detalla la estructura genérica del patrón de diseño Singleton.

images/fig811.PNG

Figura 8.2 - Estructura del patrón de diseño Singleton

2. Participantes

El único participante es la clase Singleton, que ofrece acceso a la instancia única mediante el método de clase getInstance.

Por otro lado, la clase Singleton posee un mecanismo que asegura que solo puede existir una única instancia como máximo. Este mecanismo bloquea cualquier intento de creación de otras instancias.

3. Colaboración

Cada cliente de la clase Singleton accede a la instancia única mediante el método de clase getInstance. No puede crear nuevas instancias utilizando el operador habitual de instanciación (operador new), al que ya no se puede acceder porque ahora su visibilidad es privada. Así mismo, el método mágico __clone también puede tener un modo de acceso privado para impedir que el código cliente esquive el bloqueo establecido por el constructor intentando crear clones del singleton. Aquí, hemos optado por dejarlo público, pero generando una excepción para indicar que este método no puede invocarse.

Dominio de uso

El patrón de diseño Singleton se utiliza en los siguientes casos:

  • Solo debe existir una única instancia de una clase en memoria.

  • Esta instancia solo debe estar accesible mediante un método de clase.

Ejemplos en PHP

1. Documentación en blanco

El código PHP completo de la clase DocumentacionEnBlanco aparece en el capítulo dedicado al patrón de diseño Prototype. La sección de esta clase relativa al uso del patrón de diseño Singleton se muestra a continuación.

El constructor de esta clase tiene una visibilidad privada de modo que solo pueda utilizarlo el método getInstance. De este modo, ningún objeto externo a la clase DocumentacionEnBlanco puede crear una instancia utilizando el operador new.

Del mismo modo, el atributo instance también tiene una visibilidad privada para que solo sea posible acceder a él desde el método de clase getInstance.

<?php  
 
declare(strict_types=1);  
 
namespace ENI\DesignPatterns\Prototype;  
 
class DocumentacionEnBlanco extends AbstractDocumentacion  
{  
   private static ?self $instance = null;  
 
   public static function getInstance(): self  
   {  
       if (!self::$instance) {  
           self::$instance = new self();  
       }  
 
       return self::$instance;  
   }  
 
   public function...