Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible circular dependency issue with PHP application

I'm experiencing what I believe is a circular dependency issue with my PHP application. Please let me know if this is incorrect. Here is the situation:

Two classes, LogManager and DBSession.

DBSession is used to interact with the database, and LogManager is used to log to files. Both are widely used in my application. When you create an instance of DBSession, you must give it an instance of LogManager via a constructor parameter. This because DBSession will sometimes log information to a file, and will use the LogManager instance to do this.

Now, I wanted to extend LogManager so that it could also log to a database table, rather than a text file. Naturally, my preference is to re-use existing classes, but I soon realized this brought about an interesting situation.

DBSession already requires an instance of LogManager for construction. If I want to re-use the DBSession class in LogManager, it will now require an instance of DBSession. How can I satisfy both demands? Clearly, something must be wrong with my approach.

How would you suggest I fix this?

Thanks in advance, guys.

like image 344
Matt Refghi Avatar asked Oct 12 '08 03:10

Matt Refghi


3 Answers

Don't extend LogManager, let it be an aggregate type. And delay the choice of where you want to log, i.e.:

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

Where of course FileLog and DBLog share a common interface. This is an application of the Observer pattern, where add() is the "subscribe" operation, and FileLog/DBLog are the observers of logging events. (In this way you could also save logs in many places.)

Owen edit: adjusted to php syntax.

like image 178
Federico A. Ramponi Avatar answered Sep 17 '22 11:09

Federico A. Ramponi


One of these objects doesn't actually need the other: you guessed it, it's the DBSession. Modify that object so that the logger can be attached to it after construction.

like image 42
Edward Z. Yang Avatar answered Sep 18 '22 11:09

Edward Z. Yang


Why demand a LogManager object for the creation of a DbSession object, if it only sometimes writes to files? lazy load it instead only when you need it. Also, in my opinion both should be independent from each other. Each could instance the other when needed.

like image 21
Eran Galperin Avatar answered Sep 16 '22 11:09

Eran Galperin