This is usually a sign of poor design if you need to explicitly switch behavior based on the type of object. Whenever you add a shape, you will have to update all the places where you use these type-based switches.
Your main "weapon" in such cases is polymorphism and virtual functions .
In the easiest approach, you can have an IShape method that the editor creates on its own:
public interface IShape { IShapeEditor CreateEditor(); } public interface IShapeEditor { void ShowDialog(); } public class Square : IShape { public IShapeEditor CreateEditor(){ return new SquareEditor(this); } } public class Triangle: IShape { public IShapeEditor CreateEditor(){ return new TriangleEditor(this); } } public class Circle: IShape { public IShapeEditor CreateEditor(){ return new CircleEditor(this); } }
In this case, your editing method might look like this:
public static void Edit(IShape shape) { shape.CreateEditor().ShowDialog(); }
The problem with this approach is that you may not want the form to know about the editor. The pattern that is trying to solve this problem is the pattern.
Using a visitor template might look like this:
public interface IShapeVisitor { void VisitSquare(Square s); void VisitTriangle(Triangle t); void VisitCircle(Circle c); } public interface IShape { void Accept(IShapeVisitor visitor); } public class Square : IShape { public void Accept(IShapeVisitor visitor){ visitor.VisitSquare(this); } } public class Triangle: IShape { public void Accept(IShapeVisitor visitor){ visitor.VisitTriangle(this); } } public class Circle: IShape { public void Accept(IShapeVisitor visitor){ visitor.VisitCircle(this); } }
This is the basic structure. For the editor you know, create such a visitor:
public class EditorCreationVisitor : IShapeVisitor{ IShapeEditor editor; public void VisitSquare(Square s ){ editor = new SquareEditor(s); } public void VisitTriangle(Triangle t ){ editor = new TriangleEditor(t); } public void VisitCircle(Circle c ){ editor = new CircleEditor(c); } public IShapeEditor Editor {get{return editor;}} }
Your editing method will now look like this:
public static void Edit(IShape shape) { var visitor = new EditorCreationVisitor(); shape.Accept(visitor); var editor = visitor.Editor; editor.ShowDialog(); }
The visitor pattern works best if the number of different types of shapes is fairly constant, but you regularly add different behavior.