gpt4 book ai didi

c# - 设计抽象基类。使用什么类型,抽象的还是具体的?

转载 作者:搜寻专家 更新时间:2023-11-01 01:06:36 25 4
gpt4 key购买 nike

我只是在我叔叔的推荐下从 Java 跳到 C#。 Java 几何库似乎比 C# 的绘图库更完整,因此我正在做一些简单的移植工作,添加一些功能以开始进入 C#。

但是,我遇到了设计问题,无法辨别哪个是更好的选择。在抽象基类中有多个采用具体数据类型的方法,还是有较少的方法采用抽象基类作为其参数?

public abstract bool isOverlapping(GeometricObject2D o) {}

public abstract bool isOverlapping(Rectangle2D rect) {}
public abstract bool isOverlapping(Circle2D circ) {}
etc...

我脑子里的论点告诉我具体的论点可以防止逻辑错误,但是,我被教导要在适合的情况下始终使用抽象数据类型。

最佳答案

如果想把操作放在基类中,就用抽象类型。您不希望每次决定添加新子类时都必须修改基类。

另一种方法是使用类似 visitor pattern 的东西并让每个具体类依次发送给访问者。然后,交集访问者将包含有关如何计算每对对象类型的交集的所有知识。

以下是访问者模式如何用于此目的。 (我将使用 Java 语法,因为我不是 C# 程序员)。首先,在这里使用访问者模式比通常的情况更复杂,因为您必须根据两个 参数的类型修改操作。实际上,您需要三重调度。 Clojure 等语言直接支持这一点,但在 Java(可能还有 C#)中,您需要使用两级访问者来模拟三重分派(dispatch)。它很丑陋,但最大的好处是它使您的几何层次结构保持清洁和可维护,并将所有交集逻辑集中在一个编译单元中。

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 . . .;
}
}

关于c# - 设计抽象基类。使用什么类型,抽象的还是具体的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13292037/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com