拥有委托管理器是一个好的设计思路吗?

3
许多Android应用程序都包括自己的BaseActivity类,所有应用程序中的活动都扩展该类。这很有用,因为它提供了一个集中放置大多数/所有活动通用功能的中心位置。拥有BaseActivity的主要缺点是您无法使用任何Activity子类(ListActivity等)。
一种替代方法是使用ActivityDelegate。这提供了一个集中的地方来放置功能,同时仍然允许您使用Activity子类。而且这种方法可以说更易于测试,因为它使用组合而不是继承。
这些解决方案可能都会导致BaseActivity / ActivityDelegate变得过于庞大和复杂,产生许多混乱代码。通过将功能分成许多不同的Delegates,使用委托模式可能是一个解决方案。这将减少Delegate中的混乱代码,但然后活动变得更加复杂 - 现在它们试图将它们的on*方法转发到许多不同的Delegates而不仅仅是一个。
解决所有这些问题的一种可能方法是使用Delegate Manager。Delegate Manager跟踪应用程序中的所有较小的Delegates。活动将它们的on*方法转发给Delegate Manager,后者将它们转发给所有单独的Delegates。这完成了以下所有内容:
- 去重代码 - 所有通用功能都放置在其中一个Delegates中 - 允许使用Activity子类 - 所有活动中的简单代码 - 所有on*方法都转发到一个类 - 易于测试 - 为单元测试轻松模拟Delegates和Delegate Manager周围的所有内容
是否有人尝试过这种模式?如果是,它效果如何?
1个回答

2
据我所理解,您在谈论整个应用程序的单个DelegateManager对象。如果是这种情况,您可以使用registerActivityLifecycleCallbacks,请参见http://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks%28android.app.Application.ActivityLifecycleCallbacks%29 如果您使用的是API级别14以下的版本,则需要查看:https://github.com/BoD/android-activitylifecyclecallbacks-compat
registerActivityLifecycleCallbacks允许您钩入活动的onXXX生命周期方法。
这样做肯定具有您所描述的所有好处:
  • 解耦只有在你需要重复行为时才能使用,对于控制器和视图逻辑紧密结合的 Activity,这种情况相当少见。
  • 如果你有可能重用活动,则删除继承很好 - 但我以前从未遇到过这种情况。但我想一个很好的用例是处理设置或类似需要应用程序范围内外观和行为的自制活动。

我可以想到以下缺点:

  • 在各个地方使用监听器可能会模糊应用程序活动/调用层次结构的路径,并使代码难以理解。这对所有监听器/分发器类型的编程都是成立的。它是一个强大的工具,但要小心使用。
  • 如果你只是把生命周期侦听器/委托传递下去,它可能会引入大量(如你所提到的)样板/混乱代码。
  • 你有责任使用 Application.unregisterActivityLifecycleCallbacks 从应用程序中注销自己。我认为没有好的解决方法,

个人而言,我没有经常使用这种设计模式来处理生命周期,但对于某些用例可能是值得的。例如:

  • ApplicationLifecycleLogger:每次创建/恢复/暂停...一个活动时,你可以使用logcat或其他工具记录下来,以便更轻松地调试生命周期。
  • 例如,如果由于某种模型状态(例如响铃警报-->无法进入AlarmEditActivity)而有人进入了他/她不允许进入的活动,则可以在那里完成(finish())。
  • 在没有Parcelable和屏幕旋转变化的情况下,在活动之间传递对象状态。通常,这是在应用程序中使用Map或某个静态字段实现的。你可以通过让委托者持有状态来实现此目的。

此外,请查看:在Android中子类化活动时减少代码重复的设计模式?

希望这对你有所帮助 =)


感谢回复。我需要这种模式的主要原因之一是在网络无法加载时显示“网络错误”屏幕。我在活动和片段中都进行网络工作,所以我需要同样的屏幕来显示两者。通过使用代理,我已经能够将所有显示网络错误的代码放在一个地方;如果我使用继承,我需要一个BaseActivity,然后还需要一个BaseFragment,它们都包含非常相似的代码。你遇到过这种用例吗?如果是这样,你能否使用继承处理它,而不必重复代码? - Mark
非常抱歉回复晚了。 "网络错误" 似乎是一个合理的用例 - 它有点类似于 "ApplicationLifecycleLogger",因为它在大多数基于网络的应用程序中的大部分活动中都有使用动机。就我个人而言,我还没有编写过这样的应用程序,所以我还没有遇到过它。 - Centril

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