gpt4 book ai didi

java - 模拟中 "dynamic"对象的结构

转载 作者:太空宇宙 更新时间:2023-11-04 11:20:26 24 4
gpt4 key购买 nike

我想创建一个或多或少简单的重力模拟,我目前正在对结构做出一些决定。我遇到了一个问题,我不知道如何“很好地”解决。这是问题的简单类图:

The Problem

乍一看,您可能看不出任何问题,但让我告诉您一个额外的事实:如果一颗恒星达到一定的密度(史瓦西半径 > 半径),它应该形成黑洞。那么我如何告诉模拟将 Star 实例与 BlackHole 实例交换呢?我可以向每个主体添加一个模拟实例,然后它们自己可以修改主体数组,但必须有更好的方法!

另一种方法可能是让 Planet、Star 和 BlackHole 成为新类 BodyType 的子类,然后 Body 将保存该类的实例。

你觉得怎么样?您将如何以干净利落的方式解决这个问题?如有任何帮助,我们将不胜感激!

编辑:为了进一步说明,here is an illustration我提到的两种方法。这两者哪一个更好?或者还有我没有提到的更好的吗?

最佳答案

也许这可能有帮助;在运行时改变行为的一种常见方法是策略模式;这个想法是在 Body 类中保留所有 body 类型的共同点,并将不同的行为分成不同的策略,这样每当 body 改变类型时就可以交换策略。他们可以实现一个接口(interface),比如 BodyBehavior,而不是让 BlackHole、Planet 和 Star 扩展 Body;

public interface BodyBehaviour {
String getType ();
Double getLuminosity (Body body);
// anything else you need that's type specific....
}

public class PlanetBodyBehavior implements BodyBehaviour {
public static final String TYPE = "Planet"
@Override
public String getType() {
return TYPE;
}

@Override
public Double getLuminosity(Body body) {
// planet specific luminosity calculation - probably 0
return calculatedLuminosity;
}
}

你的 body 类别看起来像这样;

public class Body {
private Double mass;

// coordinates,radius and other state variables

private BodyBehavior bodyBehaviour;

public void setBodyBehaviour (BodyBehaviour behaviour) {
this.bodyBehaviour = behaviour;
}

public String getBodyType () {
bodyBehaviour.getType();
}

public Double getLuminosity () {
bodyBehavior.getLuminosity(this);
}
}

对于你的模拟,你可以有类似的东西;

// init - note we keep our behaviors stateless so we only need one instance of each
public class Simulation () {
BodyBehaviour planetBehavior = new PlanetBodyBehavior();
BodyBehaviour starBehavior = new StarBodyBehavior()
BodyBehaviour blackHoleBehavior = new BlackHoleBodyBehavior()
// Just showing initialisation for a single star...
Body body = new Body(initilising params....)
body.setBehaviour (starBehavior);

// iterations....
while (!finished) {
// assume we have many bodies and loop over them
for (Body body : allBodies) {
// update body positions etc.
// check it's still a star - don't want to be changing it every iteration...
if (body.hasBecomeBlackHole() {
// and this is the point of it all....
body.setBodyBehaviour(blackHoleBehavior);
}
}
}
}

祝你模拟愉快!

请注意,在这种情况下,顶层模拟循环会调用行为更改,但您可以将其添加到您的 BodyBehavior 中;

boolean hasBecomeBlackHole (Body body);

在 body 里你可以做类似的事情

public boolean hasBecomeBlackHole () {
bodyBehaviour.hasBecomeBlackHole(this);
}

对于 StarBodyBehavior;

public boolean hasBecomeBlackHole (final Body body) {
return doSomeCalculations(body.getMass(), body.getRadius());
}

对于行星和黑洞

public boolean hasBecomeBlackHole (final Body body) {
return false;
}

关于java - 模拟中 "dynamic"对象的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44980100/

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