1

假设我有一个包含 Dog 对象集合的 Person 类。这种关系是双向的。

public class Person {
  private List<Dog> dogs;
  // getter and setter for dogs
}

public class Dog {
  private Person person;
  // getter and setter for person
}

好的,如果我只是在处理这些对象,我将在 Person 中有添加狗和删除狗的方法,这样客户端就不会直接使用集合。

public void removeDog(Dog dog) {
  dogs.remove(dog);
  dog.setPerson(null);
}

public void addDog(Dog dog) {
  dog.setPerson(this);
  dogs.add(dog);
}

或类似的规定。

我的问题是在服务层中使用这些对象时出现的。我可以通过 addDog 向一个人添加一条新狗,然后简单地保存将自动保留新狗的人。但是,通过 removeDog 删除狗然后保存人不会自动从持久存储中删除狗......它只会将狗引用设置为 null。

所以我最终得到了类似的东西:

Dog dog = dogDAO.getDogById(int id);
dogDAO.remove(dog);

因为这是一个 web 应用程序,并且 Persons 和 Dogs 不在内存中维护,所以它工作正常,我从未调用过 Person.removeDog()。下次我加载最初引用这条狗的人时,它不会包含这条狗,因为它已从存储中移除。同样的事情也适用于添加狗:

Person person = personDAO.getPersonById(int id);
Dog dog = new Dog();
dog.setPerson(person);
dogDAO.save(dog);

同样,这甚至可以正常工作,而且我从未调用过 Person.addDog()。

那么在我的 Person 类中使用 addDog 和 removeDog 方法有什么意义吗?

4

2 回答 2

1

如果没有人工干预,这总是很难做到的。一旦您删除对象引用并拥有一个陈旧的对象。在另一个用例中,您只需删除一些其他对象指向的对象(列表)。这也应该是个问题。如果这被懒惰地接受,它将涵盖很多错误。

为简单起见,您可以将 dao remove 操作添加到 person removeDog() 中,但是这样的用例将狗从一个人身上移除并将其添加到另一个人身上是不可能的。如果您知道必须将其从持久性中移除,那么您将狗从人身上移除,然后将其从持久性中移除,有什么问题?你少走一步。所以归还被移除的狗会给你带来一个模式

dogDAO.remove(person.removeDog(dog))

亲自进行添加和删除使您不仅可以模仿列表行为,还可以拥有一些额外的功能。在你的情况下很难决定,因为它是一个简单的设置,它取决于 dao 东西的可访问性以及你喜欢把它放在哪里。

您至少应该对要支持的每个用例都有印象。然后需要定义强制和可选的对象链接和设置。有了一些实用主义(例如将持久性东西与对象耦合),我们必须有机会做一些更容易(因此更不容易出错)使用的面向对象的设置

于 2009-05-06T19:50:48.413 回答
1

如果从逻辑上讲,从人中添加和删除狗是如何完成的,那么就没有理由从狗中添加和删除人的方法。您的目标是您的数据模型始终处于一致状态。如果您允许从狗身上移除人,那么您必须让狗从人身上移除自己,以保持您的数据模型一致。然后你必须避免递归。

听起来你拥有它的方式很好、清晰、明确。如果您愿意,您可以随时向 Dog 类添加注释,以添加没有 addPerson 和 removePerson 方法是有目的的,并且应该通过从人中删除狗或将狗添加到人来完成。

代码中不需要完美的对称性或完美的正交性。目标不是为了那个,而是为了让你的数据模型以一种干净、易于理解的方式保持一致。

于 2009-05-06T21:07:26.717 回答