| <<O>> Difference Topic VisitorPatternExample (r1.6 - 28 Apr 2005 - TWikiGuest) |
| <<O>> Difference Topic VisitorPatternExample (r1.5 - 31 Jan 2005 - LiYan) |
| <<O>> Difference Topic VisitorPatternExample (r1.4 - 23 Jan 2005 - TWikiGuest) |
| Added: | |
| > > | |
| Changed: | |
| < < | -- IsaacGouy - 06 Feb 2004 |
| > > | |
| <<O>> Difference Topic VisitorPatternExample (r1.3 - 14 Feb 2004 - IsaacGouy) |
| Changed: | |
| < < | // Visitor Pattern: Tools //----------------------- |
| > > | // Visitor Pattern: Operations //---------------------------- |
| Changed: | |
| < < |
========================================
Can we add a type and tool without modifying
|
| > > |
=============================================
Can we add a type and operation without modifying
|
| Changed: | |
| < < |
========================================
|
| > > |
=============================================
|
| Changed: | |
| < < | // Visitor Pattern: Adding Tools //------------------------------ |
| > > | // Visitor Pattern: Adding Operations //----------------------------------- |
| Changed: | |
| < < | //--------------------------- |
| > > | //------------------------- |
| <<O>> Difference Topic VisitorPatternExample (r1.2 - 06 Feb 2004 - IsaacGouy) |
| Changed: | |
| < < | %META:TOPICPARENT{name="VisitorMultiMethodExample"}% |
| > > | %META:TOPICPARENT{name="VisitorPatternMultiMethodExample"}% |
| <<O>> Difference Topic VisitorPatternExample (r1.1 - 06 Feb 2004 - IsaacGouy) |
| Added: | |
| > > |
%META:TOPICINFO{author="IsaacGouy" date="1076042497" format="1.0" version="1.1"}%
%META:TOPICPARENT{name="VisitorMultiMethodExample"}%
/* Please try the NoviceExamples before the MultiMethodExamples
To compile:
nicec --sourcepath .. -a visitor.jar visitor
To run:
java -jar visitor.jar
*/
// Visitor Pattern: Types
//-----------------------
abstract class Shape {
<T> T process(IShapeVisitor<T> v);
}
class Square extends Shape {
double side;
process(IShapeVisitor v) = v.forSquare(this);
}
class Circle extends Shape {
double radius;
process(IShapeVisitor v) = v.forCircle(this);
}
class Translated extends Shape {
Point d;
Shape shape;
process(IShapeVisitor v) = v.forTranslated(this);
}
class Point { double x; double y; }
// Visitor Pattern: Tools
//-----------------------
interface IShapeVisitor<T> {
T forSquare(Square s);
T forCircle(Circle s);
T forTranslated(Translated s);
}
<T| boolean <: T <: boolean>
class ContainsPointVisitor<T> implements IShapeVisitor<T> {
Point point;
forSquare(Square s){
let d = s.side/2;
return
(point.x >= -d && point.x < d) &&
(point.y >= -d && point.y < d);
}
forCircle(Circle s) =
// just test the bounding box
(point.x >= -s.radius && point.x < s.radius) &&
(point.y >= -s.radius && point.y < s.radius);
forTranslated(Translated s){
let p' =
new Point(
x: point.x - s.d.x,
y: point.y - s.d.y );
return s.shape.process(
new ContainsPointVisitor(point: p'));
}
}
/*
============================================
Can we add a type and tool without modifying
the original code?
============================================
*/
// Visitor Pattern: Adding Type Variants
//--------------------------------------
interface IUnionVisitor<T> extends IShapeVisitor<T> {
T forUnion(Union s);
}
class Union extends Shape {
Shape shape1;
Shape shape2;
process(IShapeVisitor v) = cast(v).forUnion(this);
}
<T| boolean <: T <: boolean>
class ContainsPointUnionVisitor<T>
extends ContainsPointVisitor<T> implements IUnionVisitor<T> {
forUnion(Union s) =
s.shape1.process(this) || s.shape2.process(this);
}
// Visitor Pattern: Adding Tools
//------------------------------
<T| Shape <: T <: Shape>
class ShrinkVisitor<T> implements IShapeVisitor<T> {
double toPercent;
forSquare(Square s) =
new Square(side: (s.side*toPercent)/100);
forCircle(Circle s) =
new Circle(radius: (s.radius*toPercent)/100);
forTranslated(Translated s) =
new Translated(d: s.d, shape: s.shape.process(this));
}
// Visitor Pattern: Testing
//---------------------------
void main(String[] args){
let s = new Square(side: 4);
let c = new Circle(radius: 2);
let t =
new Translated(
d: new Point(x: 1.5, y: 0),
shape: c
);
let p = new Point(x: 3, y: 0);
let v = new ContainsPointVisitor(point: p);
println("square contains point " + s.process(v));
println("circle contains point " + c.process(v));
println("translated contains point " + t.process(v));
let vshrink = new ShrinkVisitor(toPercent: 50);
let t' = t.process(vshrink);
println("shrunk translated contains point " + t'.process(v));
let u = new Union(shape1: s, shape2: t);
println("union contains point " + u.process(v) ); // FAILS AT RUNTIME
}
/*
/* Notes
See the detailed discussion in
"Synthesizing Object-Oriented and Functional Design to Promote Re-use"
Section 3.1 figures 7, 8, 9, 10, 11
http://citeseer.nj.nec.com/krishnamurthi98synthesizing.html
square contains point false
circle contains point false
translated contains point true
shrunk translated contains point false
Exception in thread "main" nice.tools.code.EnsureTypeProc has wrong type
*/
-- IsaacGouy - 06 Feb 2004 |
| Topic VisitorPatternExample . { View | Diffs | r1.6 | > | r1.5 | > | r1.4 | More } |
|
Revision r1.1 - 06 Feb 2004 - 04:41 GMT - IsaacGouy Revision r1.6 - 28 Apr 2005 - 11:56 GMT - TWikiGuest |
Copyright © 1999-2003 by the contributing authors.
All material on this collaboration platform is the property of the contributing authors. Ideas, requests, problems regarding TWiki? Send feedback. |