Close

Simplifying Multiplicities for Agile MVP

It’s 2016 and guess who just turned 20 years old? Extreme Programming! You might not have thought it was around that long but Ron Jeffries in his “XP at 20” webpages assures us we can start counting from the year 1996. You might remember the first book on XP was published in October 1999, but Kent Beck was actually putting the ideas behind XP into practice three years before that.

2016 – 1999 + 3 = 20. So XP is 20.

In this article we will focus on one of the four values of Extreme Programming, namely simplicity. We’ll explore how far we can stretch that concept and try to apply it to one of the more recent UI design patterns, the Model-View-Presenter.

Nothing like the present

One of the thrusts of XP has always been simplicity. XP’s particular brand of simplicity is supported by the observation that developers are about as lousy at anticipating future user requirements as users are at describing their current ones. Therefore, the well-meaning attempts of developers to speculatively build features today in the hope of minimizing their context switching tomorrow, wind up costing them more time than they save. The advice from XP is to pursue simplicity through restraint – write software to the current needs of the users only, and avoid developing features that aren’t explicitly required now.

As the popularity of the simplicity value of XP has grown, the aphorism “You Ain’t Gonna Need It” or YAGNI has emerged to reinforce it. As a motto, YAGNI can stretch the simplicity objective beyond the classic forward-engineering scenario to the refactoring of existing software. The idea of “not required now” includes features that may be needed in the future (“not yet required”) but also those that had been at one time in the past (“no longer required”). YAGNI also applies to design so we ensure it also is a fit for the required features: we avoid overengineering and don’t add or keep layers of abstraction that aren’t necessary.

In object-oriented languages, this striving for simplification is a good counterbalance for patterns. Patterns enable us to develop infinitely complex technical classes and give them the illusion of meaningful purpose using a standardized domain-neutral naming. Two developers with a good understanding of patterns could both be tasked to write an ObserverVisitorFactoryFactorySingleton and both will probably write very similar code. This code can be written, moreover, without having to answer the question if such an over-engineered construct is actually needed. YAGNI has a neat role to play.

Simplifying features to patterns

If we can use YAGNI during refactoring to simplify designs so they support only the required features, is there also an opportunity to simplify our patterns to support only those features used by our designs?

Let’s take MVP. To recap briefly, MVP improves the older MVC UI pattern by dumbing down the view’s responsibilities to layout and event handling. The benefit is the separation of UI framework APIs from the presentation logic, which leads to:

  • Understandability of the operations of the interface in business-oriented terms (like “add customer”) in addition to the events of the interface in API terms (like “OnClick”);
  • Improved testability of the presentation logic;
  • Presenter’s indirect dependency on the view implementation and, by extension, the UI framework involved.

The standard template for MVP allows us to reap all of these benefits also in Vaadin applications. If we choose the right names for the presenter methods, remove from our views as much logic as we can, keep the presenter clean of dependencies on items from the com.vaadin.ui package, and let the presenters push updates to view implementations through references typed as interfaces, these benefits can be realized. The problem we’re left with is that MVP takes a lot of work and discipline, both when developing systems anew and when refactoring. For applications containing many screens for which users have rapidly changing requirements, the extra work might make it hard to justify the investment.

But can YAGNI help us here? Can we identify parts of the pattern that we do not need in order to fit our requirements of understandability, testability, and indirect dependencies? One place we recently considered with a Vaadin customer was the area of multiplicities.

E pluribus

A part of the complexity of MVP is its support for many 1:n multiplicities. Obvious examples would be being able to place hundreds of components on one view layout, or to add hundreds of listeners to one single event. There are two cases in which the actual needs of many enterprise UIs do not exceed 1:1 multiplicity where MVP allows 1:n at the cost of increased complexity: the number of views per presenter and the number of population types per view.

The first category is the easiest to understand and implement. Instead of working with an observer-type “add listener” pattern to associate our presenter with n views, we can simplify with a setter if there is only one. With DI, the view will get its presenter autowired and then invoke something using “this” to make the presenter aware of the view(s) it needs to populate.

One example:

package com.generalbakeries.erp;

import ...;

abstract public class GeneralBakeriesPresenter
{
  GeneralBakeriesDisplayable view = null;

  public void setView(GeneralBakeriesDisplayable val) {
    view = val;
  }

  abstract public void populate();
}
package com.generalbakeries.erp;

import ...;

@UIScope
@Controller
public class EmployeeListPresenter
       extends GeneralBakeriesPresenter {

  @Override
  public void populate() {
    view.display(EmployeeService.getEmployees());
  }
}
package com.generalbakeries.erp;

