49
Functional Vaadin Henri Muurimaa, SVP of Engineering [email protected] @henrimuurimaa 7

Functional UIs with Java 8 and Vaadin JavaOne2014

  • Upload
    hezamu

  • View
    609

  • Download
    4

Embed Size (px)

DESCRIPTION

Slides for the JavaOne 2014 talk about how the functional features of Java 8 and Vaadin empower you to write clearer UI code.

Citation preview

Page 1: Functional UIs with Java 8 and Vaadin JavaOne2014

Functional Vaadin

Henri Muurimaa, SVP of Engineering [email protected] @henrimuurimaa

7

Page 2: Functional UIs with Java 8 and Vaadin JavaOne2014
Page 3: Functional UIs with Java 8 and Vaadin JavaOne2014

MissionMissionWhy do we exist

Make building amazing web applications easy

Page 4: Functional UIs with Java 8 and Vaadin JavaOne2014

Build UIs with components

Vaadin X

Page 5: Functional UIs with Java 8 and Vaadin JavaOne2014

Developer

Productivity

Rich

UX

Page 6: Functional UIs with Java 8 and Vaadin JavaOne2014

Web application layers

JavaScriptWeb serverBackend Communication

JS required required required requiredVaadin

required optionalrequired optional

Page 7: Functional UIs with Java 8 and Vaadin JavaOne2014

Web application layers

JavaScriptWeb serverBackend Communication

JS required required required required

Vaadin

required optionalrequired optional

1 layer vs

3 layers

Less code Less bugs Faster time-to-market

Page 8: Functional UIs with Java 8 and Vaadin JavaOne2014

But can it scale?

Page 9: Functional UIs with Java 8 and Vaadin JavaOne2014

Test results

20,622 AJAX requests / minute before exceeding 1% rejected connections

MPAA reports 1,4 billion movie tickets sold in 2009. !

~2,700 tickets / minute.

5,496 tickets / minute

~11,000 concurrent users

On a single Amazon EC2 Large instance

www.vaadin.com/blog/-/blogs/vaadin-scalability-study-quicktickets

Page 10: Functional UIs with Java 8 and Vaadin JavaOne2014

Wrong, but the community is very active there

> 100.000 developers from > 10.000 cities > 450 add-ons in the marketplace

Other 4 %Asia

20 %

Americas 22 %

Europe 54 %

Open Source community

Apache-licensed

Page 11: Functional UIs with Java 8 and Vaadin JavaOne2014

Demo time

Page 12: Functional UIs with Java 8 and Vaadin JavaOne2014

github.com/hezamu/WorkoutTracker

Page 13: Functional UIs with Java 8 and Vaadin JavaOne2014

What is Functional Programming?

Page 14: Functional UIs with Java 8 and Vaadin JavaOne2014

A style of programming that expresses computation as the evaluation of mathematical functions

Page 15: Functional UIs with Java 8 and Vaadin JavaOne2014

Recursion

Lazy evaluation

Lambda expressionsType theory

MonadsReferential transparency

Currying

Entscheidungsproblem

Pattern matching

Tuples

Page 16: Functional UIs with Java 8 and Vaadin JavaOne2014

Something practical?

Side effects?

State?

Denied

Denied

Page 17: Functional UIs with Java 8 and Vaadin JavaOne2014

Okay…

Page 18: Functional UIs with Java 8 and Vaadin JavaOne2014
Page 19: Functional UIs with Java 8 and Vaadin JavaOne2014

What’s in it for me?

A new way of thinking

A new way of programming

Write tight, robust and scalable code

Page 20: Functional UIs with Java 8 and Vaadin JavaOne2014

What’s hot in Java 8

Page 21: Functional UIs with Java 8 and Vaadin JavaOne2014

Improved Date API

Page 22: Functional UIs with Java 8 and Vaadin JavaOne2014

New Java 8 Date API in action

public int monthAge() { return (new Date().getYear() - date.getYear()) * 12 + (new Date().getMonth() - date.getMonth()); }

// Java 8 version with the new Date API public int monthAge() { return (int) Period.between(date, LocalDate.now()).toTotalMonths(); }

Page 23: Functional UIs with Java 8 and Vaadin JavaOne2014

Lambda expressions

Page 24: Functional UIs with Java 8 and Vaadin JavaOne2014

Anonymous functions

Runnable r = () -> System.out.println("hello lambda!”);

Comparator<Integer> cmp1 = (x, y) -> (x < y) ? -1 : ((x > y) ? 1 : 0);

// Anonymous onsite functions button.addClickListener(event -> System.out.println("Button clicked!"));

Comparator<Integer> cmp2 = (x, y) -> { return (x < y) ? -1 : ((x > y) ? 1 : 0); // Need return if not one liner };

Page 25: Functional UIs with Java 8 and Vaadin JavaOne2014

Workout Tracker example

editor.clear.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { editor.clearValues(); updateRating(); } });

// Java 8 version with a lambda editor.clear.addClickListener(event -> { editor.clearValues(); updateRating(); });

Page 26: Functional UIs with Java 8 and Vaadin JavaOne2014

Method references with the :: notation

! private void eventHandler(Button.ClickEvent event) { // do something about the button click }

button.addClickListener(this::eventHandler);

// If the handler method is static button.addClickListener(MyClass::eventHandler);

Page 27: Functional UIs with Java 8 and Vaadin JavaOne2014

Workout Tracker example

!editor.activity.addValueChangeListener(new Property.ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { updateRating(); } });

editor.date.addValueChangeListener(this::updateRating);

Page 28: Functional UIs with Java 8 and Vaadin JavaOne2014

Streams

Page 29: Functional UIs with Java 8 and Vaadin JavaOne2014

Composable to new Streams with higher order functions

Stream != Collection

As lazy as possible

