2008-10-12 18 views
7

Estoy experimentando lo que creo que es un problema de dependencia circular con mi aplicación PHP. Por favor, avíseme si esto es incorrecto. Aquí está la situación:Posible problema de dependencia circular con la aplicación PHP

Dos clases, LogManager y DBSession.

DBSession se utiliza para interactuar con la base de datos, y LogManager se usa para iniciar sesión en los archivos. Ambos son ampliamente utilizados en mi aplicación. Cuando crea una instancia de DBSession, debe darle una instancia de LogManager a través de un parámetro de constructor. Esto porque DBSession algunas veces registrará información en un archivo, y usará la instancia LogManager para hacer esto.

Ahora, quería extender LogManager para que también pudiera iniciar sesión en una tabla de base de datos, en lugar de en un archivo de texto. Naturalmente, mi preferencia es reutilizar las clases existentes, pero pronto me di cuenta de que esto producía una situación interesante.

DBSession ya requiere una instancia de LogManager para la construcción. Si deseo volver a utilizar la clase DBSession en LogManager, ahora requerirá una instancia de DBSession. ¿Cómo puedo satisfacer ambas demandas? Claramente, algo debe estar mal con mi enfoque.

¿Cómo Sugeriría que solucione esto?

Gracias de antemano, chicos.

Respuesta

8

No extienda LogManager, permita que sea un tipo agregado. Y retrasar la elección del lugar donde desea iniciar sesión, es decir .:

$logManager = new LogManager(); 
$dbSession = new DbSession($logManager); 
$logManager->add(new FileLog($filename)); 
$logManager->add(new DBLog($dbSession)); 

donde por supuesto FileLog y dBlog comparten una interfaz común. Esta es una aplicación del patrón Observer, donde add() es la operación "suscribirse", y FileLog/DBLog son los observadores de los eventos de registro. (De esta manera también podría guardar registros en muchos lugares.)

Owen edit: ajustado a la sintaxis de php.

+0

$ logManager = new LogManager(); $ dbSession = new DbSession ($ logManager); $ logManager-> add (new FileLog ($ filename)); $ logManager-> add (nuevo DBLog ($ dbSession)); – micahwittman

+0

No es consistente en los nombres de clase .. –

+0

@Owen: ¡gracias por editar! –

1

Quizás pueda aplicar algún patrón, como el Singleton Pattern para asegurarse de que solo tiene una instancia de su clase LogManager, por ejemplo.

2

Uno de estos objetos no necesita realmente el otro: lo has adivinado, es la DBSession. Modifique ese objeto para que el registrador pueda adjuntarse después de la construcción.

2

¿Por qué exigir un objeto LogManager para la creación de un objeto DbSession, si solo se escribe a veces en los archivos? Cargue perezoso en su lugar solo cuando lo necesite. Además, en mi opinión, ambos deberían ser independientes el uno del otro. Cada uno podría instanciar el otro cuando sea necesario.

+0

Nunca he intentado implementar la carga lenta, pero gracias por la recomendación. Admito que sería más adecuado dado que LogManager solo se usa a veces con DBSession. ¡Gracias! –

Cuestiones relacionadas