Android - 为什么使用接口被认为是在Activity和Fragment之间通信的最佳实践?

10
在这份文档“与其他片段通信”中,谷歌告诉我们,Activity和Fragment之间通信的最佳实践是实现一个接口。然后Fragment可以调用该接口,在Activity中执行必要的行为。
但也有一种黑客方式来做到这一点。直接通过方法"getActivity()"获取Activity,然后我们可以使用它下面的“公共方法”
这让我感到困惑。因为我真的想不出使用黑客方式存在任何重大缺点。
我脑海中第一种方法的优点是:
  1. 我可以将“资源可访问性”限制在我的Activity下面。但由于Fragment能够调用“getActivity()”,所以它实际上可以访问其中的所有“公共”方法。因此,这并不能让我真正信服。
  2. 代码更易读和故事化。使用第一种方法,代码告诉我们,“该Activity只为Fragment打开了这些特定的可访问区域”。我们可以通过查看Activity中的代码直接知道“Fragment中的内容可能会干扰Activity”。否则,我们将需要打开Fragment下面的代码来查看它做了什么。
好吧,当我总结这些时,我有点被自己说服了。但坦白地说,我真的希望有其他坚实而必要的理由来做到这一点。任何想法或文档都将不胜感激!

有很多原因可以解释为什么你应该使用接口而不是直接调用公共方法。只需在谷歌上搜索即可。 - code monkey
@QuentinTsai:你看到我的回答了吗? - Yash Sampat
@ZygoteInit 是的!抱歉回复晚了,我之前生病了。我已经仔细阅读了你的所有答案,它们都非常有帮助。但是很抱歉,我可能会给 Reinier 提供正确的答案,因为对我来说,它确实提醒了我之前没有注意到的事情。感谢大家!! - KunYu Tsai
3个回答

7
首先,主要优点是您的代码具有模块化。当您直接从“子”类调用“父”类时,会创建循环依赖。这实际上意味着您不能替换其中一个而不更改另一个。这种方法经常导致意大利面条式代码,难以维护,甚至更难扩展,几乎不可能在大规模重构的情况下进行替换。
至于您的示例:如果您直接从Fragment调用Activity的公共方法,则无法在其他活动中重复使用Fragment,除非实现hacky解决方案(例如if(getActivity() instanceof A) {...} else {...}),也无法将其替换为例如控制器类或任何其他解决方案。
如果您难以理解此主题,我强烈建议您阅读Effective Java一书。

4

这种方法本身没有什么“优势”,除了

  • 它是一种可识别的习惯用语。在Java中,使用接口是两个类之间通信的常见方式。
  • 相同的代码可以在许多不同的FragmentActivity中重用。
  • 它遵循模块化和抽象的一般原则,其中Fragment“告诉”Activity它已经达到了某个状态,而Activity根据这个状态确定自己的行为。

我认为第二个应该是“相同的片段可以从更多的活动中使用”(这可以在获取getActivity()之后完成,但需要进行后续的instanceof检查和转换...) - DNax
@ZygoteInit 已经完成了!因为您提供了这个答案!我立即给它点了赞!谢谢 : ) !! - KunYu Tsai

1
我认为接口化方法的主要优势在于其良好的模块化和足够高的抽象程度,从软件工程的角度来看。假设你在一个团队中工作,每个团队成员负责其中的一个组件,例如,假设你应该实现那个片段,我应该实现那个活动。因此,我们需要在彼此之间达成一致,使用一个共享接口作为标准,然后我们应该实现符合该标准的组件,即我们约定的接口。此外,在软件工程方面,一个基于组件的软件系统由多个组件组成,它们相互独立地运行,它们之间的交互仅通过标准的共享接口进行,每个组件内部的材料对其他组件来说是透明的。
因此,在您的情况下,Activity 和 Fragment 应被视为两个独立的组件,彼此不知道对方的详细信息。这时就需要用到 Java 接口。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接