[Tutor] Dependencies among objects

Jeff Shannon jeff@ccvcorp.com
Thu, 25 Apr 2002 10:27:38 -0700


> Alexandre Ratti <alex@gabuzomeu.net> wrote:
>
> while working on my pet project, I find it increasingly difficult to manage
> dependencies across objects.
> [...]

> Passing around lost of references as arguments is getting messy. Hence I
> thought about this design: storing references to helper objects in a parent
> class so that every child class can access it easily.

[...]

> Do you think this is a good design?

I think there are better ways of handling the issue.  To a fair degree, the best way to do it will depend on your overall
architecture for the project.  Lately, most of my projects have been GUI (wxPython) apps, so I tend to store any widely useful
objects as attributes of the window object (or an appropriate dialog object, etc.)  Since everything is already "owned" by either
the window or the App object, this makes sense.  In a console app, however, it might not be such a good choice (unless you already
have an App object, or something similar).

At the most basic level, what you're doing could be simply expressed by creating a global dictionary, and storing object references
in that.

archive = {}
...
class Bar:
    def DoIt(self):
         value = "I am Bar and I use '%s'."
         return value % archive['foo'].getValue()

if __name__ == '__main__':
    archive['foo'] = Foo()
    bar = Bar()
    bar.DoIt()

A better way would be to look at how your project is structured, conceptually, and to make these objects "belong" to the class that
they're most conceptually related to.  For instance, you might have a Document class, and have the PageIndex and TextIndex classes
stored as attributes of the Document.  When someone modifies the Document (using Document's methods, of course), then the Document
could automatically update the Indexes.  Document could also provide methods to give easy access to the indexes, either by
delegating individual function calls (Document.FindTextLocation() calling into TextIndex and returning the result), or by directly
returning a reference to the TextIndex object.  The first method is usually better, if practical, because it lets you change your
TextIndex without disturbing anything that uses the Document class, but if there's a lot of different method calls to delegate, it
might not be practical.

Keep in mind that the whole point of objects is to let the structure of your code mimic the conceptual structure of your problem.
Object references should be kept where the conceptually "belong", and if you've broken your project into appropriate parts, this
*should* minimize the cross-dependencies.  Of course, there always will be dependencies, but a good design should reduce them.

Jeff Shannon
Technician/Programmer
Credit International