Create from a Collection or an Iterable

Page 30: Functional UIs with Java 8 and Vaadin JavaOne2014

Input validation

private boolean areInputsValid() { Component component = null; for (Iterator<Component> iter = editor.iterator(); iter.hasNext(); iter.next()) { if (fieldNotValidating(component)) return false; } return true; }

// Java 8 version with anyMatch and a method reference private boolean areInputsValid() { return !StreamSupport.stream(editor.spliterator(), true) .anyMatch(this::fieldNotValidating); }

Page 31: Functional UIs with Java 8 and Vaadin JavaOne2014

From rating to stars

StringBuilder stars = new StringBuilder("New Workout: "); for (int i = 0; i < rating; ++i) { stars.append(FontAwesome.STAR.getHtml()); } editor.title.setValue("New Workout: “ + stars);

String stars = IntStream.range(0, rating) .mapToObj(r -> FontAwesome.STAR.getHtml()) .collect(Collectors.joining("")); editor.title.setValue("New Workout: " + stars);

Page 32: Functional UIs with Java 8 and Vaadin JavaOne2014

Higher order functions

Page 33: Functional UIs with Java 8 and Vaadin JavaOne2014

A function that takes one or more functions as input

Page 34: Functional UIs with Java 8 and Vaadin JavaOne2014

Returns a new stream by applying the given function to all elements of this stream. !

MapReturns a new stream consisting of the elements of this stream that match the given predicate.

Filter

SQL analogue: SELECT SQL analogue: WHERE

Page 35: Functional UIs with Java 8 and Vaadin JavaOne2014

Workout Tracker Example

!

!

!

private List<Workout> findByAge(int maxMonths) { List<Workout> result = new ArrayList<>(); for (Workout w : workouts) { if (w.monthAge() < maxMonths) { result.add(w); } } Collections.sort(result, new Comparator<Workout>() { @Override public int compare(Workout o1, Workout o2) { return o2.monthAge() - o1.monthAge(); } }); ! return result; }

!

!

!

private Stream<Workout> findByAge(int maxMonths) { return workouts.stream() .filter(w -> w.monthAge() < maxMonths) .sorted(Comparator.comparing(Workout::monthAge) .reversed()); }

Page 36: Functional UIs with Java 8 and Vaadin JavaOne2014

What is Functional Reactive Programming?

Page 37: Functional UIs with Java 8 and Vaadin JavaOne2014

Observable

Page 38: Functional UIs with Java 8 and Vaadin JavaOne2014

Consider a spreadsheet

Page 39: Functional UIs with Java 8 and Vaadin JavaOne2014

RxJava

Page 40: Functional UIs with Java 8 and Vaadin JavaOne2014

Quick peek at RxJava

Observable<String> letters = Observable.from(new String[] { "a", "b", "c" });

letters.subscribe(letter -> System.out.println("Got letter: " + letter));

Page 41: Functional UIs with Java 8 and Vaadin JavaOne2014

Power of Observables - composition

Observable<String> letters = Observable.from(new String[] { "a", “b", "c" }); Observable<Integer> numbers = Observable.from(new Integer[] { 1, 2, 3 });

Observable<String> pairs = Observable.combineLatest(letters, numbers, (l, n) -> { return "" + l + " -> " + n; }); !pairs.subscribe(pair -> System.out.println("Got pair: " + pair));

Page 42: Functional UIs with Java 8 and Vaadin JavaOne2014

RxVaadinwww.vaadin.com/blog/-/blogs/reactive-functional-ui-development-with-vaadin

Page 43: Functional UIs with Java 8 and Vaadin JavaOne2014

Rating to stars, reactive style!

Observable<String> activities = RxVaadin.valuesWithDefault(editor.activity, null); Observable<String> durations = RxVaadin.valuesWithDefault(editor.duration, ""); Observable<Date> dates = RxVaadin.valuesWithDefault(editor.date, editor.date.getValue()); Observable<String> calories = RxVaadin.valuesWithDefault(editor.calories, ""); Observable<String> avgHRs = RxVaadin.valuesWithDefault(editor.avgHR, ""); Observable<String> maxHRs = RxVaadin.valuesWithDefault(editor.maxHR, ""); Observable<String> comments = RxVaadin.valuesWithDefault(editor.comment, "");

Page 44: Functional UIs with Java 8 and Vaadin JavaOne2014

Composing the rating Observable

Observable<Integer> ratings = WorkoutRatingLogic.ratings(activities, durations, dates, calories, avgHRs, maxHRs, comments);

Observable<String> ratingStrings = ratings.map(rating -> { if (rating == null) { return "New Workout”; // No stars if required fields not ok } else { return IntStream.range(0, rating) .mapToObj(i -> FontAwesome.STAR.getHtml()) .collect(Collectors.joining("", "New Workout: ", "")); } });

Page 45: Functional UIs with Java 8 and Vaadin JavaOne2014

Last step: update the UI

// Have the label update its value whenever the Observable // emits a value RxVaadin.follow(editor.title, ratingStrings);

// Disable or enable the add button based on if the rating // calculation was successful or not ratings.subscribe(rating -> editor.add.setEnabled(rating != null));

Page 46: Functional UIs with Java 8 and Vaadin JavaOne2014

Summary

Page 47: Functional UIs with Java 8 and Vaadin JavaOne2014

The functional additions in Java 8 rock

Observables allow us avoid the “callback hell” with events

Vaadin works brilliantly with both

Page 48: Functional UIs with Java 8 and Vaadin JavaOne2014

Thank You! !

github.com/hezamu @henrimuurimaa

[email protected]

Page 49: Functional UIs with Java 8 and Vaadin JavaOne2014

!

Join us for a chat and drinks at the Vaadin Meetup

!

Hotel Serrano

Right now!