Lazy loading of views?

45 katselukertaa
Siirry ensimmäiseen lukemattomaan viestiin

Olx

lukematon,
8.11.2009 klo 11.45.148.11.2009
vastaanottaja Mvp4g
Hi Pierre,

Another concern/question regarding the framework. Referring to FAQ
(http://code.google.com/p/mvp4g/wiki/FAQ) the framework generates the
following code (as an example):

...
public class Mvp4gStarterImpl implements Mvp4gStarter {
public void start(){
EventBus eventBus = new EventBus();
final com.mvp4g.example.client.view.UserDisplayView
userDisplayView = new com.mvp4g.example.client.view.UserDisplayView();
final com.mvp4g.example.client.view.UserCreateView
userCreateView = new com.mvp4g.example.client.view.UserCreateView();
final com.mvp4g.example.client.view.RootView rootView = new
com.mvp4g.example.client.view.RootView();
final com.mvp4g.example.client.service.UserServiceAsync
userService = GWT.create
(com.mvp4g.example.client.service.UserService.class);
final com.mvp4g.example.client.presenter.UserCreatePresenter
createUserPresenter = new
com.mvp4g.example.client.presenter.UserCreatePresenter();
createUserPresenter.setEventBus(eventBus);
...

Which means that all widgets are created during application
initialization. That can become a problem for big monolithic
applications... Would be great to have views lazy loading (create
widget on demand). Does the stated in coming version 1.1.0
modularization solve this problem? Can you please clarify how you
address this problem?

Thanks!

All the best,
Alex.

Pierre

lukematon,
9.11.2009 klo 11.31.119.11.2009
vastaanottaja Mvp4g
Hi Alex,

For views, one solution could be to use LazyPanel and bind view only
when the view is displayed:

public MyPresenter extends Presenter<MyLazyView> {

public void bind(){
//do nothing because view hasn't been created yet.
}


public void onStart(){

lazyBind();
eventBus.dispatch("DisplayView", view);

}

public void lazyBind(){
if (view.getWidget() == null){
view.setVisible(true);

//bind view here
view.getButton()...

}
}

}


A thing that could be interesting to add to the framework is a kind of
lazy creation of presenter. A presenter
could be created only when it needs to handle an action (or when it's
the presenter associated with the start view).

public void start(){
getPresenter("userPresenter", UserPresenter.getClass()).onStart();
}

private <T> T getPresenter(String name, Class<T> presenterClass){
T presenter = (T) maps.getPresenter(name);
if(presenter == null){
presenter = (T) buildPresenter(name);
maps.put(name, presenter);
}
return p
}

private PresenterInterface buildPresenter(Sting name){
//build presenter
if("userPresenter".equals(name)){
...
}
}

I have to think about it to see if there is a better way to do it and
make sure that there is no performance issue.

Thanks for this great idea.

-Pierre

Oleksandr Lobunets

lukematon,
10.11.2009 klo 3.55.0810.11.2009
vastaanottaja mv...@googlegroups.com
Pierre,

indeed, usage of LazyPanel helps to avoid overhead in big
applications. I like your idea with lazy presenters, but not sure how
it will impact the performance. It seems to be that initialization of
presenter with a complex view binded to it in the runtime will
increase the event processing time.

Not sure if this should be part of a framework or should be left up to
developers...

Pierre

lukematon,
10.11.2009 klo 12.33.2210.11.2009
vastaanottaja Mvp4g
Hi Alex,

you bring a good point. Developers should be able to initialize views
at start if they want to speedup event processing. However, maybe the
framework could help developers to use lazy view by postpone binding
of the view to presenter.
Presenter could still be initialized when handling its first event and
view will be binded then. However view will be initiatialized at
startup and it will be up to the developer to lazy load it or not
(depending if he uses a lasy panel or not), but unlike the first
solution, he will be able to load its views in the bind method
(instead of having to manage another one).
Initialization of presenter shouldn't have a big impact on event
proccessing time so I think they can be lazy loaded.

You would have something like that:

public MyPresenter extends Presenter<MyLazyView> {


public void bind(){
//with this solution, you know that bind is called the first
//time the presenter is used, so you can built your lazy view
here
if (view.getWidget() == null){
view.setVisible(true);


//bind view here
view.getButton()...


}
}


public void onStart(){
eventBus.dispatch("DisplayView", view);
}

}


public class Mvp4gStarterImpl implements Mvp4gStarter {
public void start(){

//if it's a lazy panel, view will be built later otherwise it
will be built at start-up
final UserDisplayView userDisplayView = new UserDisplayView();

EventBus eventBus = new EventBus(){

public void start(){
getPresenter("myPresenter", MyPresenter.class).onStart
();

}

private <T> T getPresenter(String name, Class<T>
presenterClass){
T presenter = (T) maps.getPresenter(name);
if(presenter == null){
presenter = (T) buildPresenter(name);
maps.put(name, presenter);
}
return p
}

private PresenterInterface buildPresenter(Sting name){

PresenterInterface p = null;
//build presenter
if("userPresenter".equals(name)){
p = new UserPresenter();
p.setView( userDisplayView );
}
...

return p;

}

}
}
}


What do you think?

-Pierre

On Nov 10, 9:55 am, Oleksandr Lobunets <alexander.lobun...@gmail.com>
wrote:
> >> Alex.- Hide quoted text -
>
> - Show quoted text -

Olx

lukematon,
11.11.2009 klo 3.51.3711.11.2009
vastaanottaja Mvp4g
Pierre,

this looks clear. LazyPanel usage is up to developers and there's no
need to hack around bind() introducing another method.
I think this would be a great add-on to the framework without
complicating things.

Do you believe this can be also implemented within 1.1?

All the best,
Alex

Pierre

lukematon,
11.11.2009 klo 17.14.5111.11.2009
vastaanottaja Mvp4g
> Do you believe this can be also implemented within 1.1?
Yes, I don't think it will be too hard to implement. I created an
issue (Issue 15) and updated the roadmap.

-Pierre

Olx

lukematon,
12.11.2009 klo 10.01.2112.11.2009
vastaanottaja Mvp4g
Thanks a lot!

Pierre

lukematon,
25.11.2009 klo 22.09.2925.11.2009
vastaanottaja Mvp4g
I tried to implement this factory method and use maps (one for
presenters, views and services, as described before) to delay
instantiation of the presenter and the bind of the view. I've been
disappointed by the result since performances were not as good as
before.
Also stocking presenters in a map means that the more presenters you
have, the longer it will take to retrieve a presenter from the map and
treat an event.

So I want to try another approach, closer to the GWT lazy panel.

Like lazy panel, presenter will be instantiated at the start but they
will neither be built nor bind to the view before they have to handle
an event. I want to introduce a new method in presenter definition:
bindIfNeeded. This method will be called all the times before the
presenter has to handle an event to verify that the presenter was
binded to view. If it's not the case, the bind method will be called,
otherwise nothing will be done. Like that, the framework will call the
bind method only when needed and it will make sure to call this method
only once. Thus developers can build the presenter and its view in the
bind method. The bindIfNeeded method will be implemented by
BasePresenter so developers won't have to worry about it.

View and presenter will be instantiated at the start but not built
until they have to handle their first event so you can speed up start
up time.
Developers will also be able to decide if views and presenter should
be built at the start or when they handle their first event.

You would have something like:

public Mvp4gStarterImpl implements Mvp4gStarter{

public void start(){

LoginView loginPresenterView = new LoginView();

final LoginPresenter presenter_LoginPresenter = new
LoginPresenter();
...

AbstractEventBus eventBus = new AbstractEventBus(){
public void init(){
checkBind(presenter_LoginPresenter).onInit();
...
}
...
}
}

public <T extends PresenterInterface> T checkBind(T presenter){
presenter.bindIfNeeded();
return presenter;
}

...
}

public BasePresenter<T,V> implements PresenterInterface<T,V>{

private boolean binded = false;

public void bindIfNeeded(){
if(!binded){
bind();
binded = true;
}
}


}

public LoginPresenter extends BasePresenter{
public void bind(){
//build presenter
buildPresenter();

//build view
buildView();

//bind view
...

}

}

This shouldn't impact performances that much and be more scalable.
What do you think?

-Pierre


> > -Pierre- Hide quoted text -

Oleksandr Lobunets

lukematon,
26.11.2009 klo 4.22.1226.11.2009
vastaanottaja mv...@googlegroups.com
Pierre,

Looks good so far, the only question is if there will be requirements to migrate an existing code?

As far as I understood, having this functionality implement, all presenters should extend BasePresenter
instead of Presenter<SomeViewInterface>?

Another questions regarding the bind() method: is this just an example with buildView()/buildPresenter() or are there any new conventions related to presenters/views implementation?

As for the lazy views loading, the solution is just to use LazyPanel as a basis, right? (just confirming)
> --
>
> You received this message because you are subscribed to the Google Groups "Mvp4g" group.
> To post to this group, send email to mv...@googlegroups.com.
> To unsubscribe from this group, send email to mvp4g+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/mvp4g?hl=en.
>
>

Pierre

lukematon,
26.11.2009 klo 10.15.4726.11.2009
vastaanottaja Mvp4g
> Looks good so far, the only question is if there will be requirements to migrate an existing code?
> As far as I understood, having this functionality implement, all presenters should extend BasePresenter
> instead of Presenter<SomeViewInterface>?
I had to rename the Presenter class to BasePresenter because I added
an annotation called Presenter. Even if these classes
are in two different packages, I wanted to prevent code like this:

import com.mvp4g.client.presenter.Presenter

@com.mvp4g.client.annotation.Presenter
public MyPresenter extends Presenter<,>{}


> Another questions regarding the bind() method: is this just an example with buildView()/buildPresenter() or are there any new conventions related to presenters/views implementation?
This is just an example but it should be followed as a best practice.
You want to do as little as possible in your constructor method and as
much as you can in your bind method to speed up load of the
application and prevent execution of useless code (as all constructor
methods are called at the start but bind is called only when the
presenter has to handle its first event).

> As for the lazy views loading, the solution is just to use LazyPanel as a basis, right? (just confirming)
Yeah and then in the bind method of the presenter, call view
setVisible method to build your view:

public MyPresenter ... {

public void bind(){
//build your presenter
...

//build your view
view.setVisible(true);

//bind your view
...

}

}

-Pierre


On Nov 26, 10:22 am, Oleksandr Lobunets <alexander.lobun...@gmail.com>
wrote:
> > For more options, visit this group athttp://groups.google.com/group/mvp4g?hl=en.- Hide quoted text -

Oleksandr Lobunets

lukematon,
26.11.2009 klo 10.22.5526.11.2009
vastaanottaja mv...@googlegroups.com
Pierre,

thank you for clarification. Mvp4g is indeed a great framework and we already started using it in a new long term project. Hopefully, in 4-5 months I will be able to share with you some information as a showcase of mvp4g usage.

The only disappointment is the REST-services support I've mentioned some time ago. It is possible to go without it, but presenters unit testing is impossible (well, the straight-forward way). I know that corresponding Issue was added and hope it will be available in version 1.2 or later...

Thumbs up!

Pierre

lukematon,
29.11.2009 klo 11.35.1829.11.2009
vastaanottaja Mvp4g
Thanks Alex, I can't wait to see your feedback about the framework.

I implemented the "lazy binding" feature in the framework. I also
added two lazy classes to ease the work of the developer to implement
the best practices I described earlier: LazyView and LazyPresenter.

LazyView provides a method to build the view when needed:
public interface LazyView {

/**
* Method called when the elements of the view needs to be built
*/
public void createView();

}

LazyPresenter will automaticaly build the view and the presenter in
the bind method. Presenter that extends this class will have to
override the bindView method instead of bind method.
public class LazyPresenter<V extends LazyView, E extends EventBus>
extends BasePresenter<V, E> {

@Override
final public void bind() {
view.createView();
createPresenter();
bindView();
}

/**
* Bind the view to the presenter once both elements have been
created.
*/
public void bindView() {

}

/**
* Called when presenter needs to be built.
*/
public void createPresenter() {

}

}


I uploaded a new version of 1.1.0-snapshot library with the
Mvp4gHistory example that uses these classes to lazy bind the view.

-Pierre

On Nov 26, 4:22 pm, Oleksandr Lobunets <alexander.lobun...@gmail.com>
> >>> For more options, visit this group athttp://groups.google.com/group/mvp4g?hl=en.-Hide quoted text -

Toine Eetgerink

lukematon,
30.11.2009 klo 5.43.4530.11.2009
vastaanottaja mv...@googlegroups.com
Pierre

Perfect the lazy loading ,
Is this also possible to use this in a kind of way with GXT. At lazyview extends lazypabel extends .......google panel..
With this implementation is it also possible to not load the presenter when no access is retrieved..

Keep up the good work
Regards toine

----- Oorspronkelijk bericht -----
Van: Pierre <plco...@gmail.com>
Verzonden: zondag 29 november 2009 17:35
Aan: Mvp4g <mv...@googlegroups.com>
Onderwerp: Re: Lazy loading of views?
[Het originele bericht is niet volledig opgenomen]

Pierre

lukematon,
30.11.2009 klo 17.41.5730.11.2009
vastaanottaja Mvp4g
Hi Toine,

> Is this also possible to use this in a kind of way with GXT.
Yes you can use it with GXT. Here is an example of a GXT view using
Mvp4g LazyView interface:

public class UserListView extends ContentPanel implements
UserListViewInterface, MyWidgetInterface, LazyView {

private MySimpleGXTButton delete = null;
private MySimpleGXTButton newButton = null;
private MySimpleGXTButton yes = null;
private MySimpleGXTButton no = null;
private MyLabel confirmText = null;

private MyGXTTable userList = null;
private MyGXTPagingToolBar toolBar = null;

public void createView(){
delete = new MySimpleGXTButton( "Delete" );
newButton = new MySimpleGXTButton( "New" );
yes = new MySimpleGXTButton( "Yes" );
no = new MySimpleGXTButton( "No" );
confirmText = new MyLabel( "Are you Sure?" );
toolBar = new MyGXTPagingToolBar( 4 );

setBodyBorder( false );
setHeading( "Users" );
setButtonAlign( HorizontalAlignment.CENTER );

HorizontalPanel buttons = new HorizontalPanel();
buttons.setSpacing( 4 );
buttons.add( delete );
buttons.add( newButton );
buttons.add( confirmText );
buttons.add( yes );
buttons.add( no );

add( buttons );

setBottomComponent( toolBar );

}

...
}

What you basicaly do is:
-have your view to implement LazyView
-move everything you were doing from your constructor to the
createView method.

> With this implementation is it  also possible to not load the presenter when no access is retrieved..
Yes, you can easily do that by having your presenter extends
LazyPresenter. By extending this class, you will have to define the
createPresenter method which will be called to load/build the
presenter. This method will be called by the bind method thanks to the
specific implementation of LazyPresenter.

> Keep up the good work
Thanks :)

-Pierre
Vastaa kaikille
Vastaa kirjoittajalle
Välitä
0 uutta viestiä