File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes OO, Patterns, UML and Refactoring and the fly likes (Visitor) two different collections Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "(Visitor) two different collections" Watch "(Visitor) two different collections" New topic
Author

(Visitor) two different collections

Pho Tek
Ranch Hand

Joined: Nov 05, 2000
Posts: 761

Hi,

I have a class which initially consists of one Collection of objects.

Now I am adding the ability to nest Foo within another Foo. I, however, want to maintain the accept method signature.

Should I add another accept method, perhaps calling it accept2 or do an if switch within the current method ?

[ November 21, 2006: Message edited by: Pho Tek ]
[ November 21, 2006: Message edited by: Pho Tek ]

Regards,

Pho
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I'm not clear what your goal is. How many times do you want the visitor to be called? Do you want accept() to visit one collection or the other or both?


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2922
    
    5
Originally posted by Pho Tek:
Should I add another accept method, perhaps calling it accept2 or do an if switch within the current method ?


I'd be tempted to implement the IVisitor interface on two different inner classes of Foo; one exposing the IVisitor for stuff the other for foos - then add two functions to retrieve the appropriate interface. Similar to the tactic that the FactorParameter class uses in Handle situation where there can be Potential increase in the method parameters.

However I would be even more tempted to take a good look at the class and decide whether it is time to split the class in two - at which point the problem will go away.

Ultimately you may be trying to implement the Composite Pattern. In that case there shouldn't be a collection of "stuff" only one single "stuff". The only collection present should be foos - and your problem goes away. Foo objects acting as leaves store a single "stuff" while Foo objects acting as nodes only store other Foo objects in the foos collection.

Composite Pattern:
http://www.exciton.cs.rice.edu/JavaResources/DesignPatterns/composite.htm
http://www.javaworld.com/javaworld/jw-09-2002/jw-0913-designpatterns.html
http://www.allapplabs.com/java_design_patterns/composite_pattern.htm
http://www.fluffycat.com/Java-Design-Patterns/Composite/
[ November 21, 2006: Message edited by: Peer Reynders ]
Pho Tek
Ranch Hand

Joined: Nov 05, 2000
Posts: 761

Peer,

BTW, I've edited the code to highlight the differences of objects contained in the Collections.

It is my intention to use the composite pattern! The original Foo class initially just contains one Collection, namely stuff. Following that, a change request commanded that Foo must be able to nest other Foos.

1) Perhaps I don't understand the pattern properly. I cannot see the use of leaf nodes in my situation. All Foo are composites. And the ones with an empty collection of children Foos are the leafs.


Foo objects acting as leaves store a single "stuff" while Foo objects acting as nodes only store other Foo objects in the foos collection.


Foo has a 1-many relation with Bar (see updated code).

2) I think I can learn somethings from the FactorParameter link that you sent. For now, as a stopgap measure, I am using a conditional within the accept method.

e.g.

Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2922
    
    5
Originally posted by Pho Tek:
Foo has a 1-many relation with Bar (see updated code).


Your new solution is problematic as it requires the visitor to implement the .interestedInFoo() method, basically strengthing the coupling between the visitor and the class being visited.

I appreciate that in your original design "Foo has a 1-many relation with Bar". However once you use the composite you should convert the "Foo has a 1-many relation with Bar" to "Foo has a 1-many relation with Foo objects which each have one Bar" which is just a special case of "Foo has a 1-many relation with Foo objects".

There is another implementation possibility. If you take a look at the composite pattern you should notice that both the Leaf and the Composite implement the same Component interface. In your case the Component interface is the IVisitable interface. Keep your Foo Class as is and use it as the Leaf Class. Create a new class FooFoo which manages the new IVisitable collection (Foos or other FooFoos) and implements the IVisitable interface. FooFoo then simply delegates the accept request to all of its IVisitables.
[ November 22, 2006: Message edited by: Peer Reynders ]
Pho Tek
Ranch Hand

Joined: Nov 05, 2000
Posts: 761

Peer,

Thanks for the clarification.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: (Visitor) two different collections