import ...;

@UIScope
@SpringView(name = ...)
public class EmployeeListView 
       extends GeneralBakeriesView
       implements GeneralBakeriesDisplayable {

  @Autowired
  EmployeeListPresenter presenter;

  @PostConstruct
  public void init() {
    this.addComponents(...);
    presenter.setView(this);
  }

  @Override
  public void enter(ViewChangeListener.ViewChangeEvent vce) {
    presenter.populate();
  }

  @Override
  public void display(Employees emp) {
    this.setContainerDataSource(cont);
  }

}

The second is more nuanced and considers the asymmetry between the number of types of event data that originate in the interface and the number that originate in the server. Even simple views will support multiple components and will generate multiple events that need to be forwarded to the presenter. Simple views in business applications, on the other hand, can often be populated in one single way.

In MVP the mechanism we’re given to populate the view implementation is the view interface on which we can define as many methods as we want. If are able to simplify and reduce the number of methods to 1, then we actually no longer have a requirement to define a view-specific implementation and interface for each view. Instead, we can use one shared view interface containing one method with a parameterized type argument. Such a base interface could be simplified to the following:

package com.generalbakeries.erp;

public interface GeneralBakeriesDisplayable<T> {
  void display(T dType);
}

If our UI contains a header, sidebar, footer, and a body, and the body is the container for our view navigation, and if our views are simple, a large portion of our UI could be composed of implementations of this interface. The samples below show how this would look for a view that shows a list of employee data and one that shows a single employee detail. Differences between the two are highlighted in bold:

package com.generalbakeries.erp;

import ...;

@UIScope
@SpringView(name = ...)
public class EmployeeListView
       extends GeneralBakeriesView
       implements GeneralBakeriesDisplayable<Employee[]> {

  @Autowired
  EmployeeListPresenter presenter;

  @PostConstruct
  public void init() {
    this.addComponents(...);
    presenter.setView(this);
  }

  @Override
  public void enter(ViewChangeListener.ViewChangeEvent vce) {
    presenter.populate();
  }

  @Override
  public void display(Employee[] emp) {
    ...
  }

}
package com.generalbakeries.erp;

import ...;

@UIScope
@SpringView(name = ...)
public class EmployeeDetailView 
       extends GeneralBakeriesView
       implements GeneralBakeriesDisplayable<Employee> {

  @Autowired
  EmployeeDetailPresenter presenter;

  @PostConstruct
  public void init() {
    this.addComponents(...);
    presenter.setView(this);
  }

  @Override
  public void enter(ViewChangeListener.ViewChangeEvent vce) {
    presenter.populate();
  }

  @Override
  public void display(Employee emp) {
    ...
  }

}

The presenters would look as follows:


package com.generalbakeries.erp;

import ...;

@UIScope
@Controller
public class EmployeeListPresenter 
       extends GeneralBakeriesPresenter {

  @Override
  public void populate() {
    view.<Employee[]>display(EmployeeService.getEmployees());
  }

}

package com.generalbakeries.erp;

import ...;

@UIScope
@Controller
public class EmployeeDetailPresenter
       extends GeneralBakeriesPresenter {

  @Override
  public void populate() {
    view.<Employee>display(EmployeeService.getEmployee(..));
  }

}

The knowledge whether a view has a single or multi-method interface will often only be needed by the presenter, so complexity can be added or removed as needed without impacting the other parts of the system. And if views start out simple, the single-method implementation will actually reinforce simplistic thinking.

By simplifying the patterns wherever possible so to minimize the number of classes and also providing support for views to be addressable indirectly through single-method interfaces, we are implementing and encouraging the fourth rule of XP Simple Design. This rule is to minimize the number of classes and methods. By following this rule we expect to achieve more agility and better quality software.

My best practices for Vaadin add-on projects

A good software project should be easy to build, fast to develop and it should be simple to test. This is also the case for Vaadin add-ons, which are not the most trivial kind of software projects on the Earth.

The de-facto method for creating Vaadin add-ons is a Maven project template called vaadin-archetype-widget. To tell you the truth, I’m not that big of a fan of it. Most of Vaadin’s own add-ons don’t use that kind of project setup either. The project it generates is a complicated multimodule setup, which is slow to develop with and, most essentially, it doesn’t really support proper testing.

