Re: Converting existing app to MVP

265 views
Skip to first unread message

Ümit Seren

unread,
Jul 10, 2012, 10:17:31 AM7/10/12
to google-we...@googlegroups.com
Make sure you read following articles (in case you haven't done it yet): 

Then there are also some interesting google I/O conference from last year: http://www.google.com/events/io/2010/sessions/gwt-continuous-build-testing.html

I am not sure how big your project is you want to convert. However I would probably start a fresh new project and then create the views/presenters one by one and populate them with the data from the original project (i.e. copy the business code and server calls into the presenters and copy the view UI into the views). 
I am not sure if that's not the cleaner/better approach. 

Also you can try 3rd party MVP tools (GWTP or mvp4g) which automatically create a lot of boilerplate code.


On Thursday, July 5, 2012 1:27:55 AM UTC+2, Zane wrote:
We have a alpha stage application with significant code developed in the "classic" style with front end widgets (using UiBinder in many cases, but not exclusively) making calls to back end services and directly updating the UI themselves. I.e., clicking on row in CellTable summary widget clears main content area and adds edit detail widget for the row. Clicking on cancel clears content area and adds summary widget back in. That kind of thing.

We've been looking into MVP and the concepts and style seem clear enough on their own. I don't think we'd have a problem with green field development, but in our case it is a question of refactoring and transitioning the existing application.

I figure we'll get started with the login module, which is relatively small and isolated compared to the application proper.

Thinking ahead to the larger task of transitioning the full application, I have two questions.

First, any general advice or references?

Second and more specifically, it seems clear enough that the transition will proceed view-by-view, starting with the initial look and proceeding through the options. What's not clear to me at the moment is whether there's any trick, or how reasonable it is to tie the classic style code into the MVP portions so that we can maintain functionality during the transition process.

Or, whether it's more reasonable to "bite the bullet" and transition everything in one go. 

Thanks in advance for any advice.

Regards,

Z

Daniel Kurka

unread,
Jul 17, 2012, 2:14:55 PM7/17/12
to google-we...@googlegroups.com
It`s hard to give a general advice on how to tackle this best, because it highly depends on your current application and the structure of your code.

Let me outline a few important things, which you should take into consideration:
Navigation inside a one page app is a very important thing. It essentially means that reload and the back button have to work like in a normal webpage situation.
This is very easy to implement with GWT, but its very hard to retrofit apps if you don`t have that right from the start. Make sure to use a proper history support mechanism throughout your app.

The other thing that comes to mind:
I always like moving in small steps and see if the floor support my weight. So I am not a big fan of an everything new approach in one big step. If you code is already cut into what you call small widgets that talk to a back end try separating them first into a presenter, a model and a view and write tests for them. Writing test will help you keep your code in the right places (you can write unit tests for views) and it shows you that you did not break anything from the basic functionality of the widget while going forward. This would mean that it should be possible to port all your "presenters" first and then change the overall structure of your application. 

If you want a more detailed recommendation, we should take a look into some example code from the app to see what actually needs to be done.

-Daniel

Zane

unread,
Aug 1, 2012, 12:41:03 PM8/1/12
to google-we...@googlegroups.com
Here's a flavor of the current style. 'EntryPoint' loads 'ItemsDropdown', which displays a list of individual item names. Clicking on one of these names displays the 'ItemOverview' widget.

Some specific conversion strategies we'd like ideas on:

- Is it reasonable and useful to implement Places within the current implementation without moving to the full MVP approach?

- Same question on the EventBus?

I.e., I see three possible strategies at this point:

Big Gulp: Current Impl -> MVP
Iterative 1: Current Impl -> Places -> EventBus / MVP
Iterative 2: Current Impl -> EventBus -> Places / MVP

Other approaches may be possible.


----------------
public class EntryPoint {

  public void loadUi() {
    mainLayout = uiBinder.createAndBindUi(this);
    initWidget(mainLayout);
  
    //mainContent is the panel below the navigation menu, where the controls are displayed
    //There's no dependency injection, just some basic declaration of dependencies
    //appMessages is a widget to display any errors related to server calls.
    final ItemsDropdown itemSelect = new ItemsDropdown(labels.myItems(), appMessages, mainContent);
  }

}
----------------
// from the dropdown control, we can select a summary view or select a specific item
public class ItemsDropdown {
        //The i18n classes are always instantiated with GWT.create(),
        //same with the services. There is no caching.
        private final I18nLabels labels = GWT.create(I18nLabels.class);
        private final ItemServiceAsync itemService = GWT.create(ItemService.class);

        private final ApplicationMessages appMessages;
        private final Panel contentPanel;

        //Constructor and Table code has been removed for clarity; this is
        //where we build out the table of the most recently used items;
        //clicking on an item calls 'loadSpecificItem', clicking on the top
        //'Items' label causes all the user's items to be loaded with
        //'MyItems'

        protected void loadSpecificItem(final ListItem lItem) {
                final Item value = lItem.getValue();

                //Most controls have not been designed with instance reusability in mind, it's safer to
                //instantiate a new one.
                //Clear the panel and draw the control
                final ItemOverview itemOverview = new ItemOverview(appMessages);
                contentPanel.clear();
                contentPanel.add(ItemOveriew);

                itemOverview.displayDetail(value);
        }

        protected void loadAllItems() {
                //MyItems handles both displaying a table with all items and the detail of a single one.
                //This is a Dropdown, purely UI, therefore it would be messier to do the table vs single work here.
                final MyItems myItems = new MyItems(appMessages);
                contentPanel.clear();
                contentPanel.add(myItems);
        }
}
----------------
// Displays the details of a single item.
public class ItemOverview extends Composite implements DetailDisplay<Item> {
        @Override
        public void displayDetail(final Item item) {
                // the detail display consists of a detail, notes, a summary of other items by the same user and 
                final ItemDetail itemDetail = new ItemDetail(appMessages);
                final NotesManager notes = new NotesManager(appMessages);
                final OtherItemsByAuthor otherItems = new OtherItemsByAuthor(/*DetailDisplay<Item>*/this, appMessages);

                final ItemProfile itemProfile = new ItemProfile(itemDetail, notes, otherItems, appMessages);

                mainContent.clear();
                mainContent.add(itemProfile);
        }
}
EntryPoint.java
ItemOverview.java
ItemsDropdown.java

Daniel Kurka

unread,
Aug 30, 2012, 2:37:03 PM8/30/12
to google-we...@googlegroups.com
Hi Zane,



you can definitely use an iterative approach and go one part after another.

I think it would be best to start to convert your CustomWidgets to actual MVP first which you can later connect by using the Activity and Places.

-Daniel
Reply all
Reply to author
Forward
0 new messages