Nice TWiki > Doc > CodeExamples > VisitorPatternMultiMethodExample (r1.4) TWiki webs:
Dev | Doc | Main | TWiki | Sandbox
Doc . { Changes | Index | Search | Go }
The first part of each example gives the existing datatypes and operations; the second part shows how we could add a datatype and how we could add an operation.

There are partial approaches - the Functional approach, easy to add an operation; the OO approach (Composite Pattern), easy to add a datatype - and approaches that allow extension of both datatypes and operations, the Visitor Pattern and Extensible Visitor Pattern.

Here's the multimethod and open class approach to extending software without modification.


/* Please try the NoviceExamples before the MultiMethodExamples
To compile:
   nicec --sourcepath .. -a multimethod.jar multimethod
To run:
   java -jar multimethod.jar
*/


// Multimethods: Types and Operations
//-----------------------------------

abstract class Shape {
   boolean containsPoint(Point p);
}

class Square extends Shape { 
   double side; 

   containsPoint(p) {
      let d = side/2;
      return 
         (p.x >= -d && p.x < d) && 
         (p.y >= -d && p.y < d);
   }
}

class Circle extends Shape { 
   double radius; 

   // just test the bounding box
   containsPoint(p) {      
      return 
         (p.x >= -radius && p.x < radius) && 
         (p.y >= -radius && p.y < radius);
   }
}

class Translated extends Shape { 
   Point d; 
   Shape shape; 

   containsPoint(p){
      let p' = 
         new Point(
            x: p.x - d.x,
            y: p.y - d.y );
 
      return shape.containsPoint(p');
   }
}

class Point { double x; double y; }



/*
   =================================================
   Can we add a type and operation without modifying 
   the original code?
   ================================================= 
*/


// Multimethods: Adding Type Variants
//-----------------------------------

class Union extends Shape {
   Shape shape1; 
   Shape shape2; 

   containsPoint(Point p) =
      shape1.containsPoint(p) || shape2.containsPoint(p);
}



// Multimethods: Adding Operations
//--------------------------------

Shape shrink(Shape s, double toPercent);

shrink(Square s, toPercent) = 
   new Square(side: (s.side*toPercent)/100);
   
shrink(Circle s, toPercent) = 
   new Circle(radius: (s.radius*toPercent)/100);

shrink(Translated s, toPercent) = 
   new Translated(d: s.d, shape: s.shape.shrink(toPercent)); 
   
shrink(Union s, toPercent) =
   new Union(
      shape1: s.shape1.shrink(toPercent),
      shape2: s.shape2.shrink(toPercent)   
   );  



// Multimethods: 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);

   println("square contains point " + s.containsPoint(p));
   println("circle contains point " + c.containsPoint(p));
   println("translated contains point " + t.containsPoint(p));


   let t' = t.shrink(toPercent: 50);
   println(
      "shrunk translated contains point " + 
         t'.containsPoint(p));
                            
   let u = new Union(shape1: s, shape2: t);
   println("union contains point " +  u.containsPoint(p));            
}



/* Notes 
See the detailed discussion in
"Synthesizing Object-Oriented and Functional Design to Promote Re-use"
Section 7 p110
http://citeseer.nj.nec.com/krishnamurthi98synthesizing.html


square contains point false
circle contains point false
translated contains point true
shrunk translated contains point false
union contains point true

*/
-- IsaacGouy - 06 Feb 2004

Topic VisitorPatternMultiMethodExample . { Edit | Attach | Ref-By | Printable | Diffs | r1.7 | > | r1.6 | > | r1.5 | More }
Revision r1.4 - 14 Feb 2004 - 20:59 GMT - IsaacGouy
Parents: WebHome > CodeExamples
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.

Doc.VisitorPatternMultiMethodExample moved from Doc.VisitorMultiMethodExample on 06 Feb 2004 - 15:18 by IsaacGouy - put it back