gpt4 book ai didi

java - 在没有访问者模式的情况下避免类型自省(introspection)

转载 作者:行者123 更新时间:2023-11-30 09:03:53 29 4
gpt4 key购买 nike

我正在为以下相当微不足道的问题寻找 OOP 设计建议。我想避免在不采用访问者模式的情况下使用类型自省(introspection)(例如 Java instanceof 运算符),这是典型的建议。我目前正在用 Java 编写这个,但我认为这个问题比 Java 更普遍。

问题背景:我正在为物理模拟编写一个简单的碰撞求解器。我目前有两种类型的边界体积,轴对齐边界框 (AABB) 和边界球。模拟包含一组对象,这些对象可以使用任一类型的包围体进行碰撞检测。作为碰撞求解器的一部分,我有一个“重叠测试器”对象,如果两个给定的边界体积相交,它会简单地返回 true。这是一个草图:

interface BoundingVolume {
...
}

class AABB implements BoundingVolume {
...
}

class BoundingSphere implements BoundingVolume {
...
}

class OverlapTester {
static boolean overlaps(BoundingVolume a, BoundingVolume b) {
if (a instanceof AABB && b instanceof AABB) {
...
} else if (a instanceof AABB && b instanceof BoundingSphere) {
...
} ...
}
}

class Simulation {
List<BoundingVolume> simObjectBVs;
void collide() {
for (BoundingVolume a : simObjectBVs) {
for (BoundingVolume b : simObjectBVs) {
if (a != b && OverlapTester.overlaps(a, b)) {
...
}
}
}
}
}

事实上,overlaps 方法有一个 4 路 if-else 语句来将参数向下转换为 AABBBoundingSphere并调用适当的重叠方法。这是我想避免的。

典型的建议是为每个 AABBBoundingSphere 类型添加一个 overlaps 方法,它知道如何测试自己的重叠与其他类型的边界体积(我认为这符合访问者模式)。但是,我认为这不是最合适的:在稍后添加新类型的包围体时,我必须更新每个其他类型的包围体以添加新类型的重叠方法。但是,如果 OverlapTester 包含所有这些逻辑,我只需在一个地方添加一个新方法。

是否有其他模式可以满足我的需求,还是访客模式真的最适合?

最佳答案

我的英文不是很好,希望对你有帮助

据我了解,您有两种对象,每种对象都有自己的坐标系,您需要知道在给定空间中它们的体积是否发生碰撞。

如果这是正确的,我假设您在该空间中使用某种类型的坐标系(笛卡尔坐标系、球坐标系...)工作,那么,我将执行以下操作:

每个 BoundingVolume 都应该知道如何将它们自己的坐标系“转换”到通用模拟坐标系,并且每个 BoundingVolume 的父亲都应该知道如何比较这些体积,现在每个体积都在同一个坐标系中。

示例:

public abstract class BoundingVolume {

public abstract CartesianVolume getCartesianVolume();

public final boolean overlaps(BoundingVolume bV) {
boolean ret = false;
CartesianVolume thisCartesianVolume = this.getCartesianVolume();
CartesianVolume otherCartesianVolume = bV.getCartesianVolume();
// Decide whether they overlap or not, and return proper boolean value
return ret;
}
}

public class AABB extends BoundingVolume {

public CartesianVolume getCartesianVolume() {
// Code returning the object CartesianVolume with proper Volume
}
}

public class BoundingSphere extends BoundingVolume {

public CartesianVolume getCartesianVolume() {
// Code returning the object CartesianVolume with proper Volume
}
}

这样,如果您还没有类似的东西来管理模拟空间,您确实应该实现一个新类 Cartesian Volume。然而,如果您添加一个新的 BoundingVolume 类型,您将只需要实现它的 getCartesianVolume(),即使有了新类型,父亲也会知道该做什么。

关于java - 在没有访问者模式的情况下避免类型自省(introspection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25487521/

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