Last active
January 8, 2017 21:06
-
-
Save nuttycom/6e286855bc67b3d89096824eba33d531 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
interface ShapeVisitor<A> | |
{ | |
// The implementation of ApplyRect defines handling for the | |
// operation defined by this visitor in the case that the | |
// shape is a rectangle. | |
public A ApplyRect(IRectangle rect); | |
// The implementation of ApplyCircle defines handling for the | |
// operation defined by this visitor in the case that the | |
// shape is a circle. | |
public A ApplyCircle(ICircle circle); | |
} | |
public class AreaVisitor : ShapeVisitor<double> | |
{ | |
public double ApplyRect(IRectangle rect) | |
{ | |
return rect.height * rect.width; | |
} | |
public double ApplyCircle(ICircle circle) | |
{ | |
return Math.PI * circle.radius * circle.radius ; | |
} | |
} | |
public class PerimeterVisitor: ShapeVisitor<double> | |
{ | |
public double ApplyRect(IRectangle rect) | |
{ | |
return 2 * (rect.height + rect.width); | |
} | |
public double ApplyCircle(ICircle circle) | |
{ | |
return Math.PI * circle.radius * 2; | |
} | |
} | |
abstract class IShape { | |
public A accept<A>(ShapeVisitor<A> visitor); | |
// This becomes essentially syntactic sugar; it need not be defined as a method on the interface. | |
public double GetArea() | |
{ | |
return accept(new AreaVisitor()); | |
} | |
// I will not define GetPerimeter here - there is no purpose. The user | |
// can simply call myShape.accept(new PerimeterVisitor()) if they | |
// wish that functionality. The point here is that the end user can "extend" | |
// the interface by adding new Visitor implementations - they do not need | |
// IShape to be altered. | |
} | |
class ICircle : IShape { | |
public A accept<A>(ShapeVisitor<A> visitor) { | |
return visitor.ApplyCircle(this); | |
} | |
} | |
class IRectangle: IShape { | |
public A accept<A>(ShapeVisitor<A> visitor) { | |
return visitor.ApplyRect(this); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Never mind! Found and commited the changes to switch to a visitor