En programación de computadoras , el patrón de visitantes de una sola porción es un patrón de diseño . Su intención es optimizar la implementación de un visitante que se asigna, se usa solo una vez y luego se elimina (que es el caso de la mayoría de los visitantes).
Aplicabilidad
El patrón de visitantes de una sola porción debe usarse cuando los visitantes no necesitan permanecer en la memoria. Este suele ser el caso cuando se visita una jerarquía de objetos (como cuando el patrón de visitante se usa junto con el patrón compuesto ) para realizar una sola tarea en él, por ejemplo, contar el número de cámaras en una escena 3D.
El patrón de visitante regular debe usarse cuando el visitante debe permanecer en la memoria. Esto ocurre cuando el visitante está configurado con una serie de parámetros que deben mantenerse en la memoria para un uso posterior del visitante (por ejemplo, para almacenar las opciones de renderizado de un renderizador de escenas 3D).
Sin embargo, si debe haber sólo una instancia de tal visitante en todo un programa, puede ser una buena idea para ponerlo en práctica, tanto como una sola porción de visitantes y como un producto único . Al hacerlo, se asegura que el visitante de servicio único pueda ser llamado más tarde sin modificar sus parámetros (en este caso particular, "visitante de servicio único" es un abuso de lenguaje ya que el visitante puede ser utilizado varias veces).
Ejemplos de uso
El visitante de servicio único se llama a través del intermedio de métodos estáticos.
- Sin parámetros:
Elemento * elem ; SingleServingVisitor :: apply_to ( elem );
- Con parámetros:
Elemento * elem ; TIPO param1 , param2 ; SingleServingVisitor :: apply_to ( elem , param1 , param2 );
- Implementación como singleton:
Elemento * elem ; TIPO param1 , param2 ; SingleServingVisitor :: set_param1 ( param1 ); SingleServingVisitor :: set_param2 ( param2 ); SingleServingVisitor :: apply_to ( elem );
Consecuencias
Pros
- No hay objetos "zombies" . Con un visitante de una sola porción, se garantiza que los visitantes se asignen cuando sea necesario y se destruyan una vez que no sirvan.
- Una interfaz más sencilla que la de visitante . El visitante es creado, utilizado y gratuito con la única llamada del método estático apply_to .
Contras
- Asignación repetida . En cada llamada del método apply_to , se crea un visitante de servicio único y luego se descarta, lo que requiere mucho tiempo. Por el contrario, el singleton solo realiza una asignación.
Implementación (en C ++)
Implementación básica (sin parámetros)
// Elemento de clase de declaración ; class ElementA ; class ElementB ; class SingleServingVisitor ; ... // Igual que con el [[patrón de visitante]].// Clase de definición SingleServingVisitor { protected : SingleServingVisitor (); público : ~ SingleServingVisitor (); static void apply_to ( Elemento * ); virtual void visit_ElementA ( ElementA * ) = 0 ; virtual void visit_ElementB ( ElementB * ) = 0 ; }// Implementación void SingleServingVisitor :: apply_to ( Element * elem ) { SingleServingVisitor ssv ; elem . aceptar ( ssv ); }
Pasando parámetros
Si el visitante de servicio único debe inicializarse, los parámetros deben pasarse a través del método estático:
void SingleServingVisitor :: apply_to ( Elemento * elem , TYPE param1 , TYPE param2 , ...) { SingleServingVisitor ssv ( param1 , param2 , ...); elem . aceptar ( & ssv ); }
Implementación como singleton
Esta implementación asegura:
- que hay como máximo una instancia del visitante de servicio único
- que se pueda acceder al visitante más tarde
// Clase de definición SingleServingVisitor { protected : static SingleServingVisitor * instance_ ; TYPE param1_ ; TYPE param2_ ; SingleServingVisitor (); SingleServingVisitor estático * get_instance (); // Nota: el método get_instance no necesita ser públicopúblico : ~ SingleServingVisitor (); static void apply_to ( Elemento * ); // métodos estáticos para acceder a los parámetros static void set_param1 ( TYPE ); static void set_param2 ( TYPE ); virtual void visit_ElementA ( ElementA * ) = 0 ; virtual void visit_ElementB ( ElementB * ) = 0 ; }// Implementación SingleServingVisitor * SingleServingVisitor :: instance_ = NULL ;SingleServingVisitor * SingleServingVisitor :: get_instance () { if ( this -> instance_ == NULL ) this -> instance_ = new SingleServingVisitor (); devuelve esto -> instancia_ ; }void SingleServingVisitor :: apply_to ( Elemento * elem ) { elem -> accept ( get_instance ()); }void SingleServingVisitor :: set_param1 ( TYPE param1 ) { getInstance () -> param1_ = param1 ; }void SingleServingVisitor :: set_param2 ( TYPE param2 ) { getInstance () -> param2_ = param2 ; }
Patrones relacionados
- Patrón de visitante , del cual se deriva este patrón
- Patrón compuesto : el visitante de servicio único a menudo se aplica a las jerarquías de elementos.
- Patrón singleton