This week's book giveaway is in the Artificial Intelligence and Machine Learning forum.
We're giving away four copies of Succeeding with AI and have Veljko Krunic on-line!
See this thread for details.
Win a copy of Succeeding with AI this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Liutauras Vilda
  • Junilu Lacar
Sheriffs:
  • Tim Cooke
  • Jeanne Boyarsky
  • Knute Snortum
Saloon Keepers:
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:
  • salvin francis
  • fred rosenberger
  • Frits Walraven

Query regarding Visitor design pattern

 
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Everyone,
I am in the process of understanding the Visitor design pattern. My understanding is that somewhere this pattern creates a monolithic class with various functions.
If even 1 of the functions changes, then either a new class has to be created (just to change a function and copying the rest of the functions as it is) or one can edit the current function thereby violating open/close principle.

Let me share an example.



below is one of the classes that implement the above interface



Now suppose Necessity's implementation changes, either one has to create another implementation, copying the rest of the code, to just change Necessity or one has to manually change the visit method (used by Necessity), thereby violating open/close principle.

Is this violating the interface segregation principle?  Can we improve or change anything in this? Thanks in advance.
 
Saloon Keeper
Posts: 11923
253
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What do you mean by "Necessity's implementation changes"? And why does that mean one has to change the implementation of the visitor? Maybe it's best if you give a concrete example.
 
Marshal
Posts: 15565
263
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
1. True, for every new type of taxable item you need to visit, you'll need to add a new overloaded version of the visit() method. That's the disadvantage of the Visitor pattern.
2. Re "this patterns creates a monolithic class with various functions" -- first of all, the pattern doesn't create anything. Maybe you meant "... this pattern results in a monolithic class with potentially many overloaded versions of the visit() method" -- this is more accurate and is in line with #1 above.
3. The "visit" method doesn't always need to be literally named visit(). In this case, I would probably name it "getTaxFor()" or something that more clearly expresses what it's doing in the language of the domain. The name "visit()" as documented in the pattern is just a generalization.
4. Your implementation has smells.
4a. This is smelly: return Double.parseDouble(df.format(. . .)); -- why do this here? Why even do it at all?
4b. The TaxVisitor is also a little smelly to me. Seems like this is more appropriately called something like TaxCalculator. If you really want to retain the "Visitor" part of the name (which like the "visit" name is really not a requirement), I'd name it TaxableItemVisitor instead but that's still not a name that clearly expresses what the visitor does.
5. Your problem does not appear to be something where the Visitor pattern would be appropriately applied.

You should understand the context in which a pattern is meant to be applied. If you apply a pattern in a context that is inconsistent with the intended purpose, you run the risk of turning it into an anti-pattern instead.

This is a pretty good description of the appropriate context for Visitor (from https://sourcemaking.com/design_patterns/visitor)

Many distinct and unrelated operations need to be performed on node objects in a heterogeneous aggregate structure. You want to avoid "polluting" the node classes with these operations. And, you don't want to have to query the type of each node and cast the pointer to the correct type before performing the desired operation.



    Bookmark Topic Watch Topic
  • New Topic