在某些情况下,对象应该知道它们的用户吗?
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
。
另一种寻找主人的方法是简单地翻遍所有的主人,找到对应的狗。虽然这不会创建 Dog
和 DogOwner
的依赖关系,但这似乎比需要的要昂贵得多,因为我们必须循环遍历所有所有者。
所以,Dog
有一个getOwner()
方法可以吗?如果不是,如果只知道 Dog
,还有哪些其他方法可以有效访问所有者?
虽然我不是软件设计实用主义者,但我不认为这必然会违反太多设计原则。对于 Dog
到 "know" 关于 DogOwner
的任何事情,它仍然需要访问 DogOwner
的方法。所以,你不会说 Dog.getDogOwnersName
或类似的东西,你会说 Dog.getOwner().getName()
。这样一来,Dog
只关心它的主人是谁。但除此之外的任何信息实际上仍然是隐藏的。
"Should rely little" - 需要多少就多少,不多也不少。
狗当然可以对它的主人有一个link。您询问了替代方案:第一,始终将狗和主人的信息放在一起,即使很多代码不关心主人。第二,如果你养了一只狗,但不认识主人,你显然不能问主人。您可以使用散列 table 将狗映射到主人,但您也可以将狗与主人一起存储。或者你有一个所有狗主人的数据库,并扫描它来寻找那只狗的主人——不完全可扩展。
我会说这样做没问题。不过,想到的一种替代方法是使用以 Dog 为键、以 DogOwner 为值的字典(因为假设 DogOwner 可能会随时间变化)。这还有一个额外的好处,即保留一个 Dog/DogOwner 关系的中央存储库。
我正在为一款潜在的游戏奠定基础,但我在设计 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
。
另一种寻找主人的方法是简单地翻遍所有的主人,找到对应的狗。虽然这不会创建 Dog
和 DogOwner
的依赖关系,但这似乎比需要的要昂贵得多,因为我们必须循环遍历所有所有者。
所以,Dog
有一个getOwner()
方法可以吗?如果不是,如果只知道 Dog
,还有哪些其他方法可以有效访问所有者?
虽然我不是软件设计实用主义者,但我不认为这必然会违反太多设计原则。对于 Dog
到 "know" 关于 DogOwner
的任何事情,它仍然需要访问 DogOwner
的方法。所以,你不会说 Dog.getDogOwnersName
或类似的东西,你会说 Dog.getOwner().getName()
。这样一来,Dog
只关心它的主人是谁。但除此之外的任何信息实际上仍然是隐藏的。
"Should rely little" - 需要多少就多少,不多也不少。
狗当然可以对它的主人有一个link。您询问了替代方案:第一,始终将狗和主人的信息放在一起,即使很多代码不关心主人。第二,如果你养了一只狗,但不认识主人,你显然不能问主人。您可以使用散列 table 将狗映射到主人,但您也可以将狗与主人一起存储。或者你有一个所有狗主人的数据库,并扫描它来寻找那只狗的主人——不完全可扩展。
我会说这样做没问题。不过,想到的一种替代方法是使用以 Dog 为键、以 DogOwner 为值的字典(因为假设 DogOwner 可能会随时间变化)。这还有一个额外的好处,即保留一个 Dog/DogOwner 关系的中央存储库。