Aplicaes web que permanecem: uma abordagem arquitetural Java que vai - - PowerPoint PPT Presentation

aplica es web que permanecem
SMART_READER_LITE
LIVE PREVIEW

Aplicaes web que permanecem: uma abordagem arquitetural Java que vai - - PowerPoint PPT Presentation

Aplicaes web que permanecem: uma abordagem arquitetural Java que vai alm do ltimo framework JS da moda Eder Ignatowicz Sr. Software Engineer Red Hat Qual arquitetura e frameworks para o backend? Java 9 modular, Reactive,


slide-1
SLIDE 1

Aplicações web que permanecem:

uma abordagem arquitetural Java que vai além do último framework JS da moda

Eder Ignatowicz

  • Sr. Software Engineer Red Hat
slide-2
SLIDE 2
slide-3
SLIDE 3

Qual arquitetura e frameworks para o backend?

slide-4
SLIDE 4

Java 9 modular, Reactive, Microservices, Vert.x Drools, Spring Boot, Zookeeper, Spark

slide-5
SLIDE 5

E o front-end?

slide-6
SLIDE 6
slide-7
SLIDE 7
slide-8
SLIDE 8
slide-9
SLIDE 9
slide-10
SLIDE 10

Desenvolvimento JavaScript é complexo

slide-11
SLIDE 11

Desenvolvimento JavaScript Web é complexo

slide-12
SLIDE 12

Desenvolvimento Web vai continuar sendo complexo

slide-13
SLIDE 13
slide-14
SLIDE 14
slide-15
SLIDE 15
slide-16
SLIDE 16

Qual stack web escolher?

slide-17
SLIDE 17

Qual a arquitetura mais viável para este problema?

slide-18
SLIDE 18

5 pilares:

Aplicação de Larga Escala Desenvolvedores full stack Integração com UX Life-Span de 5~10 anos Interoperabilidade

slide-19
SLIDE 19

5 pilares:

Aplicação de Larga Escala Desenvolvedores full stack Integração com UX Life-Span de 5~10 anos Interoperabilidade

slide-20
SLIDE 20

Aplicação de Larga Escala

1mi+ de linhas código web 5 produtos ~150 sub-projetos ~30 devs 7+ anos de base de código

slide-21
SLIDE 21

Aplicação de Larga Escala

Static Typing

slide-22
SLIDE 22

Aplicação de Larga Escala

Refactoring

slide-23
SLIDE 23
slide-24
SLIDE 24
slide-25
SLIDE 25

Aplicação de Larga Escala

Transpilers para JS

slide-26
SLIDE 26
slide-27
SLIDE 27

.java javac .class

slide-28
SLIDE 28
slide-29
SLIDE 29
slide-30
SLIDE 30
slide-31
SLIDE 31

GWT The Good Parts

slide-32
SLIDE 32

GWT GOOD PARTS

Java to JavaScript

slide-33
SLIDE 33

GWT GOOD PARTS

java.* emulation

slide-34
SLIDE 34

GWT GOOD PARTS

DOM APis

slide-35
SLIDE 35

GWT GOOD PARTS

Java 8 “client side"

slide-36
SLIDE 36

GWT GOOD PARTS

Dev Tools

slide-37
SLIDE 37
slide-38
SLIDE 38

GWT GOOD PARTS

JS Interop

slide-39
SLIDE 39

JS INTEROP - CONSUME

Java

@JsType(isNative = true) public abstract class JQuery { @JsMethod(namespace=GLOBAL) public native static JQuery $(String selector); public native JQuery css(String prop, String val); public native JQuery attr(String name, String val); }

Java

import static jquery.JQuery.$; // ... $("ul > li").css("color", "red").attr("data-level", "first");
slide-40
SLIDE 40

JS INTEROP - EXPOSE

Java

package foo; @JsType public class Dora { public boolean late = true; public Dora() {} public String auAu() { return "Hello QCon!";} }

JavaScript

var dora = new foo.Dora(); if (dora.late) { alert(dora.auAu()); }
slide-41
SLIDE 41

Aplicação de Larga Escala

Refactoring

slide-42
SLIDE 42

5 pilares:

Aplicação de Larga Escala Desenvolvedores full stack Integração com UX Life-Span de 5~10 anos Interoperabilidade

slide-43
SLIDE 43

Devs Full Stack

Desenvolvedores “end-to-end"

slide-44
SLIDE 44

Devs Full Stack

Shared Codebase

slide-45
SLIDE 45

Devs Full Stack

"Java EE” no browser

slide-46
SLIDE 46
slide-47
SLIDE 47

ERRAI CDI no Browser

slide-48
SLIDE 48

