java - 在构造函数中设置父子关系而不泄漏“this”变量
问题描述
我正在编写一些物理代码,将对象组织成层次关系,Body 类的每个对象都有一个父级(一个子类处理根条件)和零到多个子级。然而,为了实例化一个新的 Body,我必须将它添加到它的父级,因此构造函数将“this”泄漏给它的父级的 addChild 方法。
目前 Body 的 addChild 方法是私有的;在 Body 的构造函数之外访问它的唯一方法是通过 Body.setParent。但是,我担心在某些极端情况下,这仍然可能会暴露一个未完全实例化的对象。下面的代码被简化为仅相关的元素:
import java.util.Set;
import java.util.TreeSet;
public class Body {
private Body parent;
private Set<Body> children;
public Body(Body parent) {
// instantiates everything else first
this.children = new TreeSet<Body>;
this.parent = parent;
parent.addChild(this);
}
public void setParent(Body parent) {
this.parent.removeChild(this);
this.parent = parent;
parent.addChild(this);
}
private void addChild(Body child) {
children.add(child);
}
private void removeChild(Body child) {
children.remove(child);
}
}
正如预期的那样,这段代码是“在构造函数中泄漏这个”,但似乎没有任何方法可以设置树结构。是否有另一种设计模式可用于避免 Body 在其构造函数完成运行之前可见的可能性?
解决方案
保持构造函数简单是个好主意。在您的情况下,与另一个对象交互会很复杂。一个原因是错误处理在构造函数中可能很困难。
不要使用带有参数的构造函数,而是删除参数并像这样调用它。
var newBody = new Body();
newBody.setParent(parent);
构造函数看起来像这样。
public Body() {
this.children = new TreeSet<Body>;
}
并更改 setParent 方法以检查是否没有当前父级。
public synchronized void setParent(Body newParent) {
if (parent != null)
parent.removeChild(this);
parent = newParent;
if (newParent != null)
newParent.addChild(this);
}
请注意,我还将 setParent 参数的名称更改为不与类变量冲突。当您忘记使用“this”来区分您指的是哪个“父级”时,就会出现难以发现的错误。
无论如何,我删除的构造函数代码实际上只是 setParent 方法的重复。
我在方法中添加了同步,这样您就可以确保对该方法的多次调用是同步完成的,否则层次结构可能会损坏。
当然,有很多方法可以做到这一点。但这是我会使用的一种简单方法。
推荐阅读
- python - 如何将缓冲区地址传递给c?
- javascript - 如何在反应中使用获取的 const 值?
- tensorflow - 带有 Resnet-50 (v1) 对象检测 API 的 Tensorflow Faster R-CNN 结果每张图像只有一个边界框
- python - Python自动更改所有字典值
- python - 如何从 Twitch IRC 响应中找到特定值
- apache-spark - 尝试使用 datastax cassandra 连接器启动 spark thrift 服务器
- python - 如何使用多个标签操作 tkinter 画布对象
- python - 网页抓取访问被拒绝 | Cloudflare 限制访问
- php - 如何使用 href 更改 MySQL 上的状态值?
- typescript - NestJS 分离队列