Java 中的双向关系

Bi Directional Relations in Java

这是我的问题。我有一个任务和一个任务列表。

public class Task {
  private Tasklist task list;

  public void setTasklist(Tasklist tasklist) {
   // the code
  }
}

public class Tasklist {
  private List<Task> tasks;

  public void addTask(Task task) {}
  public void removeTask(Task task) {} 
}

我想要的是:我想在用户更改任务的任务列表变量后更新任务列表

所以如果我执行

Tasklist myTasklist = new Tasklist();
Task myTask = new Task();
myTask.setTasklist(myTasklist);

我想看这个

myTasklist.getTasks(); // => [myTask]

反之亦然,如果我将任务添加到我的任务列表,我希望它自动更新任务任务列表参考

Tasklist myTasklist = new Tasklist();
Task myTask = new Task();

myTasklist.addTask(myTask);

myTask.getTasklist(); // => myTasklist

我尝试自己解决问题,但总是以堆栈溢出告终。

一个任务属于一个列表,一个列表知道它的任务。简单的事情 - 只缺少一件事:决定谁在向什么添加什么?

我的意思是,通常您将 Task 添加到 TaskList,那么以相反的方式对其建模有什么意义呢?为了简单起见,我敢于删除 setTaskList 方法。

现在可以清楚地看到,您通过调用 add() 向任务列表中添加了一个新任务。只有一种方法可以将任务添加到任务列表——调用 add()。将任务添加到任务列表后,此添加方法会更新任务的 taskList 属性。

public class Task {
  private TaskList taskList;
}

public class Tasklist {
  private List<Task> tasks;

  public void addTask(Task task) {
      tasks.add(task);
      task.taskList=this; // belongs to this list now
  }
  public void removeTask(Task task) {
      tasks.remove(task);
      task.taskList=null; // belongs to no tasklist
  }
}

...你最终进入了 Whosebug。

循环依赖很少是个好主意。要问自己的问题是:如果没有任务列表,任务能否存在?任务列表可以在不知道其任务的情况下存在吗?

最大的问题是您必须处理任务列表跟踪被引用到另一个任务列表的任务的可能性。

但是,对于这个问题,如果您标记到 TaskList 的调用将调用 Task 上的某些内容,这将回调 TaskList 的相同方法,您将遇到堆栈溢出。