Created
June 26, 2012 03:41
-
-
Save adam-singer/2993134 to your computer and use it in GitHub Desktop.
Basic Visitor Pattern Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Reference: http://en.wikipedia.org/wiki/Visitor_pattern | |
interface CarElementVisitor { | |
void visitWheel(Wheel wheel); | |
void visitEngine(Engine engine); | |
void visitBody(Body body); | |
void visitCar(Car car); | |
} | |
interface CarElement { | |
void accept(CarElementVisitor visitor); // CarElements have to provide accept(). | |
} | |
class Wheel implements CarElement { | |
String name; | |
Wheel(String name) { | |
this.name = name; | |
} | |
void accept(CarElementVisitor visitor) { | |
/* | |
* Wheel.accept(CarElementVisitor) overrides CarElement.accept(CarElementVisitor), so the call | |
* to accept is bound at run time. This can be considered the first dispatch. | |
* The decision to call CarElementVisitor.visitWheel(Wheel) however, rather than the other 'visit' | |
* methods in CarElementVisitor, can be made during compile time since 'this' is known at compile | |
* time to be a Wheel. Moreover, each subclass of CarElementVisitor overrides the visitWheel(Wheel), | |
* which is another decision that is made at run time. This can be considered the second dispatch. | |
*/ | |
visitor.visitWheel(this); | |
} | |
} | |
class Engine implements CarElement { | |
void accept(CarElementVisitor visitor) { | |
visitor.visitEngine(this); | |
} | |
} | |
class Body implements CarElement { | |
void accept(CarElementVisitor visitor) { | |
visitor.visitBody(this); | |
} | |
} | |
class Car implements CarElement { | |
List<CarElement> elements; | |
Car() { | |
//create new Array of elements | |
this.elements = new List<CarElement>(); | |
this.elements.add(new Wheel("front left")); | |
this.elements.add(new Wheel("front right")); | |
this.elements.add(new Wheel("back left")); | |
this.elements.add(new Wheel("back right")); | |
this.elements.add(new Body()); | |
this.elements.add(new Engine()); | |
} | |
void accept(CarElementVisitor visitor) { | |
for(CarElement elem in elements) { | |
elem.accept(visitor); | |
} | |
visitor.visitCar(this); | |
} | |
} | |
class CarElementPrintVisitor implements CarElementVisitor { | |
void visitWheel(Wheel wheel) { | |
print("Visiting ${wheel.name} wheel"); | |
} | |
void visitEngine(Engine engine) { | |
print("Visiting engine"); | |
} | |
void visitBody(Body body) { | |
print("Visiting body"); | |
} | |
void visitCar(Car car) { | |
print("Visiting car"); | |
} | |
} | |
class CarElementDoVisitor implements CarElementVisitor { | |
void visitWheel(Wheel wheel) { | |
print("Kicking my ${wheel.name} wheel"); | |
} | |
void visitEngine(Engine engine) { | |
print("Starting my engine"); | |
} | |
void visitBody(Body body) { | |
print("Moving my body"); | |
} | |
void visitCar(Car car) { | |
print("Starting my car"); | |
} | |
} | |
void main() { | |
Car car = new Car(); | |
car.accept(new CarElementPrintVisitor()); | |
car.accept(new CarElementDoVisitor()); | |
} |
I know, its definitely a used pattern in dart2js. Might start to gather what common design patterns look like in dart, maybe something similar to dofactories (www.dofactory.com) code but for dart.
That's a great idea. :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I see the Dart engy's using this pattern a lot in their parsing code.