Visitor Design Pattern - “_Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates. “ dofactory.com Another term you may hear when working with the Visitor Pattern, is Double Dispatch. How that applies to Visitor is that the accept method takes a visitor instance, which in turn has a visit method that takes the concrete instance (aka “this”). Inside the visitor visit method is where the core of the visitor pattern occurs. It is where you can extend the concrete class without actually editing the concrete class. _
Open Closed Principle (OCP)
“…using the visitor pattern helps conformance with the open/closed principle.” (Wikipedia) The Open/Closed Principle is that “a class is open for extension, closed for modification”. (Thank you Mr. Meyer) I recently used the Visitor pattern inline with usage of a State Pattern. The Visitor would be able to determine, based on it’s algorithms, which was changing regularly by the needs of the end user, whether an object could move to the next state in the machine. Adhering to our theme, a coffee shop, I decided to generat a paycheck stub . My C# example is showing how to report the coffee shop employees earned wages, deductions via sick days and number of vacation days taken:
Test Firsts (NUnit): [gist id=1067984] I have two test fixtures, one for hourly employees and one for full-time employees. Hopefully, via my rough version of Behavior Driven Development (BDD), you can read my tests without any problems. Implementation: [gist id=1067988] Please remember, this is “blog friendly” code. I would definitely break the visitor class apart into a few classes (i.e., WageCalculator, SickPayDeductionCalculator, etc).
Please understand that I’m a Ruby newbie and I’m petty sure there is a more “Ruby-ish” way to do this._ _I’ve recently been placed on a Ruby team and I’m making the transition from the static language mind-set to the dynamic language mind-set. I do understand with mix-ins you can dynamically add functionality to a class based on context, so visitor may not be necessary at all. I’m still grokking that concept. I still believe in the Open/Closed principle, but it may be moot with dynamic languages. It’s actually very exciting being a newbie developer again. It feeds my insatiable need to learn. Test (Using RSpec): [gist id=1067994] Implementation: [gist id=1067996]
What I Learned
I personally use the strategy pattern more than any other pattern. That is why I chose this pattern. So I could understand it better. A good example I saw recently, using lambdas and all the new .NET features was Chad’s comment (pastie.org) on Mo’s Recursive Command Post Hope this helps someone understand the Visitor Design Pattern better.