For all add-ons I have created, for both official and my own add-ons, I have typically just copy-pasted the build and project structure from some recent project and adapted it for the new add-on. Slow and error prone. I finally decided to spend some time creating an add-on project template that I could think of using myself. The most relevant differences to the “official solution” are:

  • Single module project by default, much easier to checkout and get contributions.

  • Test UIs are in the same project as the add-on, which dramatically shortens development cycle.

  • Automatically updated UI to list and search relevant test cases.

  • A setup and examples for unit and browser level tests.

  • A separate “light” version for add-ons that don’t use GWT (plain server side or JS only add-ons), which removes a lot of clutter from the dependencies and the build.

Based on my rather extensive experience on both Vaadin’s and my own add-ons, I dare say these new archetypes are the way to go for your next Vaadin add-ons. I'd love to hear feedback on these so that they can serve as a starting point for our next official add-on archetypes as well. If you have tried creating an add-on before, and gave up due to the complexity involved, this might be the day to try it again. Also, you can use them as an example, if you wish to convert your existing add-on project to a similar structure.

Try new add-on archetypes

Using Web Components in jQuery projects

One of the great things about Web Components is that they can easily be used in existing applications without requiring you to re-architect the application. This makes Web Components like Vaadin Elements a great resource for jQuery developers – it gives you many more options when it comes to high quality UI components at your disposal. In this post you'll learn how to easily replace an existing jQuery UI component with a Web Component.

Tutorial: updating a jQuery UI component to a Polymer based Web Component

You can find all the code for the example on GitHub: https://github.com/vaadin/jquery-web-components

This is our starting point, a simple signup form:

jQuery app with date picker
<html>
<head>
  <meta charset="utf-8">
  <title>Sigup form</title>
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.12.0/themes/base/jquery-ui.css">
  <script>
    $(function() {
      $('#birthdate').datepicker();
      $('#form').on('submit', function(e) {
        e.preventDefault();
        var name = $('#name').val();
        var birthdate = $('#birthdate').val();
        if (name && birthdate) {
          window.alert('Signed up: ' + name + 
                       ' (born ' + birthdate + ')');
        }
      });
    });
  </script>
  <style media="screen">
    body {
      font-family: sans-serif;
    }
  </style>
</head>

<body>
  <h1>Signup form</h1>

  <form id="form">
    <p>
      Name:
      <input type="text" id="name">
    </p>
    <p>
      Birth Date:
      <input type="text" id="birthdate">
    </p>

    <button>Submit</button>
  </form>
</body>
</html>

Installing the datepicker and its dependencies

The first step is to install Bower, a package manager used to fetch Web Components. You'll need to have Node and NPM installed before doing this. Adding the -g flag to npm install will make the bower command available globally, not just in the directory you are in.

npm install -g bower

With Bower installed, we can go ahead and initialize our directory. Type

bower init

and answer the questions (defaults should be fine). Once you have initialized Bower, you are ready to start installing Web Components to your project. Let's install vaadin-date-picker:

bower install --save vaadin-date-picker

Bower will install vaadin-date-picker and all it's dependencies in a folder named bower_components. You should not add this to version control, instead let other developers in your project run bower install to install the same dependencies (defined in the bower.json file).

Replacing the old datepicker with the new one

With the new date picker installed, we're ready to get coding.

The first thing we want to do is remove the CSS and JS imports for jQuery UI as we are no longer using it.

Once we've removed the unused files, we'll add two new imports – webcomponents.js and vaadin-date-picker.html. The first file is a polyfill that allows Web Components to also run on browsers that don't have native support for them yet. The second import is for the actual vaadin-date-picker component.

At this point, the <head> of our app looks like this:

<head>
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="bower_components/vaadin-date-picker/vaadin-date-picker.html">
</head>

With the imports taken care of, we can change the actual component on the page. We do this by inserting a <vaadin-date-picker> tag and giving it an id. Using a custom element like vaadin-date-picker is no different than using any other HTML tag, you don't need to do any additional JavaScript bootstrapping.

<p>
    Birth date:
    <vaadin-date-picker id="birthdate"></vaadin-date-picker>
</p>

Since we are no longer using the jQuery UI datepicker, we can also simplify our code by removing its initialization call $('#datepicker').datepicker(); Since we are still using the same id for the field, we do not need to change the submit logic.

Finally, we'll style the component to fit in. We do this through CSS, just like we would do with any other HTML.

#birthdate {
   display: inline-block;
   width: 200px;
}
jQuery app with web component date picker

And that's all there is to it. As you can see, Web Components work well together with existing jQuery applications and UI components and give you access to a large selection of quality UI components.

Browse all Vaadin Elements