Answers:
正如其他人提到的那样,这不一定是一个不好的做法,但是您应该注意,不要打破各层关注点的分离,并在各层之间传递特定于层的实例。例如:
但是,如果您要传递的实例是DTO或实体本身,则可能没问题。
传递对象实例是正常的事情。它减少了保持状态(即实例变量)的需要,并使代码与其执行上下文脱钩。
您可能面临的一个问题是重构,这是当您必须更改调用链中多个方法的签名以响应该链底部附近某个方法的参数要求变化时。但是,可以使用有助于重构的现代软件开发工具来缓解这种情况。
可能很小,但是有可能在层之一中的某个位置分配此引用,此后可能导致悬挂的引用或内存泄漏。
如果只是因为在代码的远程区域中需要对象而传递对象,则使用控制反转和依赖注入设计模式以及可选的适当IoC容器可以很好地解决有关携带对象实例的问题。我已经在一个中等规模的项目上使用它,并且永远不会再考虑不使用它而编写大量服务器代码。
快速解答:有什么不对的传递对象的实例。还要提到的是,要跳过在所有层中分配此参考的操作,这可能会导致悬挂的参考或内存泄漏。
在我们的项目中,我们确实使用这种做法在层之间传递DTO(数据传输对象),这是非常有用的做法。我们还重复使用dto对象来构造一次更复杂的对象,例如摘要信息。
我主要是一名Web UI开发人员,但对我来说,您的直觉不适可能与实例传递无关,而更多地是您对该控制器使用了一些程序这一事实。您的控制器是否应该掌握所有这些详细信息?为什么要播放音频甚至引用多个对象的名字呢?
在OOP设计中,我倾向于考虑常绿的东西和更可能发生变化的东西。变更内容的主题是您倾向于倾向于将其放置在较大的对象框中,以便即使玩家进行更改或添加新选项时也可以保持一致的界面。或者,您发现自己想大量交换音频对象或组件。
在这种情况下,您的控制器需要确定需要播放音频文件,然后以一致/常绿的方式播放音频文件。另一方面,随着技术和平台的改变或添加新的选择,音频播放器的内容很容易更改。所有这些细节都应位于更大的复合对象IMO的接口下,并且当音频播放方式的细节发生变化时,您不必重写控制器。然后,当您将具有文件位置等详细信息的对象实例传递到较大的对象中时,所有交换工作都是在适当的上下文内部完成的,而上下文中某人不太可能对它进行愚蠢的操作。
因此,在这种情况下,我不认为对象实例被弄乱可能会困扰您。是Picard队长跑到引擎室打开经纱芯,再跑回到桥上以绘制坐标,然后在打开盾牌后点击“ punch-it”按钮,而不是简单地说“ Take我们在第9扭曲处到达X行星。做到这一点。” 让他的工作人员整理细节。因为当他以这种方式处理时,他可以在舰队中担任任何一艘船的船长,而无需知道每艘船的布局以及一切运作方式。这最终是IMO赢得的最大的OOP设计大奖。
正如其他答案所指出的那样,这并不是天生的糟糕设计。它可以在嵌套类和嵌套类之间建立紧密的耦合,但是如果嵌套引用为设计提供了一个值,则松开耦合可能不是有效的选择。
一种可能的解决方案是“拉平”控制器类中的嵌套引用。
您可以在控制器类中维护对所有嵌套对象的引用,而不是通过嵌套对象多次传递参数。
具体实现的方式(甚至是有效的解决方案)取决于系统的当前设计,例如:
这是我在GXT客户端的MVC设计模式中遇到的一个问题。我们的GUI组件包含多层嵌套的GUI组件。更新模型数据后,我们最终将其传递到多个层,直到到达适当的组件为止。它在GUI组件之间造成了不必要的耦合,因为如果我们希望新的GUI组件类接受模型数据,则必须创建方法来更新包含新类的所有GUI组件中的模型数据。
为了解决这个问题,我们在View类中维护了对所有嵌套GUI组件的引用映射,以便每当更新模型数据时,View都可以将更新后的模型数据直接发送到需要它的GUI组件,这是故事的结尾。 。这很好,因为每个GUI组件只有一个实例。如果某些GUI组件有多个实例,我会发现它不能很好地工作,这使得很难确定需要更新哪个副本。