1

这之间有什么区别(性能和其他):

public class MyPlaceMapper implements PlaceHistoryMapper {
    @Override
    public String getToken(Place place) {
        if(place instanceof HomePlace)
            return "home";
        else
            return null;
    }

    @Override
    public Place getPlace(String token) {
        if(token.equals("home"))
            return new HomePlace();
        else
            return null;
    }
}

和:

public class MyPlaceMapper implements PlaceHistoryMapper {
    // Singleton HomePlace to inject and reuse over and over again
    private HomePlace homePlace;

    // Getter/setter for homePlace...

    @Override
    public String getToken(Place place) {
        if(place instanceof HomePlace)
            return "home";
        else
            return null;
    }

    @Override
    public Place getPlace(String token) {
        if(token.equals("home"))
            return homePlace;
        else
            return null;
    }
}

换句话说,我是否Place一遍又一遍地重复使用相同的“单例”,或者我每次请求时都实例化一个新的,有什么区别。

此外,对于Activitys 内部的相同问题ActivityMapper。再次感谢!

4

2 回答 2

6

经验法则:位置应该是不可变的。考虑到这一点,只有在该地点没有附加数据HomePlace时才能使用单例地点(如您的示例中所示)。因为地方是如此轻量级,所以使用单例与创建新实例的影响可以忽略不计。

对于活动来说,情况完全不同,因为它们不是价值对象

使用单例活动意味着什么?

  • 您必须清除onStopandonCancel中的状态,否则之前使用活动的状态可能会泄漏到以后的使用中。虽然它在某些情况下很有用,但我认为最好将缓存行为分开(关注点分离)。
  • 根据定义,单例在应用程序的整个生命周期内都保存在内存中,即使是那些用户只会看到/使用一次的。例如,Google Groups 的欢迎屏幕很可能在每次应用程序运行时只能看到一次,那么为什么要把它保存在内存中呢?
  • 如果您在两个都映射到同一个活动的地方之间导航,则活动将不会重新启动(这是 的一个功能ActivityMapper),因此您必须以某种方式向活动发出信号表明该地点已更改(当然,如果需要) . 这可以在ActivityMapper或通过让活动监听PlaceChangeEvents 来完成。

如果您使用 MVP(将视图从活动中分离出来),活动通常是轻量级的,因此使用短期活动可以让您从上述情况onStoponCancel解脱出来:活动被创建,然后开始,然后被取消或停止,然后它就消失了,准备好被垃圾收集。如果您需要保留一些数据或计算结果的缓存,则使用所有活动实例将共享的显式缓存对象;它使事情更清楚。


关于 MVP 和视图生命周期的旁注:视图(小部件)通常是重量级的,因此对于经常使用的视图,您可能希望将它们设为单例。在这种情况下,您的活动必须在其start方法(或可能onStoponCancel)中清除视图的状态(字段值等),从而以某种方式阻止使用短期活动。视图的缓存(您可能会考虑不使用单例,而是将实例保留在内存中一段时间​​并在延迟后将其驱逐)应该被视为此处的优化,其中构建新视图的成本比在活动中清除它要高得多开始。这是一个权衡。

我接近 MVP 的方式是视图本身没有状态,即演示者真正控制视图应该显示/知道/等的内容。所以清除视图start是流程的一部分:演示者(在许多情况下是活动)知道它处于什么状态,并在视图中反映该状态;并且start是赋予视图控制权的时间。在 Google I/O 2010 的GWT 测试最佳实践会议期间,Google 在制作 Wave 时描述了这种方法。

于 2012-11-23T13:54:48.253 回答
1

托马斯的回答很好。只是为了添加更多信息。

您可以决定覆盖 google 提供的对象的默认实现。例如,您可以决定编写自己的活动映射器,该映射器将始终为给定类型的地点返回相同的活动实例。正如托马斯所说,这个地方并不是一个真正重要的对象。重要的是通过活动映射器与该地点相关联的活动。尽管如此,您可能会遇到生命周期问题,并且您启动和停止方法的编码将非常困难。

您可能想要重新编码活动管理器并向模式添加更新方法以刷新现有活动(如果这是您想要做的)

问问自己,在浏览器中按前进或后退时,您的应用程序应该如何表现。你可以在我写的一篇关于活动和地点的文章中找到更多细节。

希望它会有所帮助。

于 2013-03-08T20:35:24.487 回答