这是我用于模拟模型的类“层次结构”的一部分(我的代码是用 Python 编写的,但我认为我的问题与语言无关):
class World:
# highest-level class, which "knows" everything about the model
# most likely will have just one instance
# contains (e.g., in a dictionary) references to all the instances of class Agent
class Agent:
# each instance represents an agent
# an agent can, among other things, move around according to certain rules
# movement depends on the internal state of the agent,
# but also on the terrain and other information not stored in the Agent instance
问题:move
实例方法应该放在哪里?
我想我应该将 class Agent
的依赖限制在层次结构中比它本身低的类(即,其实例包含在 Agent
实例中的类) .但这意味着 move
方法不能在 class Agent
中,因为它创建了对描述地形等的类(至少是接口(interface))的依赖 - 所以我不妨添加Agent
引用(因此依赖于)World
。从软件设计的角度来看,这可以吗?
另一种方法是将方法 move
放在 class World
中,这样它就不会产生任何额外的依赖关系。然而,class World
将完成几乎所有的工作,在我看来,这将违背 OOP 的主要思想(我的理解是不要将所有功能堆放在一个地方,而是将其包含在相关类中)。
性能方面的考虑只是次要问题(而且我不认为两种方法之间的性能会有差异)。
编辑:我误用了上面的“类层次结构”这个词。我指的不是继承层次结构,而是一堆实例相互包含的类。
最佳答案
您需要考虑的是 Single Responsibility Principle .基本上,每个类都应该负责一件“事情”,并且应该完全封装那一项责任。而且你应该只继承责任延伸的地方。你应该总是能够说扩展类是父类的 100% 甚至更多(在特定意义上更多)。您永远不应该遇到 child 是 parent 的子集并且“更少”的情况。因此,扩展世界的人不是一个好的设计,因为世界的某些方面与人无关。
因此,如果我们看一个示例,您会把实例方法放在由该特定类的角色决定的级别上。那么,让我们更明确地看一个例子:
class Person:
name: ""
birthDate: ""
class PoliceOfficer extends Person:
badgeNumber: ""
显然这是伪代码,但它演示了正在发生的事情。
现在,您要在哪里添加 move()
方法?我们可以将它添加到 PoliceOfficer
中,但是这样我们就会破坏 Person
的封装,因为人也可以移动。
class Person:
def move(world):
但是,我们要在哪里添加 issueTicket()
方法呢?广义的 Person
不能开票,所以如果我们把它添加到 Person
类中,我们就违反了它的职责。因此,我们将它添加到 PoliceOfficer
,因为这是有意义的地方。
就创建依赖性而言,您应该 always favor composition over inheritance .所以从这个意义上说,可以有任意多的依赖关系,因为它们都是软依赖关系(好吧,有点)。由于 move()
采用 world
的实例(或具有世界接口(interface)的对象),因此依赖项被推出类并进入调用代码。这样一来,您的类(class)代码就可以保持相当开放和无依赖性,同时仍能保持高效。
硬编码依赖项通常被视为不好的做法。但是注入(inject)它们(通过依赖注入(inject)或组合)通常被视为一件好事。
总结:将实例方法放在逻辑上有意义的地方。
关于python - 实例方法应该写在类层次结构中的什么位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4860686/