The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Advice Please: Dodgy design or is it just me?

Hi all, I'm working on a project and I've seen something that I think is questionable. Now because my design skills aren't too strong I need some outside advice please.

We have a Manager object that holds references to other objects, DataObjects. All of these contained DataObjects require a reference to the Manager itself when they are instantiated. This is so a DataObject can easily get access to other DataObjects it needs through the passed in Manager reference.

Is my uneasiness of this justified, and if it is, is there a better way? I mean, I would just pass in the references that each DataObject needs instead of anything it might need.

Thanks for reading!
Jonathan R Send private email
Thursday, June 14, 2007
 
 
Without knowing more about the context of this design it is very hard to judge the merit of this particular design decision. While in general I am not a big fan of the structure you describe, maybe there is a very good reason to use it in this case.
Jeroen
Thursday, June 14, 2007
 
 
Yes, it's usually preferable to avoid bidirectional relationship between objects but there are some cases where it's the best thing to do.

It's nice to spread the behaviour of an application in several classes but when the classes have dependencies between each other it can turn into a complete mess. You can't reuse a class without pulling all the others, a change in a class affects a lot of other classes,...
To avoid that problem you can use the mediator pattern. It's a pattern where you have a central class (the mediator) and classes only call that mediator instead of calling each other.
I don't know if you have that particular problem but it's certainly something to be aware of.


Your problem remember me the dependency injection pattern. You might want to read about it : http://www.martinfowler.com/articles/injection.html .
The thing that will interest you the most with that article is that there are two main way to add a depency to an object :
-the object makes a call to retrieve the dependency
-the dependency is "injected" through constructor or property/setter when the object is created.

What's the best thing to do? It depends on the situation.
Monkeyget Send private email
Thursday, June 14, 2007
 
 
One alternative would be to abstract the searching functionality to an Interface and pass that in instead, now your DataObject would not be directly linked to the Manager object. The Manager could implement the interface and pass in a reference to it in the DataObjects constructor.
RobJ Send private email
Thursday, June 14, 2007
 
 
Apologies if the description was a bit wishy-washy. One of the main reasons the Manager was being passed around was that it also provided access to a database. I believe that it was due to convenience that the DataObject references were included in it.

I separated the database code to another class and this made the Manager of no use to most of the DataObjects. I'm now attempting to replace references to the Manager with this new 'connection object' in the DataObjects.

Thanks for the replies, they have given me a lot to think about and I think I can now see a way forward. :-)

Cheers.
Jonathan R Send private email
Thursday, June 14, 2007
 
 
I cannot reconcile your two statements:

OP:
"This is so a DataObject can easily get access to other DataObjects"

Later:
"...this made the Manager of no use to most of the DataObjects"

Originally it sounded like the problem was the DataObjects reaching through the Manager to access the other DataObjects. But later it sounds like they were only using the manager to get to the database.

In the case of the original problem I would say it is unlikely the DataObjects should be objects at all. In the latter case, I would say you have done the correct thing.
onanon
Thursday, June 14, 2007
 
 
If the manager exists only to give access to other objects then it would be better to use service discovery for each individual service rather than collect them under one object. Others disagree. I don't like the binding of the manager object. You are linking parts of the program together that have no nead to know about each other. I prefer a singleton, something like string, jndi.
son of parnas
Thursday, June 14, 2007
 
 
Agreed.

It may be that the choice of name "Manager" was rather misleading. It implied that the parent object, so to speak, has control over the child objects and in reality, no such relationship existed nor was needed.

Big picture wise, I think the original described arrangement is somewhat acceptable if there was a centralized third party security module that you needed to treat as a black box. Under such a secenario, data objects would need to "negotiate" access to other data objects or to the database itself.

Given the problem as described, I think it does make more sense to have a unidirectional relationship wherein the various data objects all call and share the one connection object.
TheDavid
Thursday, June 14, 2007
 
 
"holds references" is a vague relationship.  If manager has references to an abstract type (eg Java interface) that the manager package owns, and all data objects implement/extend that abstraction, then dependency only flows from DO package to Mgr package and there's no problem. If the manager depends on the exact types of the DOs (DO must be present to compile manager, changing the DO can break the manager) then there's a highly suspect circular dependency.
Stan James Send private email
Thursday, June 14, 2007
 
 
Hi,

To onanon: Both were true, the manager provided database access and access to the other DataObjects. I didn't mention the db originally because I thought it would muddy the waters.

After splitting out the db code from the Manager it didn't seem necessary to pass the Manager to all the DataObjects. I needed another way for the DataObjects to get a handle on others. It seems that the 'service locater' approach would fit nicely here and it's what I'm going to go with.

I appreciate that I've been talking in very loose terms and I agree that the names are somewhat misleading. To be honest I'm not convinced by the overall design of the project and it feels like I'm just applying band-aids. I just want to improve my design skills so I can do something about it. :-)

Again, thanks for all the comments.
Jonathan R Send private email
Friday, June 15, 2007
 
 
Jonathan

the situation you mention remembers me two tings I came across very recently: one, the dependency injection that someone else has already suggested. The other is the need of a kind of "super factory" to allow an object to get references to instances of other objects, whith out actually knowing how to instantiate them (this include the posibility to retrieve them from a db).

To avoid passing the reference to this factory object to each object, I created an static method in a Environment class which retrieved a singleton instane of the factory. Now, each object can access instances of any type doing something like this:

SomeType obj = Environment.getFactory().createObject(SomeTpe);

Based on the class type is passed to the factory's createObject method, it looks for the appropiated concrete factory, and retrieves an instance.

Pablo
Pablo Chacin Send private email
Saturday, June 16, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz