GWT MVP with Places&活动 - 模特在哪里?

时间:2011-04-01 07:57:16

标签: gwt mvp

我正在努力熟悉GWT开发的“地方与活动”设计模式,到目前为止我认为它有很大的潜力。我特别喜欢这样一种方式,一旦你开始考虑你的应用程序的“地方”,浏览器历史几乎没有任何额外的努力落在你的腿上。

然而,有一件事让我感到困扰:到目前为止我看到的所有文章和代码示例都掩盖了一个(就我而言,主要的)方面:'MVP'的'M'部分,即模特!

在普通的MVP架构中,据我所知,Presenter拥有对模型的引用,并负责根据UI事件更新它,或者根据模型的变化更新UI。

现在,在“P& A”的所有文章/样本中,活动似乎取代了Presenter,但与“普通”主持人不同,它们会在新地方到达时被丢弃并重新创建,所以他们不能存储客户端状态,或者每次都会丢失。活动起来很便宜,所以不是很麻烦,但我不想一遍又一遍地创建复杂应用程序的模型。

所有样本都相当简单,并且没有太多的状态,因此只是忽略了Model方面,但是实际的,复杂的应用程序在哪里存储它的状态?

2 个答案:

答案 0 :(得分:10)

我想我找到了自己的答案。主要问题似乎是所有简单的代码示例都使 Activities 成为 Presenters ,如:

public class NavigationActivity extends AbstractActivity implements NavigationView.Presenter {
    private final ClientFactory clientFactory;
    private final NavigationPlace place;

    public NavigationActivity(ClientFactory clientFactory, NavigationPlace place) {
        this.clientFactory = clientFactory;
        this.place = place;
    }

    @Override
    public void start(AcceptsOneWidget panel, EventBus eventBus) {
        NavigationView navView = clientFactory.getNavigationView();
        navView.setSearchTerm(place.getSearchTerm());
        navView.setPresenter(this);
        panel.setWidget(navView);
    }

    @Override
    public void goTo(Place place) {
        clientFactory.getPlaceController().goTo(place);
    }
}

现在,活动相当短暂,而“经典”意义上的典型演示者具有更长的生命周期,以维持模型和UI之间的绑定。所以我所做的是使用标准的MVP设计模式实现一个单独的Presenter,所有Activity都是这样的:

public class NavigationActivity extends AbstractActivity {
    private final ClientFactory clientFactory;
    private final NavigationPlace place;

    public NavigationActivity(ClientFactory clientFactory, NavigationPlace place) {
        this.clientFactory = clientFactory;
        this.place = place;
    }

    @Override
    public void start(AcceptsOneWidget panel, EventBus eventBus) {
        NavigationPresenter presenter = clientFactory.getNavigationPresenter();
        presenter.setSearchTerm(place.getSearchTerm());
        presenter.go(panel);
    }
}

因此,取代“提取视图”的活动,并在其上扮演类似Presenter的角色,它会获取实际的 Presenter,只是通知它客户端状态更改引发的由Place,并告诉它在哪里显示其信息(即视图)。然后,Presenter可以随心所欲地管理视图和模型 - 这种方式比我发现的代码示例更好(至少我对我正在处理的应用程序的想法)远。

答案 1 :(得分:9)

你是对的,几乎总是主持人是唯一持有该模型并管理其生命周期的人。以前的GWT版本中的模型只是一个DTO,(并且仍然是)一个POJO,它是由RPC方法返回时由GWT反序列化器创建的,或由Presenters创建并由UIHandlers填充UI数据,并发送到服务器。

我已经努力将模型生命周期封装在“活动”生命周期内,并避免在活动之外存储状态。 (但我确实有一个单独的全局状态可以在应用程序的任何地方维护使用。)我认为这是GWT MVP工程师所假设的 - 当用户已经离开 Place ,对于与该地点相关的模型也要处理(和收集)。创建模型,在活动中填充它们,并在导航之前进行服务调用以更新服务器(或由页面上的某些控件触发),并让它们与活动一起进行 - 这是我迄今为止所做的事情。

我参与的一个更大的项目面临着相当多的浏览器内存占用问题,而且所有问题都归因于与另一个(当前未查看) Place 相关联的对象在内存中。很难跟踪和删除对这些对象的引用,并且由于用户已离开屏幕 - “为什么我的旧屏幕对象仍然在内存中?”问题经常出现并随后得到固定。这就是为什么,我选择将模型的生命周期封装在我当前宠物项目的活动生命周期中。

如果您的模型跨越(由多个活动填充/访问)(如果您有侧边栏和主要/容器小部件的情况),可以按顺序重新设计模型,如果您有示例我会尽力帮助。