javagwtsingletongwt-placesgwt-activities

Should GWT Activities/Places be Singletons or Prototypes?


What's the difference (performance and otherwise) between this:

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;
    }
}

And:

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;
    }
}

In other words, what's the difference whether I keep reusing the same "singleton" Place over and over again, or if I just instantiate a new one every time it is requested.

Also, same question for Activitys from inside the ActivityMapper. Thanks again!


Solution

  • Rule of thumb: places should be immutable. With that in mind, using a singleton place can only be done if the place has no data attached to it (as in your HomePlace example). Because places are so lightweight, the implications of using a singleton vs. creating a new instance is negligible.

    It's a totally different story for activities, because they aren't value objects.

    What would it imply to use a singleton activity?

    If you use MVP (splitting the view out of the activity), activities are generally lightweight, so using short-lived ones frees you from the above make sure you clear everything in onStop and onCancel and tell the activity the place has changed and overall makes things simpler: the activity is created, then started, then cancelled or stopped and it's gone, ready to be garbage-collected. If you need to keep a cache of some data or computation results, then use an explicit cache object that all your activity instances will share; it makes things clearer.


    A side note about MVP and views lifecycle: views (widgets) are generally heavyweight, so for often-used ones you might want to make them singletons. In this case, your activity will have to clear the state of the view (field values, etc.) in its start method (or possibly onStop and onCancel), somehow defeating the use of short-lived activities. The caching of the view (you might consider not using a singleton but rather keeping the instance in memory for some time and evicting it after some delay) should be viewed as an optimization here, where constructing a new view costs much than clearing it on activity start. It's a tradeoff.

    The way I approach MVP is that the view has no state on its own, that is the presenter really controls what the view should display/know/etc. so clearing the view on start is part of the flow: the presenter (the activity in many cases) knows what state it's in, and it reflects that state in the view; and start is the time when it's given the control of the view. That approach was described by Google, in the making of Wave, during Google I/O 2010 in the GWT testing best practices session.