Composition problem
I have a class A that uses class B. Class B uses class C. When I am in class A I want to retrieve data from class C. Currently, when I am in class A, I am using a method call on class B to ask class C for the data. The effect is that I am passing the data item from C to B and then from B to A. Now I know there has to be a better way to pass data around between classes but I can't think of a way to do so without lots of redundant methods across classes and without forcing certain classes along the chain to offer methods that they have no right to offer.
So, for example, my class A wants to graphically display the total number of unique IP addresses as determined by the method getNumUniqueIPs() in class C. Unfortunately, A doesn't have a reference to C to directly retrieve that information so I have to write a method in B (presumably also called getNumUniqueIPs) to have B get the data from C and pass it to A.
So, my question is, is there a way around this indirect data retrieval? I'd like to point out that class A needs much more data from C than just the unique number of IPs. In other words, this isn't an isolated case. I also have this problem among other parts of my class structure. Any help would be appreciated. Thanks.
[1264 byte] By [
amjavadeva] at [2007-10-2 23:55:39]

> I have a class A that uses class B. Class B uses
> class C. When I am in class A I want to retrieve
> data from class C. Currently, when I am in class A,
> I am using a method call on class B to ask class C
> for the data. The effect is that I am passing the
> data item from C to B and then from B to A.
Why do you think this is a problem?
I thought it was potentially a design problem until you stated
" I'd like to point out that class A needs much more data from C than just the unique number of IPs."
If by this you mean you retrieve a large set of data from C then parse it into smaller parts that are then passed on individually through A, then this is OK. If you mean you have a bunch of methods on A that just forward onto C, then I question the value of this design.
Perhaps A should just be returning C. If you are returning all the state of C through methods on A, then you are really not encapsulating C. Maybe take a 2nd look at how you partitioned your responsibilities.
In fact, you said yourself A needs data from C. That's a subconscious indication that B needs to get out of the way unless B is providing C.
Let me restate my question. What is the purpose of B? Why does it exist? How did you get to the current structure?
Thanks for the replies. I believe my problem is a design flaw. I just spoke with one of the lead software engineers at my company and he gave me some pointers as to how to fix the design. It seems as though I was trying to split the responsibilities from class B (the "middleman" in my example) off to a separate class C because I was worried that I was delegating unrelated responsibilites to class B that I thought it shouldn't be required to handle. So, in this case, class B needed some data regarding IP addresses and I thought that by delegating those responsibilites to another class I was creating a "cleaner" design. Turns out that my coworker claims that Agile development practices dictate that unless the software developer has a specific reason for offloading work from one class to another, then it's best to leave the design alone. I'm following his advice now (there was more to it than that) but I'll post another message if things don't turn out as well as I hope. Thanks again for the responses.
Agile software does say that. It would also suggest that once you get it all working you go back over it and make it 'cleaner' just for the sake of it being cleaner. So hold onto your ideas for later.Good Luck.
> Turns out that my coworker claims
> that Agile development practices dictate that unless
> the software developer has a specific reason for
> offloading work from one class to another, then it's
> best to leave the design alone.
Turns out your co-worker doesn't quite know what he's talking about.
Agile development practices "dictate" that you refactor your code in each iteration, until everything is expressed once and only once. They do not dictate you make god classes until you have a specific reason to design properly, in fact the opposite.
Like many people, he seems to have gotten this confused with the "You Aren't Gonna Need It" 'rule', which says don't add features until they are actual current requirements. Focus only on the features for the Use Case / User Story you are currently working on, but refactor mercilessly at all times.
For example, let's say in your current story you have a requirement which involves storing some objects to disk for retrieval in a later run of the application, in an XML file. Your co-worker seems to imply that Agile practices mean you hardwire your storage and retrieval code in the business class being stored itself, until you ever need to support storing in a DB or in another format. That's dead wrong.
YAGNI implies that, indeed you do not at this point waste time writing code for any other storage mechanism than what you currently require, or for determining which StorageStrategy to use etc. Refactor mercilessly implies that, because the storage and retrieval is a separate concept, you still express this in a separate class right away or as one of the first refactorings once everything works.
There practices are very connected; refactoring to a clear design is one of the reasons why you can afford not to think about every possible new or changed requirements in the future yet.
Misunderstanding about key practices, along with the appeal the magic word "Agile" seems to have as an excuse for working sloppily, leads to many a disaster...
Message was edited by:
Loko
Lokoa at 2007-7-14 16:42:04 >

