在某些情况下,对象应该知道它们的用户吗?

Should objects know about their users in certain cases?

我正在为一款潜在的游戏奠定基础,但我在设计 class 既要封装又要高效的元素时遇到了问题。

通常,人们说对象应该很少相互依赖以保持模块化和封装。

然而,有时让一些对象相互了解似乎很方便。

假设我们有一个 class 叫狗。

public class Dog {

  public void eat() { ... }
  public void wagTail() { ... }

}

狗有主人,所以有狗主人class。

public class DogOwner {
  private Dog dog;

  public Dog getDog() { return dog; }
  public void petDog() { ... }
  public void takeDogForWalk() { ... }
}

现在,如果我们有一个 Dog,但没有它的主人怎么办?为Dog做一个getOwner()方法似乎是有意义的。

public class Dog {
  private DogOwner owner;

  public void eat() { ... }
  public void wagTail() { ... }
  public DogOwner getOwner() { return owner; }

}

然而,这现在给出了 Dog 关于 DogOwner 的信息,这似乎违反了信息隐藏。它似乎也造成了冗余,因为 Dog 有一个 DogOwner,而 DogOwner 有一个 Dog

另一种寻找主人的方法是简单地翻遍所有的主人,找到对应的狗。虽然这不会创建 DogDogOwner 的依赖关系,但这似乎比需要的要昂贵得多,因为我们必须循环遍历所有所有者。

所以,Dog有一个getOwner()方法可以吗?如果不是,如果只知道 Dog,还有哪些其他方法可以有效访问所有者?

虽然我不是软件设计实用主义者,但我不认为这必然会违反太多设计原则。对于 Dog 到 "know" 关于 DogOwner 的任何事情,它仍然需要访问 DogOwner 的方法。所以,你不会说 Dog.getDogOwnersName 或类似的东西,你会说 Dog.getOwner().getName()。这样一来,Dog 只关心它的主人是谁。但除此之外的任何信息实际上仍然是隐藏的。

"Should rely little" - 需要多少就多少,不多也不少。

狗当然可以对它的主人有一个link。您询问了替代方案:第一,始终将狗和主人的信息放在一起,即使很多代码不关心主人。第二,如果你养了一只狗,但不认识主人,你显然不能问主人。您可以使用散列 table 将狗映射到主人,但您也可以将狗与主人一起存储。或者你有一个所有狗主人的数据库,并扫描它来寻找那只狗的主人——不完全可扩展。

我会说这样做没问题。不过,想到的一种替代方法是使用以 Dog 为键、以 DogOwner 为值的字典(因为假设 DogOwner 可能会随时间变化)。这还有一个额外的好处,即保留一个 Dog/DogOwner 关系的中央存储库。