实例方法应该写在类层次结构中的哪个位置?

2024-01-05

这是我用于模拟模型的类“层次结构”的一部分(我的代码是用 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因为它创建了对描述地形等的类(至少是其接口)的依赖 - 所以我不妨添加Agent对(并因此依赖于)的引用World。从软件设计的角度来看这可以吗?

另一种方法是放置方法move in class World,它不会导致任何额外的依赖关系。然而,class World然后将完成几乎所有的工作,在我看来,这违背了 OOP 的主要思想(我的理解是不要将所有功能堆积到一个地方,而是将其包含在相关的类中)。

性能考虑只是次要问题(而且我认为两种方法之间的性能不会有差异)。

编辑:我误用了上面的“类层次结构”一词。我指的不是继承层次结构,而是指一组实例相互包含的类。


你需要考虑的是单一责任原则 http://en.wikipedia.org/wiki/Single_responsibility_principle。基本上,每个类应该负责一件“事情”,并且应该完全封装该职责。而且你应该只继承责任延伸的地方。您应该始终能够说扩展类是父类的 100% 甚至更多(特定意义上的更多)。你永远不应该出现孩子是父母的子集并且“较少”的情况。因此,人扩展世界并不是一个好的设计,因为世界的某些方面与人无关。

因此,如果我们看一个示例,您会将实例方法放在由该特定类的角色决定的级别上。那么,让我们看一个更明确的例子:

class Person:
    name: ""
    birthDate: ""

class PoliceOfficer extends Person:
    badgeNumber: ""

显然这是伪代码,但它演示了正在发生的事情。

现在,您将在哪里添加move()方法?我们可以将其添加到PoliceOfficer,但是我们会打破封装Person因为人也是可以移动的。

class Person:
    def move(world):

但是,我们在哪里添加一个issueTicket()方法?广义的Person无法开票,所以如果我们将其添加到Person类,我们就违反了它的责任。因此,我们将其添加到PoliceOfficer,因为这就是有意义的地方。

至于创建依赖关系,您应该总是倾向于组合而不是继承 https://stackoverflow.com/questions/49002/prefer-composition-over-inheritance。因此,从这个意义上说,可以有任意数量的依赖项,因为它们都是软依赖项(嗯,有点)。自从move()举一个例子world(或具有世界接口的对象),依赖关系被推出类并进入调用代码。因此,这可以让您的类的代码保持相当开放和无依赖性,同时仍然保持高效。

通常认为对依赖项进行硬编码是不好的做法。但注入它们(通过依赖注入或组合)通常被视为一件好事。

总之:将实例方法放在逻辑上有意义的地方。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实例方法应该写在类层次结构中的哪个位置? 的相关文章

随机推荐

  • 发送参数到before_save

    我正在尝试以 rails 方式 构建一个应用程序 所以这次我不是回顾性地处理数据库中的记录 而是尝试使用 before save 方法来完成它们 即这个 def make percentage from score percent scor
  • 如何在 Dart 中合并两个列表?

    我想知道是否有一种简单的方法可以在 dart 中连接两个列表来创建一个全新的列表对象 我找不到任何东西和类似的东西 My list list1 1 2 3 list2 4 5 6 I tried var newList list1 list
  • 在python中通过ftp更改权限

    我正在使用 pythonftplib将图像上传到我的 raspberryPi 上位于 var www 的文件夹中 一切工作正常 除了上传的文件有600权限和我需要644对于他们来说 哪种方法最好 我正在寻找类似的东西 def ftp sto
  • PhpStorm - 导航后退键盘快捷键不起作用

    When I Ctrl click on method it will jump to declaration of that method 问题 如何跳回到该方法的使用 I tried Ctrl Alt Left combination
  • 用于随机森林分类的​​ ROC 曲线

    我在用randomForestR平台中用于分类任务的包 rf object lt randomForest data matrix label factor cutoff c k 1 k 其中 k 的范围为 0 1 到 0 9 pred l
  • 如何在 Ruby on Rails 中分析请求?

    如何分析控制器操作 我的一个观点是渲染需要相当长的时间 我想把它分解一下 我懂了script performance profiler 但这似乎只能访问全局范围 红宝石教授 http ruby prof rubyforge org 是要走的
  • 如何轻松获取 Scala 案例类的名称?

    Given case class FirstCC def name String something that will give FirstCC case class SecondCC extends FirstCC val one Fi
  • pyspark approxQuantile 函数

    我有包含这些列的数据框id price timestamp 我想找到按以下分组的中值id 我正在使用此代码来查找它 但它给了我这个错误 from pyspark sql import DataFrameStatFunctions as st
  • 如何使用angularjs动态显示表中的对象数组?

    我使用 angular js 作为我的字体端 使用 node js 作为服务器端 使用 PostgreSQL 作为数据库 现在 我在数据库中有一些值列表 数据库 控制器代码 我得到以下输出console console log scope
  • 计算二维数组的页面错误数

    我正在努力学习考试 我找到了这个例子 但不明白他们是如何得到答案的 有人可以解释一下吗 问题 考虑二维数组 A int A 新 int 100 100 其中 A 0 0 位于页大小为 200 的分页内存系统中的位置 200 操作矩阵的小进程
  • 带有自定义分配器但没有其他参数的 std::function 构造函数有什么意义?

    我正在玩标准 函数和自定义分配器 但当我不为函数提供初始函子时 它的行为并不像我预期的那样 当我向构造函数提供自定义分配器但没有初始函子时 分配器永远不会被使用 或者看起来是这样 这是我的代码 Simple functor class th
  • 获取 Firestore 中玩家的排名

    我在 Firestore 中有 10k 个用户 每个用户的 documentId 是他们的 uid 分数注册到他们的文档中 为了找到Leaderboard的Top 20 它成功地根据其分数查询了Top 20用户 就像使用复合索引一样 let
  • 重新创建父 Fragment 后获取对子 Fragment 的引用

    从Android 4 2开始 Android支持嵌套片段 http developer android com about versions android 4 2 html NestedFragments 该文档没有给出很多有关嵌套的解释
  • 从 android O 和​​ P 中最近的应用程序列表中检测应用程序何时被终止

    用例是当应用程序从最近的列表中被杀死时 我必须向服务器发送注销请求 我用任务删除时然而在 Android 中处理这个问题O and P我收到通知栏显示 应用程序正在运行 我想避免这种情况 这是我运行前台服务的方式 if android os
  • Objective-C 中的弱键字典

    我想知道是否有可能有类似于 ActionScript 3 的东西DictionaryObjective C 中具有弱键的对象 我希望能够将类的实例 附加 到其他任意实例 Example MetaData meta MetaData meta
  • Mac OS Pygame 使用已弃用的函数 CGSFlushWindow

    我在 OS Mountain Lion 下以 32 位模式运行 Python 2 7 3 并且刚刚开始使用 Pygame 我不断在终端窗口中收到以下错误消息 2012 12 31 10 58 03 695 Python 12097 f07
  • 当所有异步 Http 请求完成时执行函数

    Let s say we have two HTTP Async Calls Task 1 and Task 2 And I want to execute both of them in the same time and once bo
  • 以编程方式更改应用程序图标

    我见过iTunes 上的此应用程序 https itunes apple com in app id662522133 mt 8 它正在 iphone 中创建自定义图标 在我的应用程序中 我还想更改 icon 具体来说 我想要做的是在我的图
  • 将 Spring Boot 执行器运行状况端点更改为自定义端点

    是否可以将 Spring Boot 执行器运行状况端点更改为自定义端点 像下面这样的东西 http localhost 8080 actuator health http localhost 8080 actuator health to
  • 实例方法应该写在类层次结构中的哪个位置?

    这是我用于模拟模型的类 层次结构 的一部分 我的代码是用 Python 编写的 但我认为我的问题与语言无关 class World highest level class which knows everything about the m