+ All Categories
Home > Documents > Business vstechnology

Business vstechnology

Date post: 23-Jun-2015
Category:
Upload: open-knowledge-gmbh
View: 122 times
Download: 2 times
Share this document with a friend
81
@mobileLarson @_openKnowledge Lars Röwekamp | CIO New Technologies Mut zur Fachlichkeit
Transcript
Page 1: Business vstechnology

@mobileLarson @_openKnowledge

Lars Röwekamp | CIO New Technologies

Mut zur Fachlichkeit

Page 2: Business vstechnology

Business vs. Technology Mut zur Fachlichkeit

JAX2014

„May I submit my billing info to your merchant account via your payment

gateway?“

Page 3: Business vstechnology

Mut zur FachlichkeitJAX2014

End User

Domain Expert

TechnicalExpert

Business vs. Technology

Translationist auf Dauer teuer - sogar sehr teuer!

Page 4: Business vstechnology

Mut zur FachlichkeitJAX2014

End User

Domain Expert

TechnicalExpert

Ubiquitous Language

Basis für ein konsistentes

Domain Model

Business vs. Technology

Page 5: Business vstechnology

„Produce Software that makes perfectly sense to business,

not only to coder“

Mut zur FachlichkeitJAX2014

End User

Domain Expert

TechnicalExpert

Rich Domain Model

Business vs. Technology

Page 6: Business vstechnology

„Produce Software that is always

in a correct state, not only partially“

Mut zur FachlichkeitJAX2014

Domain Expert

TechnicalExpert

Rich Domain Model

Business vs. Technology

Access Layer

Business Layer

DB Layer

Page 7: Business vstechnology

Mut zur FachlichkeitReality CheckJAX

2014

Page 8: Business vstechnology

Mut zur FachlichkeitReality CheckJAX

2014

The déjà-vuExperiment

Page 9: Business vstechnology

/** * Represents a business customer with a * full qualified name, a date of birth indicating * if the customer is „sui juris“ and a valid address * that may change after a relocation. */ public class Customer { ! private String firstName; private String sureName; ! private Date birthDate; private Address address; ! public void setFirstName(String aFirstName) { ... } public String getFirstName() { return firstName; } ! public void setSureName(String aSureName) { ... } public String getSureName() { return sureName; } ! public void setBirthDate(Date birthDate) { ... } public Date getBirthDate() { return birthDate; } ! public void setAddress(Address address) { ... } public Address getAddress() { return address; } !}

Reality Check

Fachlichkeit?

JAX2014 Mut zur Fachlichkeit

Page 10: Business vstechnology

/** * Represents a business customer with a * full qualified name, a date of birth indicating * if the customer is „sui juris“ and a valid address * that may change after a relocation. */ public class Customer { ! public Customer(String firstName, String sureName, String zipCode, String city) { ... } ! public Customer(String firstName, String sureName, String zipCode, String city, String street) { ... } ... }

Reality Check

Parameter (Hölle)?

JAX2014 Mut zur Fachlichkeit

Konstruktor (Hölle)?

Page 11: Business vstechnology

/** * Represents a business customer with a * full qualified name, a date of birth indicating * if the customer is „sui juris“ and a valid address * that may change after a relocation. */ public class Customer { ! public Customer(String firstName, String sureName, String zipCode, String city) { Validate.isTrue(StringUtils.isNotEmpty(firstName)); Validate.isTrue(StringUtils.isNotEmpty(sureName)); ... } ! public void setFirstName(String firstName) { this.firstName = firstName; } !! ... }

Reality CheckJAX2014 Mut zur Fachlichkeit

Validierung?

Page 12: Business vstechnology

/** * Represents a business customer with a * full qualified name, a date of birth indicating * if the customer is „sui juris“ and a valid address * that may change after a relocation. */ public class Customer { ! private static final String ZCODE_PATTERN = ...; ! public Customer(String firstName, String sureName, String zipCode, String city) { setFirstName(firstName); setZipCode(zipCode); ... } ! public void setZipCode(String zipCode) { Validate.isTrue(Pattern.matches(ZCODE_PATTERN, zipCode)); } ! ... }

Reality CheckJAX2014 Mut zur Fachlichkeit

Richtig hier?

Page 13: Business vstechnology

