A community in which webmasters can ask for help with topics such as PHP coding , MySQL , IT jobs, web design, IT security.
Current location:homephp forumphp talk in 2009 yearEgg-chicken problem in OOP way - page 1
User InfoPosts
Egg-chicken problem in OOP way#1
I have a chicken-egg problem. I would like too implement a system in PHP in a OOP way, in which two classes would play important roles: Database and Log. My idea was to build up the connection by the Database class, which would have public methods eg. runQuery(sUpdateQuery), doInsert(sInsert), etc. The Log class would writing logs through common methods just as like logMessage(message), logDatabaseQuery(sQuery) TO THE DATABASE. The problem comes now.

1: Inside the methods of the Database(s class I would like to be able to use the Log class(s logDatabaseQuery(sQuery)

2: This still would not be a big challenge if I would not like to use the Database class(s doInsert(sInsert) method inside the logDatabaseQuery method.

I would like to keep it simple - and just use one instance of the database connection object, and from the loggeras well, if it is possible.

For many people Singleton model would be the first idea to choose, but I definitely would like to use different solution.

So there would be two classes which would use each-other(s methods:



I would like to keep the Log methods separately (in the Log class), since later on it would have other methods for logging not just to the database, but to files or e-mails as well.

Any ideas, how this should / could be done in the nicest, OOP friendly way?

I was thinking about a common parent abstract class, or about using interfaces as well, but finally could not figure out the proper way :(

What I would like to know is a suggestion for a correct class hierarchy

posted date: 2009-04-07 13:22:00

Re: Egg-chicken problem in OOP way#2
I had made out the solution of this problem. click to view my topic...

hope that hepls.

posted date: 2009-04-07 13:22:01

Re: Egg-chicken problem in OOP way#3
Create an insert method overload that allows for inserts without logging, and have your logging class use that. Otherwise, your design is recursive by definition: Log all DB inserts by performing a DB insert.

posted date: 2009-04-07 13:28:00

Re: Egg-chicken problem in OOP way#4
add an optional parameter to doInsert $callerIsLogger=false, then everytime you need to doInsert() from your logger, provide the second parameter true, and your doInsert could check for this situation and not call the logger when is called by logger. What hierarchies? KISS methodology rocks :)

posted date: 2009-04-07 13:29:00

Re: Egg-chicken problem in OOP way#5
This is a good candidate for the Mediator Pattern. You would have an object that the logger and database would both invoke various methods on, and this mediator object would keep references to the logger and database and handle communication for you.

posted date: 2009-04-07 13:32:00

Re: Egg-chicken problem in OOP way#6
Create a Logger class that implements a interface ILogger. A new instance of the Logger class receives a Object that implements the interface ILoggingProvider that is used to output log messages.Create a Database class that implements the ILoggingProvider interface. A new instance of the Database receives a object that implements the ILogger interface that is used to log messages.public interface ILogger{ void Debug(String message)}public interface ILoggingProvider{ void Log(String message)}public class Logger : ILogger{ private ILoggingProvider LoggingProvider { get; set; } public Logger(ILoggingProvider loggingProvider) { this.LoggingProvider = loggingProvider; } public void Debug(String message) { this.LoggingProvider.Log(message); }}public class Database : ILoggingProvider{ private ILogger Logger { get; set; } public Database(ILogger logger) { this.Logger = logger; } public void DoStuffWithTheDatabase() { // Do stuff with the database this.Logger.Debug("Did stuff with the database."); } public void Log(String message) { // Store message to database - be carefull not to generate new // log messages here; you can only use the subset of the Database // methods that do not themselve generate log messages }}

posted date: 2009-04-07 13:33:00

Re: Egg-chicken problem in OOP way#7
You could add another class that both the Database and Logger use to avoid getting into an infinite logging loop (and avoid the circular dependency as well).// Used only by Logger and DatabaseProxyclass Database { function doInsert( $sql ) { // Do the actual insert. }}class Logger { function log($sql) { $msg_sql = ... Database.doInsert($msg_sql);}// Used by all classesclass DatabaseProxy { function doInsert( $sql ) { Logger.log($sql); Database.doInsert($sql); }}You could dress it up a bit by having both Database and DatabaseProxy implement a common interface as well, and use a factory to provide the appropriate instance.

posted date: 2009-04-07 13:35:00

Re: Egg-chicken problem in OOP way#8
You have combined too many things together.The database can(t really depend on a logger which depends on the database. It isn(t good design. What you really have are two kinds of database access.Low-level access does "raw" SQL. The logger can depend on this lower-level class. It doesn(t -- itself -- have raw SQL in it. It depends on a lower-level class.High-level access does application queries, it uses low-level access and the logger.

posted date: 2009-04-07 13:36:00

Re: Egg-chicken problem in OOP way#9
Doesn't that leave you with a recursion problem?

posted date: 2009-04-07 13:37:00

Re: Egg-chicken problem in OOP way#10
IMHO, the database class should not be interacting with the logger. I would be inclined to call the logger from the same part of the code that is calling the database class. Then the logger can use the database class to do its inserts.

posted date: 2009-04-07 13:43:00

Re: Egg-chicken problem in OOP way#11
That is exactly what S.Lott pointed out. You cannot use logging everywhere in the Database class - so it would be good to explicitly seperate these parts.

posted date: 2009-04-07 13:45:00

Re: Egg-chicken problem in OOP way#12
Putting "raw" SQL in your logger class is a great way to make a mess you'll have to clean up later. Just pass it to a database object and pass the database object to it.

posted date: 2009-04-07 13:50:00

select page: « 1 2...»
Copyright ©2008-2017 www.momige.com, all rights reserved.