如果要將操作放在基類中,請使用抽象類型。您不希望每次決定添加新的子類時都必須修改基類。
另一種方法是使用類似visitor pattern的東西,並將每個具體類輪流發送給訪問者。然後交集訪問者將包含關於如何計算每對對象類型的交集的所有知識。
以下是訪問者模式可以如何用於此目的。 (我將使用Java語法,因爲我不是C#程序員)。首先,在這裏使用訪問者模式比通常情況更復雜,因爲您必須根據兩個參數的類型修改操作。實際上,你需要三重調度。像Clojure這樣的語言直接支持這一點,但在Java(可能是C#)中,您需要使用兩個級別的訪問者來模擬三重調度。這很醜陋,但最大的好處是它可以保持幾何體系的清潔和可維護性,並且它集中了一個編譯單元中的所有交集邏輯。
public interface IGeometry {
void accept(IGeometryVisitor visitor);
}
public interface IGeometryVisitor {
void visitCircle2D(Circle2D circle);
void visitBox2D(Box2D box);
// a method for each concrete type
}
public class Circle2D implements IGeometry {
public void accept(IGeometryVisitor visitor) {
visitor.visitCircle2D(this);
}
}
public class Box2D implements IGeometry {
public void accept(IGeometryVisitor visitor) {
visitor.visitBox2D(this);
}
}
public class IntersectionVisitor implements IGeometryVisitor {
private boolean mResult;
private IGeometry mGeometry2;
public static boolean isOverlapping(IGeometry geometry1, IGeometry geometry2) {
return new IntersectionVisitor(geometry1, geometry2).mResult;
}
private IntersectionVisitor(IGeometry geometry1, IGeometry geometry2) {
mGeometry2 = geometry2;
// now start the process
mGeometry1.accept(this);
}
public void visitCircle2D(Circle2D circle) {
mGeometry2.accept(new Circle2DIntersector(circle));
}
private class Circle2DIntersector implements IGeometryVisitor {
private Circle2D mCircle;
Circle2DIntersector(Circle2D circle) {
mCircle = circle;
}
public void visitCircle2D(Circle2D circle) {
mResult = isOverlapping(mCircle, circle);
}
public void visitBox2D(Box2D box) {
mResult = isOverlapping(mCircle, box);
}
}
private class Box2DIntersector implements IGeometryVisitor {
private Box2D mBox;
Box2DIntersector(Box2D box) {
mBox = box;
}
public void visitCircle2D(Circle2D circle) {
mResult = isOverlapping(circle, mBox);
}
public void visitBox2D(Box2D box) {
mResult = isOverlapping(mBox, box);
}
}
// static methods to compute overlap of concrete types
// For N concrete types there will be N*(N+1)/2 methods
public static boolean isOverlapping(Circle2D circle1, Circle2D circle2) {
return /* intersection of 2 circles */;
}
public static boolean isOverlapping(Circle2D circle, Box2D box) {
return . . .;
}
public static boolean isOverlapping(Box2D box1, Box2D box2) {
return . . .;
}
}
就像比較一下,Java的API是如何選擇解決這個問題的? – Servy
我從來沒有見過這樣的抽象方法。像接口這樣的抽象類的地獄需要實現。 –
@Servy偉大的問題。它看起來像具體類型。 [鏈接](http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/geom/RectangularShape.html)但是,我想添加更多的功能。 – kicks