prose :: and :: conz


Explosive verbosity: Java and the MVP Pattern

I’ve been silent the past several weeks due to setting into my new position at Mentor Graphics. That has kept me busy and frankly, nothing has been pissing me off enough to write. Unfortunately, Java did its thing and inspired me to write again. At my job, we are working on a small Sencha GXT web application (a derivative of GWT). When I arrived, the project was very monolithic and growing difficult to maintain. As a result, we’re spending an entire 2-week sprint on refactoring to the Model View Presenter Architecture. I’m quite confident that this architecture will substantially improve the code quality of our product. Thus far, I have no complaints about MVP. It’s Java that’s causing all the problems…

If you aren’t familiar with MVP, the main thing you need to know for this rant is that the View component of it only contains widgets. You put your text boxes, buttons, blah blah all here. You define an interface for the view that the presenter can interact with. This interface abstracts away the concrete implementation classes of the actual widgets. You just get some accessors for the interfaces the widgets implement. Let me show an illustrative example before I lose you. Let’s consider a view that has only a button. This might be the View interface:

public interface Display {
    HasSelectHandlers getButton();
}

Here you can see the button accessor I referred to. Notice that it is not a TextButton or any concrete button class. It is the interface HasSelectHandlers which is all you need to be notified when the user clicks it.

Display display = new ...

display.getButton().addSelectHandler(new SelectHandler() {
    @Override
    public void onSelect(SelectEvent event) {
        // Take some action...
    }
});

Obviously, I want to lament the lack of lambdas in this code, but not only is that an easy target, Java 8 has Project Lambda to address this. Hence we will be able to write it much more concisely soon, like this:

display.getButton().addSelectHandler(event ->
    // Take some action...
);

We’ll let Java have that one. Let’s move on to something a little more interesting than a simple button. Let’s add a TextField to our view.

public interface Display {
    HasSelectHandlers getButton();
    TakesValue<String> getTextField();
}

So it’s all good, right? We have some widget out there that lets us set and get the value via TakesValue. If we suppose the button selection is the user’s gesture for submitting the data entered into the text field, we’re good to go. I hope you know better than this. Not all of us like to use a mouse. We should also submit the data when the Enter key is pressed within the text field. This means we need it to accept what they call a KeyDownHandler, hence it needs to be a HasKeyDownHandlers.

But… we’ve already abstracted our TextField to a TakesValue… We also need it to be a HasKeyDownHandlers because… well… a TextButton IS both a TakesValue and a HasKeyDownHandlers. This is where we take a deep sigh because Java doesn’t give us a way to express such a return type. We have to resort to adding another method to return the same object but as a different interface.

public interface Display {
    HasSelectHandlers getButton();
    TakesValue<String> getTextFieldTakesValue();
    HasKeyDownHandlers getTextFieldKeyDown();
}

Now imagine that you have several events and such you want to handle for that one widget as well as more handles for manipulating the field. The code just piles up.

public interface Display {
    HasSelectHandlers getButton();
    TakesValue<String> getTextFieldTakesValue();
    HasKeyDownHandlers getTextFieldKeyDown();
    HasKeyUpHandlers   getTextFieldKeyUp();
    HasVisibility      getTextFieldVisibility();
    HasEnabled         getTextFieldHasEnabled();
}

While this example is a little contrived, it’s not unreasonable to need all of these accessors. The interface is cluttered up enough, but you also have to implement all of those little getters in each implementation you write, such as the production code:

public class DisplayImpl implements Display {
    private TextButton button = new TextButton();
    private TextField textField = new TextField();
    public HasSelectHandlers getButton() { 
        return button; 
    }
    public TakesValue<String> getTextFieldTakesValue() { 
        return textField; 
    }
    public HasKeyDownHandlers getTextFieldKeyDown() { 
        return textField; 
    }
    public HasKeyUpHandlers getTextFieldKeyUp() { 
        return textField; 
    }
    public HasVisibility getTextFieldVisibility() { 
        return textField; 
    }
    public HasEnabled getTextFieldHasEnabled() { 
        return textField; 
    }
}

I find it very annoying that I have to write five getters for the same object. I can’t complain too much. They were EXACTLY the same, so copy/paste shortcut keys made my job easy. Code reuse at its finest!

Sigh… If only we could use Scala in GWT… Our Display interface would only need one getter per widget, because we could mix all of the little interfaces together. The trait would look like this:

trait Display {
  def getButton:SelectEvent.HasSelectHandlers
  def getTextField:HasValue[String] with 
                   HasKeyDownHandlers with 
                   HasKeyUpHandlers with 
                   HasVisibility with 
                   HasEnabled
}

And the implementation of the display is likewise more concise.

class DisplayImp extends Display {
  private val button = new TextButton
  private val textField = new TextField
  override def getButton = button
  override def getTextField = textField
}

One really nice feature of this approach is you can mix more of these interfaces into the view interface without having to even change the production code implementation.

Here’s to hoping that scala.js takes off. I could buy into a Scala to JavaScript compiler any day over Java to JavaScript.

So if you’ve been skeptical about the claims of how Scala requires one-half or one-third the lines of code as Java, maybe this example helps.


Olde Comments
  1. […] myself. It has been on my radar, but I’ve yet to dabble in it. Combined with my recent lamentations on GWT/Java/MVP, I decided to give it a […]

  2. […] aside, this is a pattern I was already using quite recently due to our refactor to utilize the Model-View-Presenter pattern. In this pattern, the presenter interacts with the view via an interface. The presenter then has a […]

Tagged with: scala (41), java (22), web-development (19), gwt (1), mvp (1)