@Dependent public class ProjectsView { @Inject Document document; @Inject @DataField( "projects-view" ) Div view; @Inject @DataField( "new-project" ) Button newProject; @Inject @DataField( "projects-list" ) UnorderedList projectsList; @Inject Instance<ProjectItem> projects;

CDI NO BROWSER

slide-49
SLIDE 49 if (!filter.doFilter(event)) { if (event.kind().equals(StandardWatchEventKind.ENTRY_ADD)) { resourceAddedEvent.fire(buildEvent(ResourceAddedEvent.class, event).getK2()); } … }
slide-50
SLIDE 50

public void onNewFile(@Observes ResourceAddedEvent event) { Window.alert( "ResourceAddedEvent:" + event.getPath().toURI() + " ['" + event.getMessage() + “‘]"); }

slide-51
SLIDE 51
slide-52
SLIDE 52

Server

Browser Browser Browser Browser

Long Polling Web Sockets SSE

ERRAI BUS

slide-53
SLIDE 53

Devs Full Stack

Shared Programming Model

slide-54
SLIDE 54

5 pilares:

Aplicação de Larga Escala Desenvolvedores full stack Integração com UX Life-Span de 5~10 anos Interoperabilidade

slide-55
SLIDE 55 <form action="orderResult.jsp" method="POST"> <h3>Pizza Types</h3> <div> <ul> <% for ( Pizza pizza : pizzaTypes ) { %> <li> <input type="radio" name="pizzaTypeOptions" value="<%=pizza.getName()%>" checked /> <span class="pizzaType"><%=pizza.getName()%></span> <span class="pizzaPrice"><%=pizza.getPrice()%>$</span> </li> <% } %> </ul> </div> <h3>Size</h3> <ul> <li id="li_1"> <input id="pizza_size1" type="radio" name="pizzaSizeOptions" value="Small" checked/> <span class="pizzaSize">Small</span> <input id="pizza_size2" type="radio" name="pizzaSizeOptions" value="Medium"/> <span class="pizzaSize">Medium ( + 2$ )</span> <input id="pizza_size3" type="radio" name="pizzaSizeOptions" value="Large"/> <span class="pizzaSize">Large ( + 3$ )</span> </li> </ul> <h3>Extra Toppings</h3> <div class="section group"> <% for ( int j = 0; j < 3; j++ ) { %> <div class="col span_1_of_3"> <ul class="ul_2"> <% for ( int i = sliceSize * j; i < ( j + 1 ) * sliceSize; i++ ) { %> <li class="li_2"> <input type="checkbox" name="pizzaToppings" value="<%=pizzaToppings.get( i )%>"/> <%=pizzaToppings.get( i )%> </li> <% } if ( j == 0 && remainder > 0 ) { %> <li class="li_2"> <input type="checkbox" name="pizzaToppings" value="<%=pizzaToppings.get( pizzaToppings.size() - 2 )%>"/> <%=pizzaToppings.get( pizzaToppings.size() - 2 ) </li> <% } else if ( j == 1 && remainder > 1 ) { %> <li class="li_2"> <input type="checkbox" name="pizzaToppings" value="<%=pizzaToppings.get( pizzaToppings.size() - 1 )%>"/> <%=pizzaToppings.get( pizzaToppings.size() - 1 )%> </li> <% } %> </ul> </div> <% } %> </div> <h4>Each extra topping is 0.65$</h4> <input type="submit" value="Order"/> </form> ...
slide-56
SLIDE 56

<h1>{{title}}</h1> <h2>My favorite hero is: {{myHero}}</h2> <p>Heroes:</p> <ul> <li *ngFor="let hero of heroes"> {{ hero }} </li> </ul>

slide-57
SLIDE 57

<div> <ul class=“list-group" data-field="projects-list"> </ul> <button type="button" class="btn" data-field="new-project"> <i class="fa fa-plus"></i> New Project </button> </div>

slide-58
SLIDE 58

@Dependent @Templated public class ProjectsView { @Inject @DataField( "projects-view" ) Div view; @Inject @DataField( "new-project" ) Button newProject; @Inject @DataField( "projects-list" ) UnorderedList projectsList; }

ERRAI UI

slide-59
SLIDE 59
slide-60
SLIDE 60 <!-- Masthead --> <nav class="navbar navbar-default navbar-pf "> <div class="navbar-header "> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse-2"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a href="/" class="navbar-brand"> <img src="images/BPMSuite.svg" alt="JBoss BPM Suite" /> </a> </div> <div class="collapse navbar-collapse navbar-collapse-2"> <ul class="nav navbar-nav "><!-- navbar-iconic --> <li class="dropdown"> <a class="dropdown-toggle nav-item-iconic" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> Home <span class="caret"></span> </a> <ul class="dropdown-menu" aria-labelledby="dropdownMenu2"> <li><a href="#">Design</a></li> <li><a href="#">Processes &amp; Tasks</a></li> <li><a href="#">Runtime</a></li> <li><a href="#">Settings</a></li> </ul> </li> </ul> <ul class="nav navbar-nav navbar-right"> <li class="dropdown"> <a class="dropdown-toggle nav-item-iconic" id="notifications" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> <span title="Notifications" class="fa pficon-warning-triangle-o"></span> Messages: 0 </a> <div class="dropdown-menu infotip bottom-right"> <div class="arrow"></div> <ul class="list-group"> <li class="list-group-item"> <span class="i pficon pficon-info"></span> Modified Datasources ExampleDS </li> <li class="list-group-item"> <span class="i pficon pficon-info"></span> Error: System Failure </li> </ul> <div class="footer"> <a>Clear Messages</a> </div> </div> </li> <li class="dropdown"> <a class="dropdown-toggle nav-item-iconic" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> <span title="Username" class="fa pficon-user"></span> Brian Johnson <span class="caret"></span> </a> <ul class="dropdown-menu" aria-labelledby="dropdownMenu2"> <li><a href="#">Preferences</a></li> <li><a href="#">Logout</a></li> </ul> </li> </ul> </div> </nav> <div class="container-fluid kie-blank-slate"> <!-- blank state content --> <div class="blank-slate-pf row"> <div class="col-xs-12 col-lg-9" style="text-align:right;"><a href=""><span class="fa fa-gear"></span> Settings</a></div> <h1 id="welcome"> <!--<div style="float:right;"><a href=""><span class="fa fa-gear"></span> Settings</a></div>--> Welcome to <b>BPM Suite</b> </h1> <p> Business Process Management (BPM) Suite offers a set of flexible, process management tools that support the way you need to work. Select a BPM tool below to get started. </p> <div class="blank-slate-pf-secondary-action"> <div class="kie-hero-card" id="demo1">
slide-61
SLIDE 61
slide-62
SLIDE 62

Integração com UX

Deixe o HTML/CSS em paz

slide-63
SLIDE 63

5 pilares:

Aplicação de Larga Escala Desenvolvedores full stack Integração com UX Life-Span de 5~10 anos Interoperabilidade

slide-64
SLIDE 64
slide-65
SLIDE 65

Arquitetura

Hexagonal Architecture - Alistair Cockburn Onion Architecture - Jeffrey Palermo DCI - James Coplien e Trygve Reenskaug. BCE - Ivar Jacobson Clean Architecture - Robert C. Martin

slide-66
SLIDE 66

Princípios

Independente de Frameworks Testável Independente de UI Independente de Database Independente de Agentes Externos

slide-67
SLIDE 67
slide-68
SLIDE 68

"Architecture is about intent. We have made it about frameworks and details” Robert C. Martin

slide-69
SLIDE 69

UBERFIRE VFS

Use Cases VFS API Regular FS Clustering GIT FS

slide-70
SLIDE 70
slide-71
SLIDE 71

Qual framework Web escolher?

slide-72
SLIDE 72

Qual framework JS escolher?

slide-73
SLIDE 73 Escolha do framework JS Anos 1 2 3 4 5 6 Primeiro Release Perigo
slide-74
SLIDE 74

What’s next for Angular 1.x? "In all honesty, no one really knows what will happen"

https://toddmotto.com/future-of-angular-1-x

slide-75
SLIDE 75 1 2 3 4 5 6 Anos Entrega Escolha do Framework JS Curva de Aprendizado Projeto Encerrado
  • u a nova versão
não tem retrocompatibilidade Reescrita novo Framework JS Curva de Aprendizado Projeto Encerrado
  • u a nova versão
não tem retrocompatibilidade Reescrita novo Framework JS Curva de Aprendizado
slide-76
SLIDE 76

"A good architecture allows volatile decisions to be easily changed” Robert C. Martin

slide-77
SLIDE 77

E se eu tratasse a volatilidade dos frameworks JS como fato?

slide-78
SLIDE 78
slide-79
SLIDE 79
slide-80
SLIDE 80

Modelo de Programação Componentes:

  • Screen
  • Editors
  • Perspectives
  • Popups
slide-81
SLIDE 81

Modelo de Programação

LifeCycle:

  • OnStart
  • OnSave
  • IsDirty
  • OnClose
  • OnFocus
  • OnLostFocus
  • OnMayClose
  • OnReveal
slide-82
SLIDE 82

Perspective Editor Screen Screen

slide-83
SLIDE 83

Baseado em Contratos

Screen -> Interface WorkbenchScreenActivity Editor -> Interface WorkbenchEditorActivity Perspective -> Interface PerspectiveActivity

slide-84
SLIDE 84

Perspectives

Uberfire Lookup Perspective ERRAI CDI BEAN MANAGER Scan all Perspective Activity Implementations

GWT Perspective Adapter OLD GWT WIDGET ERRAI UI Perspective Adapter Plain HTML Errai UI
slide-85
SLIDE 85

Código de 7 anos atrás com GWT “old school"

slide-86
SLIDE 86

Código da semana passada HTML 5 canvas

slide-87
SLIDE 87

Live-Span de 5~10 anos

Trate a arquitetura Web com o mesmo respeito que você trata seu backend.

slide-88
SLIDE 88

5 pilares:

Aplicação de Larga Escala Desenvolvedores full stack Integração com UX Life-Span de 5~10 anos Interoperabilidade

slide-89
SLIDE 89 @WorkbenchPerspective(identifier = "HomePerspective", isDefault = true) @Templated public class HomePerspective implements IsElement { @Inject @DataField @WorkbenchPanel(parts = "MoodScreen?uber=fire&uber1=fire1") Div moodScreen; @Inject @DataField @WorkbenchPanel(parts = "HomeScreen?uber=fire") Div homeScreen; @Inject @DataField @WorkbenchPanel(parts = "AnotherScreen") Div anotherScreen; } @JsType public interface PerspectiveActivity{ PerspectiveDefinition getDefaultPerspectiveLayout(); @Override default String getName() { return getDefaultPerspectiveLayout().getName(); } boolean isDefault(); Menus getMenus(); ToolBar getToolBar(); }
slide-90
SLIDE 90
slide-91
SLIDE 91 function TodoCtrl($scope) { $scope.placeText = "MiscellaneousFeatures"; $scope.todos = [ {text: 'learn angular', done: true}, {text: 'build an angular app', done: false} ]; $scope.addTodo = function () { $scope.todos.push({text: $scope.todoText, done: false}); $scope.todoText = ''; }; $scope.remaining = function () { var count = 0; angular.forEach($scope.todos, function (todo) { count += todo.done ? 0 : 1; }); return count; }; $scope.archive = function () { var oldTodos = $scope.todos; $scope.todos = []; angular.forEach(oldTodos, function (todo) { if (!todo.done) { $scope.todos.push(todo); } }); }; $scope["goto"] = function () { $goToPlace($scope.placeText); }; } <div class="container-fluid" ng-controller="TodoCtrl"> <div class="row"> <div class="col-md-12"> <p class="pull-right" style="margin-top: 10px;">{{remaining()}} of {{todos.length}} remaining [ <a href="" ng-click="archive()">archive</a> ] </p> <h4>Todos</h4> <ul class="list-group"> <li class="list-group-item" ng-repeat="todo in todos"> <span class="done-{{todo.done}}">{{todo.text}}</span> <input class="pull-right" type="checkbox" ng-model="todo.done"> </li> </ul> </div> </div> <div class="row"> <div class="col-md-6"> <form class="form-inline" ng-submit="goto()"> <div class="form-group"> <input type="text" ng-model="placeText" size="30" class="form-control" placeholder="place to go"> <input class="btn btn-primary" type="submit" value="GoTo"> </div> </form> </div> <div class="col-md-6"> <form class="form-inline pull-right" ng-submit="addTodo()"> <div class="form-group"> <input type="text" ng-model="todoText" size="30" class="form-control" placeholder="add new todo here"> <input class="btn btn-primary" type="submit" value="Add"> </div> </form> </div> </div> </div> $registerPlugin({ id: "my_angular_js", type: "angularjs", templateUrl: "angular.sample.html", title: function () { return "angular " + Math.floor(Math.random() * 10); },
  • n_close: function () {
alert("this is a pure JS alert!"); } });
slide-92
SLIDE 92

Perspectives

Uberfire Lookup Perspective ERRAI CDI BEAN MANAGER Scan all Perspective Activity Implementations

GWT Perspective Adapter OLD GWT WIDGET ERRAI UI Perspective Adapter Plain HTML Errai UI Angular Perspective Adapter Angular native Perspective Any JS Perspective Adapter Any JS Framework
slide-93
SLIDE 93

Angular JS Screen

slide-94
SLIDE 94

Criação de Componentes em Runtime

slide-95
SLIDE 95
slide-96
SLIDE 96
slide-97
SLIDE 97

5 pilares:

Aplicação de Larga Escala Desenvolvedores full stack Integração com UX Life-Span de 5~10 anos Interoperabilidade

slide-98
SLIDE 98

Desenvolvimento Web é complexo

slide-99
SLIDE 99

Aplicações Web são parte da nossa arquitetura

slide-100
SLIDE 100

Princípios

Independente de Frameworks Testável Independente de UI Independente de Database Independente de Agentes Externos

slide-101
SLIDE 101

Arquitetura de software é exercício de trade-offs

slide-102
SLIDE 102

5 pilares:

Aplicação de Larga Escala Desenvolvedores full stack Integração com UX Life-Span de 5~10 anos Interoperabilidade

slide-103
SLIDE 103

Eder Ignatowicz @ederign

http:/ /bit.ly/5-pilares-web