Reputation: 690
in one application I have a lot of dirrerent object, let´s say : square, circle, etc ... a lot of different shape ---> I´m sorry for the trivial example.
With all this object I want to create a doc of different type : xml, txt, html, etc.. (e.g.: I want to scan all the object (shapes) tree and produce the xml file.
The natural approach I thought is visitor pattern, I tried and it works :-)
- all the objects have one visit method accepting the IVisitor interface.
- I have one concrete visitor for every kind of do I want to create : (XmlVisitor
, TxtVisitor
, etc). Every visitor has one method "visit" for every kind of object.
My doubt is ... it doesn´t seems scaling well if I have a lot of object ... from the logic point of view it´s ok, i have just to add the new shape and the method in the concrete Visitor, that´s all.
What do you think ? is an althernative possible ?
Upvotes: 1
Views: 107
Reputation: 4389
I believe you have :
Shape
s in your example) andexportXML
, exportToHTML
etc in your example)You have to consider what is more likely to change -
You should choose Visitor pattern if the class hierarchy is more or less fixed but you would like to add more operations in future. Visitor pattern will allow you to add more operations (e.g. JSON export) without touching the existing class hierarchy.
OTOH if the operations are more or less fixed, but more Shape objects can be added, then you should use regular inheritance. Define a ShapeExport
interface which has methods like exportToXML
, exportToHTML
etc. Let all Shapes implement that interface. Now you can add new Shape which implements the same interface without touching existing code.
Upvotes: 0
Reputation: 1693
I think that you have correctly implemented a visitor pattern and as a result you also have implemented a double dispatching mechanism. If you consider the "not scaling well" as a need to add a bunch of methods in case of adding a new shape and/or visitor, then it is just a side effect of the pattern. Some people consider this "method explosion" as harmful and opt for a different implementation, such as having a "decision matrix" object. For this example in particular I think that the DD approach is the way to go and that actually it does scale well, since you add new methods as you add new requirements (i.e. you add new visit* methods as new shapes are added or you add a new visitor class as new document types are needed).
HTH
Upvotes: 1
Reputation: 26858
It seems to me that what worries you the most is that you are matching against many different kinds of objects, and worry that as more and more object types are added, the performance will suffer. I don't think you need to worry about that, though: The performance of the visitor pattern is not really affected by the potential number of objects or visitors, since it is based on virtual table lookup - the passed object will contain a link to (a link to) the method which should be called.
So the visitor pattern, though relatively expensive in indirect accesses, is scalable in this regard.
Upvotes: 1