Dangers of mutual dependencies
Much like most people, I try work out my class dependencies through a top-down ‘waterfall’-ish approach. By attempting this, I think allows me to keep the structure very clear and understandable.
excuse my non-existent UML skills
In this example the Ingredient class (and subclasses) is Never aware of any Recipe classes, but only the other way round.
I try to apply the same model to instantiated objects and packages (groups of classes). When an object encapsulates another object, I attempt to make sure the sub-object object is not aware of the parent. When I design packages, I attempt to make sure 2 packages don’t require ‘each other’.
An example where this could be a problem is the following. Say, I have a ‘Database’ package. I want to log every database error to a ‘Log’ package. The ‘Log’ package has a couple of implementations, such as ‘Log_File’, ‘Log_Syslog’, but now I added ‘Log_Database’ to log any problems to the database.
Strictly speaking these two packages can no longer be separated and will always have to be used/downloaded together. As a bonus a database-error could occur while logging, resulting in an endless loop (or segmentation fault if you’re using PHP).
Another example of a mutual dependency:
<?php include 'file2.php'; ?>
<?php include 'file1.php'; ?>
You get the idea ;)
However, these types of situations are sometimes simply unavoidable (that’s why we have include_once). When they are needed, they should be implemented with care and consideration. The problem with the Log class could be fixed if the Log_Database is aware of errors thrown by itself, and this could be repackaged by creating by separating the Log_Database in a new package, depending on both the ‘Connection’ and ‘Log’ classes.
Editors note: this post was part of a much larger article around designing plug-in systems, but I lost inspiration and decided to post just this part.