Hoy me he puesto a buscar patrones de diseño para estar un poco a la orden del día en cuanto a este tema y me he encontrado con el Decorator Pattern. He buscado muchos ejemplos y aunque parece que lo he entendido tengo dudas sobre su aplicación.
¿Este patrón vale para contenidos dinámicos en una web? Por ejemplo, pienso en el menú de usuario de Mediavida donde aparece nuestro nombre, avisos, favs, mensajes y botón salir. Si estamos logueados en la web nos aparece esa información y si estamos desconectados desaparece todo eso a favor de un enlace a iniciar sesión. Podemos decir que existen dos comportamiento diferentes en función del valor de las variables de sesión. Entonces ¿esas dos posibilidades son decoradores diferentes? ¿Una clase decorador para el caso de que el usuario esté logueado y otra clase decorador si está desconectado?
Mi segunda pregunta sería en relación a la primera en caso de que ésta sea afirmativa. He visto que el aspecto general de cualquier decorador es algo así como:
abstract class Decorador extends Componente
{
private Componente _componente;
public Decorador(Componente componente)
{
_componente = componente;
}
public void operacion()
{
_componente.operacion();
}
}
Lo importante ahí es que toda clase que extienda de esa tiene que recibir en su constructor el componente a decorar. Pero, ¿qué sucede (insisto en si la primera pregunta que he formulado es afirmativa) si esos decoradores tienen a parte otras clases en su constructor a parte del componente a decorar? Todos los ejemplos que he encontrado en internet de decoradores tienen un solo elemento en el constructor (el componente a decorar) pero no he encontrado ninguno que tenga varios.
Volviendo al ejemplo anterior, si el usuario está logueado tengo que mostrar el nombre de usuario, el número de mensajes y el número de alertas. Mi clase decoradora tendría entonces declarada en el constructor el componente a decorar junto a un "UsersService" para obtener los datos del usuario (nombre, avatar etc...), "AlertsService" para obtener el número de alertas pendientes y "PrivateMessagesService" para obtener el número de mensajes privados sin leer.
class UserIsLoggedDecorador extends Decorador
{
private $componente;
private $usersService;
private $alertsService;
private $privateMessagesService;
public UserIsLoggedDecorador(Componente $componente, UserService $userService, AlertsService, PrivateMessagesService)
{
$this->componente = componente;
$this->usersService = $usersService;
[...]
}
public void operacion()
{
// Cosas
}
}
Sin embargo el otro decorador, para el caso en el que no esté logueado, no necesitaré tantas dependencias en el constructor ya que sólo tengo que mostrar el botón de iniciar sesión:
class UserIsNotLoggedDecorador extends Decorador
{
public UserIsNotLoggedDecorador(Componente $componente)
{
_componente = componente;
}
public void operacion()
{
// Cosas
}
}
Si estoy utilizando un inyector de dependencias tipo Ninject, Dagger o PHP DI, ¿cómo implemento esto? ¿Tengo que crear un factory para cada decorador y después una abstract factory que me devuelva la factory correspondiente en función de si el usuario está logueado no?