Tomasz Ducin

22nd November 2016, Warsaw

Tomasz Ducin

JavaScript, Java, Python

independent software consultant

trainer @ Bottega IT Solutions

blah, blah, blah...

<ng-enterprise>
  • private customer banking interface
  • 1+ year to go on production
  • deployed on 120+ Scandinavian banks

ARCHITECTURE

what is

  • how the application is structured

  • the toolstack used

  • all the design decisions
    you have to make

?

A REMAKE

  • re-implement everything
  • implement top 10 features,
    deliver 2 parallel apps
  • make old & new co-exist
    within 1 system

DEEPEST LAYER

DEEP LAYER

ANOTHER LAYER

//...
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<rich:panel header="RichFaces Greeter" style="width: 315px">
      <h:outputText value="Your name: " />
      <h:inputText value="#{user.name}" >
            <f:validateLength minimum="1" maximum="30" />
      </h:inputText>
      <a4j:commandButton value="Get greeting" reRender="greeting" />
      <h:panelGroup id="greeting" >
            <h:outputText value="Hello, " rendered="#{not empty user.name}" />
            <h:outputText value="#{user.name}" />






            <h:outputText value="!" rendered="#{not empty user.name}" />
      </h:panelGroup>
</rich:panel>
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<rich:panel header="RichFaces Greeter" style="width: 315px">
      <h:outputText value="Your name: " />
      <h:inputText value="#{user.name}" >
            <f:validateLength minimum="1" maximum="30" />
      </h:inputText>
      <a4j:commandButton value="Get greeting" reRender="greeting" />
      <h:panelGroup id="greeting" >
            <h:outputText value="Hello, " rendered="#{not empty user.name}" />
            <h:outputText value="#{user.name}" />






            <h:outputText value="!" rendered="#{not empty user.name}" />
      </h:panelGroup>
</rich:panel>
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<rich:panel header="RichFaces Greeter" style="width: 315px">
      <h:outputText value="Your name: " />
      <h:inputText value="#{user.name}" >
            <f:validateLength minimum="1" maximum="30" />
      </h:inputText>
      <a4j:commandButton value="Get greeting" reRender="greeting" />
      <h:panelGroup id="greeting" >
            <h:outputText value="Hello, " rendered="#{not empty user.name}" />
            <h:outputText value="#{user.name}" />






            <h:outputText value="!" rendered="#{not empty user.name}" />
      </h:panelGroup>
</rich:panel>
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<rich:panel header="RichFaces Greeter" style="width: 315px">
      <h:outputText value="Your name: " />
      <h:inputText value="#{user.name}" >
            <f:validateLength minimum="1" maximum="30" />
      </h:inputText>
      <a4j:commandButton value="Get greeting" reRender="greeting" />
      <h:panelGroup id="greeting" >
            <h:outputText value="Hello, " rendered="#{not empty user.name}" />
            <h:outputText value="#{user.name}" />






            <h:outputText value="!" rendered="#{not empty user.name}" />
      </h:panelGroup>
</rich:panel>
<main-component>
</main-component>
<comp2>
</comp2>
<comp3>
</comp3>

...

ONE BY ONE

DIRECTIVE

  • originally: reusable piece of logic
  • need to define:
    • the relationships
    • responsibility
    • communication

DECISIONS

when to make

?

  • as soon as you know
  • as late as possible

each decision reduces flexibility

each bad decision costs A LOT

each change costs

JAVASCRIPT FATIGUE

x

x

x

x

TOOLS

don't focus on

instead think about the

TOOLS

 PROBLEMS YOU SOLVE

ENTERPRISE

  • budget-driven development

  • big, distributed teams

  • backends being unavailable

  • BE changes force FE changes

  • BE needs to be implemented prior to FE

Fake HTTP backend implementation

when(method, url, [data], [headers])
  .respond(function(...){
    return [HTTP_STATUS, DATA, HEADERS];
  });
$httpBackend

~90%

actual development

FE-BE
sync

~10%

:

Frontend development
with Backend-less approach

Digest Cycle

click!

{{myVar}}
{{::myVar}}
<input ng-model="myVar">

FUTURE

  • remake is a big investment
  • how about Angular 2?

REMEMBER

if all you have is a hammer, everything looks like a nail

THANK YOU!

ng-enterprise

By Tomasz Ducin

ng-enterprise

presentation during ng-poland 2016 conference (@ngPolandConf)

  • 3,255