/** * Represents a controller to handle * customer related changes */ public class CustomerController { !/** * save new date of birth retrieved from the web * in a customer entity */ public void alterBirthDate(Customer customer, String newDate) { ! SimpleDateFormat df = new SimpleDateFormat(); Date birthDate = null; try { birthDate = df.parse(newDate); } catch (ParseException e) { // do something } Date today = new Date(); ! if (birthDate.after(today)) { // do something } else { customer.setBirthDate(birthDate); } } ... }

Reality CheckJAX2014 Mut zur Fachlichkeit

Konvertierung?

Page 14: Business vstechnology

/** * Represents a controller to handle * customer related changes */ public class CustomerController { ! /** * check if a customer has birthday today */ public boolean hasBirthDay(Customer customer) { ! Calendar todayCal = Calendar.getInstance(); Calendar birthDateCal = Calendar.getInstance(); birthDate.setTime(customer.getBirthDate().getTime()); ! if (birthDateCal.get(Calendar.YEAR) > (todayCal.get(Calendar.YEAR))) { return false; } else if (birthDateCal.get(Calendar.MONTH) != (todayCal.get(Calendar.MONTH))) { return false; } else if (birthDateCal.get(Calendar.DAY_OF_MONTH) != (todayCal .get(Calendar.DAY_OF_MONTH))) { return false; } return true; } ... }

Reality CheckJAX2014 Mut zur Fachlichkeit

Auswertung?

Page 15: Business vstechnology

/** * Util to calculate current age for a given date * and to calculate if the date is a birthday today. */ public class BirthDayUtilAkaHelper { public static boolean hasBirthDay(Date date) { ... return ...; } public static int getAge(Date date) { return 0; } } !/** * usage of BirthdayUtil */ Customer customer = ...; if (BirthDayUtilAkaHelper.hasBirthDay(customer.getBirthDate())) { ...; }

Reality CheckJAX2014 Mut zur Fachlichkeit

Util & Helper (Hölle)?

Manager?

Page 16: Business vstechnology

/** * Represents a business customer with a * full qualified name, a date of birth indicating * if the customer is „sui juris“ and a valid address * that may change after a relocation. */ public class Customer { ! private Date birthDate; ! public void setBirthDate(Date newBirthDate) { if (isInFuture(newBirthDate)) { /*abort */ ... } birthDate = newBirthDate; } ! public Date getBirthDate() { return birthDate; } ... } !/** * usage of getBirthDate */ Customer customer = ...; customer.getBirthDate().setTime(someTimeInFuture);

Reality Check

Immutable?

JAX2014 Mut zur Fachlichkeit

Page 17: Business vstechnology

/** * Data Access Object for retrieving * customer objects from the DB. */ public class CustomerDao { ! public List<Customer> findByZipCodeOrCity(String zipCode, String city) { return ...; } ! public List<Customer> findByZipCodeOrCityWithLimit(String zipCode, String city, int limit) { return ...; } ! public List<Customer> findByZipCodeOrCityAndOrders(String zipCode, String city, int orderCount) { return ...; } } !/** * usage of getBirthDate */ String current= ...; String value = ...; List<Customer> searchResult = dao.findByZipCodeOrCity(current,value);

Reality Check

Meaningful API?

JAX2014 Mut zur Fachlichkeit

Correct Order?

Page 18: Business vstechnology

/** * Data Access Object for retrieving * customer objects from the DB. */ public class CustomerDao { // BEFORE refactoring public List<Customer> findByZipCodeOrCity(String zipCode, String city) { return ...; } ! // AFTER refactoring public List<Customer> findByZipCodeOrCity(String zipCode, String city, String street) { return ...; } ! ...; }

Reality Check

Refactoring?

JAX2014 Mut zur Fachlichkeit

Page 19: Business vstechnology

Mut zur FachlichkeitProblemfelderJAX

2014

Page 20: Business vstechnology

JAX2014

Anemic Domain Model !

„Pay most of the high cost of developing a Domain Model, but get little or none of the benefits.“

Mut zur FachlichkeitProblemfelder

(Vaugn Vernon, Implementing Domain-Driven Design)

Page 21: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Problemfelder

Anemic Domain Model !

‣ „kraftloses“ fachliche Objekte mit getter/setter ‣ eigentliche Fachlichkeit ausserhalb des Modells !

‣ Konsistenzprüfung ausserhalb ‣ Konvertierung ausserhalb ‣ Validierung ausserhalb

Page 22: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Problemfelder

Anemic Domain Model !

‣ forced by procedural programming mentality ‣ forced by oversimplified samples !

‣ forced by Tool-Support ‣ forced by generated Models ‣ forced by Specifications

Page 23: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Problemfelder

Anemic Domain Model

1980s 1991 1992-1995 1996/1997 1998+

Objekte gewinnen an Bedeutung dank C++ und Smalltalk

Visuelle Tools und IDEs werden „produktiv“ und verbreiten sich

„Explosion“ von Reflexion-basierten Tools und Frameworks

Visual Basic Properties und Property Sheets erscheinen

Release von Java JDK 1.0 und der JavaBeans Spezifikation

Page 24: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Problemfelder

Anemic Domain Model !

‣ Besitzt „Domain Model“ hauptsächlich getter/setter, kaum Business Logik undfungiert als Attribute-Holder? !

‣ Sitzt die Business Logik in den Nutzern des „Domain Models“ und ruft dort getter/setter auf?

Page 25: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Problemfelder

Null Value Handling !

‣ wird validiert? ‣ wann wird validiert? ‣ wie oft wird validiert? !

‣… und vor allem wo wird validiert? ‣… bitte nicht in den Use Cases!

Page 26: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Problemfelder

Duplicated Code !

‣ Konvertierung von Parametern ‣ Validierung von Parametern ‣ Validierung von Rückgabewerten

Page 27: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Problemfelder

Utils & Helper (und Manager und …) !

‣ Verlagerung des Problems ‣ Trennung von Fachlichkeit & Domain !

‣ Util Hell a.k.a. „Ach wir haben dafür ein Util?“ ‣ Code Duplication als Konsequenz

Page 28: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Problemfelder

Non-Meaningful APIs !

‣ String & Friends Parameter Hölle ‣ fehlende Typsicherheit !

‣Methodennamen als Parameter-Deskriptor ‣Methodennamen als Refactoring-Pitfall

Page 29: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Problemfelder

Fehlende Robustheit !

‣ Refactoring erhöht das Risiko für … ‣… Programmierfehler ‣… fehlerhafte API Methoden ‣… fehlerhafte API Dokumentation

Page 30: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Problemfelder

Fehlende Robustheit !

‣ Teamwachstum / -fluktuation als Risiko ‣Wo finde ich was? ‣Was macht das? ‣Wo gehört das hin? !

‣ Copy & Paste Design Pattern!

Page 31: Business vstechnology

Mut zur FachlichkeitLösungsansätzeJAX

2014

Page 32: Business vstechnology

JAX2014

Zur Erinnerung !

„Wir möchten ein sprechendes Domain Model, mit einem sprechenden API, welches wir in sich konsistent erzeugen und im weiteren Verlauf konsequent konsistent erhalten.“

Mut zur FachlichkeitLösungsansätze

Page 33: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Lösungsansätze

Anforderungen !

‣ sprechendes Modell ‣ sprechendes API !

‣ konsistent erzeugen ‣ konsistent erhalten

Page 34: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Lösungsansätze

Rich Domain Model !

‣ inkl. Fachlichkeit ‣ inkl. Validierung ‣ inkl. Konvertierung ‣ inkl. Normalisierung ‣ inkl. Konsistenzprüfung

Page 35: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Lösungsansätze

Refactoring Step by Step !

‣ Schritt 1: Value Objects ‣ Schritt 2: Builder Pattern ‣ Schritt 3: Framework Support

Page 36: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Schritt 1: Value Objects

Page 37: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Schritt 1: Value Objects

Value Objects Definition !

‣ Ein Value Object repräsentiert eine fachlich relevante Eigenschaft des Domain Models.

Wo ist da die Grenze?

Page 38: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Schritt 1: Value Objects

Value Objects Definition !

‣ Ein Value Object repräsentiert eine fachlich relevante Eigenschaft des Domain Models.

Page 39: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Schritt 1: Value Objects

Value Objects … !

‣ #1: sind Objekte und keine primitive ‣ #2: sind unveränderbar ‣ #3: konvertieren fachlich ‣ #4: normalisieren fachlich ‣ #5: validieren fachlich ‣ #6: sind vollwertig und vergleichbar !

Page 40: Business vstechnology

/** * #1: Value Objects sind Objekte */ public class Customer { ! private Date birthDate; ! private DateOfBirth birthDate; ! ... !) !/** * Represents a date of birth */ public class DateOfBirth { ! private Date dateOfBirth; ! public boolean hasBirthDay() { return ...; } ! public int getCurrentAge() { return ...; } }

Schritt 1: Value Objects

Fachlichkeit!

JAX2014 Mut zur Fachlichkeit

Page 41: Business vstechnology

/** * #2: Value Objects sind unveränderbar */ public class DateOfBirth { ! private Date dateOfBirth; public DateOfBirth(Date date) { // do some validation here and // throw IllegalArgumentException if fail ...; this.dateOfBirth = date; } public Date getDate() { return new Date(dateOfBirth.getTime()); } ! public boolean hasBirthDay() { return ...; } ! public int getCurrentAge() { return ...; } !}

Schritt 1: Value Objects

Immutable!

JAX2014 Mut zur Fachlichkeit

Page 42: Business vstechnology

/** * #3: Value Objects konvertieren fachlich */ public class DateOfBirth { ! private Date dateOfBirth; public DateOfBirth(Date date) { // do some validation here and // throw IllegalArgumentException if fail ...; this.dateOfBirth = date; } public DateOfBirth(String date) { // create date of birth from "date" string with default pattern ...; ! } public DateOfBirth(String date, String pattern) { // create date of birth from "date" string with "pattern" ...; } ! ... !}

Schritt 1: Value Objects

Konvertieren!

JAX2014 Mut zur Fachlichkeit

Page 43: Business vstechnology

/** * #4: Value Objects normalisieren fachlich */ public class DateOfBirth { ! private Date dateOfBirth; public DateOfBirth(Date date) { // do some validation here and // throw IllegalArgumentException if fail ...; this.dateOfBirth = copyAndStripTimeStamp(date); } private Date copyAndStripTimeStamp(Date date) { // strip timestamp and copy result in a new Date object return ...; ! } ... !}

Schritt 1: Value Objects

Normalisieren!

JAX2014 Mut zur Fachlichkeit

Page 44: Business vstechnology

/** * #4: Value Objects validieren fachlich */ public class DateOfBirth { ! private Date dateOfBirth; public DateOfBirth(Date date) { Date today = new Date(); if (date.after(today)) { throw new IllegalArgumentException("Birthday " + date + " may not be after current time " + today); } this.dateOfBirth = copyAndStripTimeStamp(date); } private Date copyAndStripTimeStamp(Date date) { // strip timestamp and copy result in a new Date object return ...; ! } ... !}

Schritt 1: Value Objects

Validieren!

JAX2014 Mut zur Fachlichkeit

Page 45: Business vstechnology

/** * #4: Value Objects sind vollwertig */ public class DateOfBirth implements Serializable, Comparable{ ! private Date dateOfBirth; ... ! @Override public String toString() { return ...; } ! @Override public int hashCode() { return ...; } ! @Override public boolean equals(Object obj) { return ...; } ! public int compareTo(Object o) { return ...; }}

Schritt 1: Value Objects

Full blown Object!

JAX2014 Mut zur Fachlichkeit

Page 46: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Schritt 1: Value Objects

Value Objects Beispiele !

‣ FirstName, LastName, DateOfBirth ‣ ZipCode, City, Country ‣ Email, PhoneNumber ‣ Note, Description ‣ Year, Month, … !

‣Money, …

Page 47: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Schritt 1: Value Objects

Value Objects Benefits !

‣ Fachlichkeit befindet sich direkt in der Domain ‣ Kein/kaum duplizierter Code !

‣ sprechender & konsistenter Code ‣ verbesserter Lesbarkeit & Wartbarkeit !

‣ Keine Util, Helper, Manager & Friends

Page 48: Business vstechnology

// Entity with Value Objects public class Customer { private FirstName firstName; private LastName lastName; private FamilyStatus familyStatus; private Address postalAddress; private HashMap<PhoneNumber> phoneNumbers; private HashMap<EmailAddress> emailAddresses; ... public void changePersonalName(FirstName newFirstName, LastName newLastName) { ... } public void relocatePostalAddress(Address changedPostalAddress) { ... } public void changeHomePhoneNumber(PhoneNumber changedHomePhoneNumber) { ... } public void disconnectHomePhone() { ...} public void changeMobilePhoneNumber(PhoneNumber changedHomePhoneNumber) { ... } public void disconnectMobilePhone() { ... } public void changePrimaryEmailAddress(EmailAddress newPrimaryEmailAddress) { ... } public void changeSecondaryEmailAddress(EmailAddress newSecondaryEmailAddress) { ... } ! public List<Email> findEmailsOf(EmailDomain emailDomain) { ... } ! public void marry(LastName newLastName) { lastName = newLastName familyStatus = FamilyStatus.MARRIED; } public boolean isMarried() { return (familyStatus == FamilyStatus.MARRIED); } }

Schritt 1: Value Objects JAX2014 Mut zur Fachlichkeit

Page 49: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Schritt 2: Builder Pattern

Page 50: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Schritt 2: Builder Pattern

Das kleine 1x1 des Builder Pattern !

‣ Object Creation Design Pattern ‣ Antwort auf das Constructor-Hell Anti-Pattern !

‣ Step-by-Step Ansatz ‣ Kandidat für Fluent-API

Page 51: Business vstechnology

// Builder Pattern - Poor Mans Edition public class Address { ! public Address(String street, String streetNumber, String zipCode, String city, String state, String country) { Validate.isTrue(StringUtils.isNotEmpty(streetNumber)); Validate.isTrue(StringUtils.isNotEmpty(zipCode)); Validate.isTrue(StringUtils.isNotEmpty(city)); Validate.isTrue(StringUtils.isNotEmpty(state)); Validate.isTrue(StringUtils.isNotEmpty(country)); ... } ! // value object is immutable // - no setter // - but getter ...; }

Schritt 2: Builder PatternJAX2014 Mut zur Fachlichkeit

Schön? Nee!

Page 52: Business vstechnology

// Builder Pattern - Simple Edition public class AddressBuilder { private Street street; private StreetNumber streetNumber; private ZipCode zipCode; private City city; private State state; private Country country; public Address build() { // validate single parameter and cross parameter constraints // and throw exception if any problem occurs ... // create valid Address object else return new Address(...); } public void setStreet(Street street) { this.street = street; } ! public void setStreetNumber(StreetNumber streetNumber) { this.streetNumber = streetNumber; } ! ... }

Schritt 2: Builder PatternJAX2014 Mut zur Fachlichkeit

Schöner? Naja!

Page 53: Business vstechnology

// Builder Pattern - Simple Edition IN ACTION !// create AddressBuilder AddressBuilder builder = new AddressBuilder(); !// set all known values // BTW: could be also used in JSF and other frameworks builder.setStreet(...); builder.setStreetNumber(...); builder.setZipCode(...); builder.setCity(...); builder.setState(...); builder.setCountry(...); !// build valid and immutable Address object Address address = builder.build();

Schritt 2: Builder PatternJAX2014 Mut zur Fachlichkeit

Page 54: Business vstechnology

// Builder Pattern - Extended Edition public class AddressBuilder { private Street street; private StreetNumber streetNumber; ... private AddressBuilder() { /* empty constructor to prohibit use */ } public static AddressBuilder newAddress() { return new AddressBuilder(); } public AddressBuilder forStreetNumber(StreetNumber aStreetNumber) { streetNumber = aStreetNumber; } public AddressBuilder ofStreet(Street aStreet) { street = aStreet; } public Address build() { // validate single parameter and cross parameter constraints // and throw exception if any problem occurs ... // create valid Address object else return new Address(...); } }

Schritt 2: Builder PatternJAX2014 Mut zur Fachlichkeit

Schöner? Ja!

Page 55: Business vstechnology

// Builder Pattern - Extended Edition IN ACTION !// create AddressBuilder AddressBuilder builder = newAddress() ! // set values .forStreetNumber(...).ofStreet(...) .inCity(...).withZipCode(...) .lyingInState(...).ofCountry(...) ! // build Address object .build(...);

Schritt 2: Builder PatternJAX2014 Mut zur Fachlichkeit

Page 56: Business vstechnology

// Builder Pattern - Extended Edition with Inner Class Builder public class Address { ! public static Builder newAddress() { return new Address().new Builder(); } ! private String street; ! public class Builder { ! public Builder ofStreet(String initialStreet) { street = validateStreet(initialStreet); return this; } ! public Address build() { validate(); return Address.this; } } }

Schritt 2: Builder PatternJAX2014 Mut zur Fachlichkeit

Page 57: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Schritt 3: Framework Support

Page 58: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Schritt 3: Framework Support

JSF?Access Layer

Business Layer

DB Layer JPA?

jUnit?

Page 59: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Value Objects & JPA !

‣ Value Objects und Mapping ‣ Binding via @Embeddable / @Embedded ‣ Spaltendef. via @Column / @AttributeOverride ‣ Value Objects und JPA-QL ‣ Navigation bis zu primitiven Eigenschaften ‣ Value Objects und ResultSet ‣ via ScalarQueries

Schritt 3: Framework Support

Page 60: Business vstechnology

/** * Embeddable date of birth for (re)use in value objects */ @Embeddable public class DateOfBirth { ! @Column(name=“BIRTHDATE“) // use this or … private Date dateOfBirth; ! ... } !!/** * Customer entity making use of date of birth embeddable */ @Entity public class Customer { ! @Embedded @AttributeOverride(name=„dateOfBirth", // … this column=@Column(name=“CUST_BIRTHDATE“)) // … or both private DateOfBirth dateOfBirth; ! ... }

JAX2014 Mut zur Fachlichkeit

Schritt 3: Framework Support

Page 61: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Value Objects & JPA !

‣ Value Objects und JPA-QL ‣ Navigation bis zu Value Objects ‣ Navigation bis zu primitiven Eigenschaften

Schritt 3: Framework Support

Page 62: Business vstechnology

/** * Using JPA-QL and ValueObjects */ @Entity @Table(name = "TAB_USER", ...) @NamedQueries({ @NamedQuery(name = "User.findByEmail", query = "select u from User u where u.email = :email"), @NamedQuery(name = "User.findByEmailString", query = "select u from User u where u.email.value = :emailString“) }) public class User extends AbstractEntity { ! protected static final String EMAIL_COLUMN = "EMAIL"; ! @AttributeOverride(name = "value", column = @Column(name = EMAIL_COLUMN, unique = true, nullable = false)) private Email email; ! ... !}

JAX2014 Mut zur Fachlichkeit

Schritt 3: Framework Support

Page 63: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Value Objects & JPA !

‣ Value Objects und ResultSet ‣ via ScalarQueries

Schritt 3: Framework Support

Page 64: Business vstechnology

/** * Examples for ResultSets and ValueObjects (via ScalarQueries) */ public FullNameWithAddress findFullNameWithAddress(Email uniqueEmail) { TypedQuery<Object[]> query = em.createQuery( "SELECT c.name, c.address from Customer c "‚ + "WHERE u.email.value = :emailString"‚ Object[].class); query.setParameter("emailString", uniqueEmail.getAddress()); ! Object[] result = query.getSingleResult(); FullName fullName = (FullName) result[0]; Address address = (Address) result[1]; return new FullNameWithAddress(fullName, address); } !public List<FullNameWithAddress> findFullNamesWithAddress() { ! TypedQuery<FullNameWithAddress> query = em.createQuery( "SELECT " + " new de.openknowlede.FullNameWithAddress(c.name, c.address) " + " from Customer c", FullNameWithAddress.class ); return query.getResultList(); }

JAX2014 Mut zur Fachlichkeit

Schritt 3: Framework Support

Page 65: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Value Objects & JSF !

‣ Binding von Value Objects ‣ direkte Unterstützung durch U-EL ‣ Konvertierung von Value Objects ‣ via JSF Converter ‣ Validierung von Value Objects ‣ via JSF Validator

Schritt 3: Framework Support

Page 66: Business vstechnology

/** CDI based JSF Controller managing * user related input */ @Named("customerController") @RequestScoped public class CustomerController { private DateOfBirth dateOfBirth; private ZipCode zipCode; ...; public DateOfBirth getDateOfBirth() { return dateOfBirth; } ! public void setDateOfBirth(DateOfBirth newDateOfBirth) { dateOfBirth = newDateOfBirth; } public ZipCode getZipCode() { return zipCode; } ! public void setZipCode(ZipCode newZipCode) { zipCode = newZipCode; } ... }

JAX2014 Mut zur Fachlichkeit

Schritt 3: Framework Support

Page 67: Business vstechnology

<!-- Value Object binding in JSF xhtml page via Unified Expression Language & JSF Faces Converter --> !<!-- using JSF converter for Value Object of type ZipCode --> <h:outputText value=“#{customerController.zipCode}“ /> !<h:outputText value=“#{customerController.zipCode}“ > <f:converter converterId=“de.openknowledge.jsf.converter.ZipCodeConverter“ </h:outputText> !!<!-- using JSF converter for Value Object of type DateOfBirth --> <h:outputText value=“#{customerController.dateOfBirth}“ /> !<h:outputText value=“#{customerController.dateOfBirth}“ > <f:converter converterId=“de.openknowledge.jsf.converter.DateOfBirthConverter“ </h:outputText> !<!-- using JSF default converter for Date & Time objects --> <h:outputText value=“customerController.dateOfBirth.date“ > <f:convertDateTime locale=“DE“ dateStyle=“short“/> </h:outputText>

JAX2014 Mut zur Fachlichkeit

Schritt 3: Framework Support

Page 68: Business vstechnology

@FacesConverter(forClass = DateOfBirth.class, value = "de.openknowledge.jsf.converter.DateOfBirthConverter") public class DateOfBirthConverter implements Converter { // convert String input into Value Object @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { if (value == null) { return null; } return new DateOfBirth(value); } // convert Value Object into String @Override public String getAsString(FacesContext context, UIComponent component, Object value) { String string = null; // power point programming - not bullet proofed! if (value!=null) { string = value.toString(); } return string; } }

JAX2014 Mut zur Fachlichkeit

Schritt 3: Framework Support

Page 69: Business vstechnology

Mut zur FachlichkeitKritiker zu WortJAX

2014

Page 70: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Kritiker zu Wort

Das soll funktionieren? Das … !

‣… ist doch viel zu langsam! ‣… sind doch viel zu viele Klassen! ‣… ist doch viel zu aufwendig!

Page 71: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Kritiker zu Wort

Das ist doch viel zu langsam! !

‣ Java Objekterzeugung ist nicht mehr teuer ‣ Immutability unterstützt Garbage Collection ‣ Immutability unterstützt Inlining

Page 72: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Kritiker zu Wort

Das sind doch viel zu viele Klassen! !

‣ Domain Model erfordert mehr Vorarbeit ‣ Speedup kommt später im Projekt !

‣ deutlich bessere Verständnis für die Domain ‣ deutlich bessere Entwicklungsperformance !

‣ Basisklassen helfen

Page 73: Business vstechnology

/** * Abstract value object as a common base for all single value * value objects. */ public abstract class SimpleValueObject<T extends Comparable> implements Serializable, Comparable<SimpleValueObject<T>> { ! private T value; ! public SimpleValueObject(T aValue) { value = aValue; } ! protected T getValue() { return value; } ! public boolean equals(Object o) { return ...; } ! public int hashCode() { return ...; } ! public String toString() { return ...; } ! public int compareTo(SimpleValueObject<T> o) { return ...; } }

Kritiker zu WortJAX2014 Mut zur Fachlichkeit

Page 74: Business vstechnology

/** * Simple value object for first name using the * common base <code>SimpleValueObject</code> */ public class FirstName extends SimpleValueObject<String> { ! public FirstName(String aValue) { super(aValue); } ! public String getText() { return super.getValue(); } !}

Kritiker zu WortJAX2014 Mut zur Fachlichkeit

Page 75: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Kritiker zu Wort

Das ist doch in der Nutzung viel zu aufwendig! !

‣ komplexe Konstruktoren, da Typen statt „String“ ‣ komplexe API aufrufe, da Typen statt „String“!// Vorher Customer customer = new Customer(“Max“,“Mustermann“); !// Nacher Customer customer = new Customer(new FirstName(“Max“), new SureName(“Mustermann“);

Page 76: Business vstechnology

JAX2014 Mut zur Fachlichkeit

Kritiker zu Wort

Das ist doch viel zu aufwendig! !

‣ Problemfeld „Konstruktoren“ ‣ Builder Pattern ‣ Problemfeld „Systemgrenzen“ ‣ Frameworks entschärfen das Problem ‣ Problem „Unit Test“ ‣ zentralisierte Erzeugung von Testdaten

Page 77: Business vstechnology

Mut zur FachlichkeitFazitJAX

2014

Page 78: Business vstechnology

JAX2014

!!

„The Design is the Code, the Code is the Design.“

Mut zur FachlichkeitFazit

Page 79: Business vstechnology

JAX2014

„Muss ich denn jedes Mal den Code ändern, wenn

sich die Fachlichkeit ändert?“

Mut zur FachlichkeitFazit

Page 80: Business vstechnology

JAX2014

„Zur Hölle, ja! !

Wann denn bitte sonst?“

Mut zur FachlichkeitFazit

Page 81: Business vstechnology

@mobileLarson @_openKnowledge

Lars Röwekamp | CIO New Technologies

Mut zur Fachlichkeit

lohnt sich!


Recommended