Ein Name ist ein Name und kein String

Preview:

DESCRIPTION

Ist ein Geldbetrag vom Typ BigDecimal oder besser vom Typ Money? Ein Geburtstag? Date oder Birthday? Ein Vorname? String natürlich! Oder vielleicht doch Name? Interessanterweise wird in vielen Projekten die Verwendung einfacher Datentypen nie infrage gestellt. Zu selten, wie diese Session anhand von Java-SE-Beispielen und deren Verwendung in Java EE (JSF, JAX-WS/RS, JPA ...) eindrucksvoll zeigt.Speaker: Jens Schumann18.4.2012 | 16:15 - 17:15 Uhr | JAX, Mainz

Citation preview

Ein Name ist ein name und kein String

Jens Schumann

open knowledge GmbH

Ein Name ist ein name und kein String

In den nächsten 60 Minuten...

Ein Name ist ein name und kein String

In den nächsten 60 Minuten... ...gibt es nichts wesentlich Neues!

Bild via http://schnurpsel.de/neue-qualitaet-bei-kommentar-spam-oder-alter-hut-223/

Ein Name ist ein name und kein String

In den nächsten 60 Minuten...

Java und OO geht Java und OO macht Spaß

Ein Name ist ein name und kein String

Aber...

OO in Java – Ein Kunde public class Customer { private String firstName; private String sureName; private Date birthDate; private Address address; ... } public class Address { private String zipCode; private String city; ... }

OO in Java – eine Bestellung public class Order { private Customer customer; private String orderReference; private Date orderDate; private List<OrderEntry> entries; ... } public class OrderItem { private Item item; private double price; private int quantity; ... }

OO in Java – eine Bestellung public class Order { private Customer customer; private String orderReference; private Date orderDate; private List<OrderEntry> entries; ... } public class OrderItem { private Item item; private double price; private int quantity; ... }

URKS

Ein Name ist ein name und kein String

Was für ein Anfänger! Geldbeträge als double!

Ein Name ist ein name und kein String

Ist das alles?!

Ein Name ist ein name und kein String

•  Agenda –  „OO in Java“ - As seen in the wild –  „OO in Java“ - Problemfelder – True OO in Java – True OO in Java - was ein Quark! – True OO in Java und Frameworks – True OO in Java - Migrationspfad

As seen in the wild: Anemic Domain public class Customer { private String firstName; private String sureName; private Date birthDate; private Address address; public void setFirstName(String firstName){...} public String getFirstName(...) public void setSureName(String sureName){...} public String getSureName(...) }

Fachlichkeit?

As seen in the wild: Konstruktoren 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) {} }

Parameter?

As seen in the wild: Validierung public class Customer { public Customer(String firstName, String sureName, String zipCode, String city) { Validate.true(StringUtils.notEmpty(firstName)); Validate.true(StringUtils.notEmpty(sureName)); ... } public void setFirstName(String aFirstName) { firstName = aFirstName; } }

Ups!

As seen in the wild: Fachliche Validierung 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.true( Pattern.matches(ZCODE_PATTERN ,zipCode)); ... } }

Eigenschaft Customer?

As seen in the wild: Konvertierung // Use Case: save new birthdate retrieved from web public void alterBirthDate(Customer customer, String newDate) { SimpleDateFormat df = new SimpleDateFormat(); Date birthDate = df.parse(newDate); Date today = new Date(); if (birthDate.after(today)){ ... } else { customer.setBirthDate(birtDate); } }

Ist das OO?

As seen in the wild: Bewertung // has birthday today? Customer customer = ...; Calender todayCal = Calendar.getInstance(); Calender bdCal = Calendar.getInstance(); bdCal.setTime(customer.getBirthDate()); // validate year, month, date manually if (bdCal.get(Calendar.YEAR) >= todayCal.get(Calendar.YEAR)) { return false; } if (...) ...

Ist das OO?

As seen in the wild: Utils & Helper public class BirthDateUtil { public static boolean hasBirthday(Date date) { ... } public static int getAge(Date date) { ... } } Customer cus = ...; if (BirthDateUtil.hasBirthday(cus.getBirthDate()){ }

Ist das OO?

Das gibt es?

As seen in the wild: Immutability public class Customer { private Date birthDate; public void setBirthDate(Date newBirthDate) { if (isInFuture(newBirthDate)) {/* abort */} birthDate = newBirthDate; } public Date getBirthDate() { return birthDate; } } Customer cus = ...; cus.getBirthDate().setTime(...);

Validierung?

As seen in the wild: API - talk to me public class CustomerDao { public List<Customer> findByZipCodeOrCity( String zipCode, String city) {...} public List<Customer> findByZipCodeOrCityLimit( String zipCode, String city, int limit) {...} public List<Customer> findByZipCodeOrCityAndOrders( String zipCode, String city, int orderCount) {...}

URKS

As seen in the wild: API - talk to me public class CustomerDao { public List<Customer> findByZipCodeOrCity( String zipCode, String city) { } } public void searchMethod(...) { String current = ...; String value = ...; List<Customer> customers = dao.findByZipCodeOrCity(current, value); }

Hmmm..!?

As seen in the wild: API Refactoring // Before public List<Customer> findByZipCodeOrCity( String zipCode, String city) {... } // After public List<Customer> findByZipCodeOrCity( String zipCode, String city, String street) {... }

Zum Glück haben wir JavaDoc!

Ein Name ist ein name und kein String

•  Agenda –  „OO in Java“ - As seen in the wild –  „OO in Java“ - Problemfelder – True OO in Java – True OO in Java - was ein Quark! – True OO in Java und Frameworks – True OO in Java – Migrationspfad

„OO in Java“ - Problemfelder

•  Domain Objekte ohne Fachlichkeit – Anemic Domain

•  Fachliche Objekte sind Value Objects mit einfachen Setter/Getter Methoden

– Fachlichkeit lebt außerhalb •  Konvertierung von Eigenschaften •  Validierung von Eigenschaften •  Konsistenzprüfung

„OO in Java“ - Problemfelder

•  Null Value Value Handling – Null Value Handling erfolgt in den Use

Cases

„OO in Java“ - Problemfelder

•  Duplicated Code – Konvertierung von Parametern – Validierung von Parametern – Validierung von Rückgabewerten

„OO in Java“ - Problemfelder

•  Utils und Helper Inflation – Fachlichkeit und Domain sind weiterhin

getrennt –  „Ach wir haben dafür schon ein Util?“

•  Duplicated Code

„OO in Java“ - Problemfelder

•  Keine „sprechenden“ Schnittstellen – Parameterhölle

•  Strings, Strings, Strings

– Methodennamen beschreiben Parameter – Keine Typsicherheit

„OO in Java“ - Problemfelder

•  Robustheit – Refactoring erhöht Risiko

•  Programmierfehler •  Fehlerhafte API Methoden •  Fehlerhafte API Dokumentation

– Teamwachstum, Teamfluktuation •  Wo finde ich was? •  Wo gehört das hin?

Ein Name ist ein name und kein String

•  Agenda –  „OO in Java“ – As seen in the wild –  „OO in Java“ – Problemfelder – True OO in Java – True OO in Java - was ein Quark! – True OO in Java und Frameworks – True OO in Java – Migrationspfad

OO in Java

Konvention:

Ein Value Object repräsentiert

eine fachlich relevante Eigenschaft des Domain Modells.

OO in Java - Regeln

#1: Value Objects sind Objekte – Eigenschaften sind nur in Ausnahmefällen

„primitiv“ public class Customer { private Date birthDate; }

X

OO in Java - Regeln

#1: Value Objects sind Objekte – Eigenschaften sind nur in Ausnahmefällen

„primitiv“ public class Customer { private DateOfBirth dateOfBirth; }

OO in Java - Regeln

#1: Value Objects sind Objekte – Eigenschaften sind nur in Ausnahmefällen

„primitiv“ public class DateOfBirth { private Date birthDate; public boolean hasBirthDay(); public int getCurrentAge(); }

OO in Java - Regeln

#2: Value Objects sind immutable

public class DateOfBirth { private Date birthDate; public DateOfBirth(Date date) {...} public Date getDate() { return new Date(birthDate.getTime()); } }

OO in Java - Regeln

#3: Value Objects konvertieren

public class DateOfBirth { public DateOfBirth(Date date) {...} public DateOfBirth(String date) {...} public DateOfBirth(String date, String pattern) {...} }

OO in Java - Regeln

#4: Value Objects normalisieren

public class DateOfBirth { private Date birthDate; public DateOfBirth(Date date) { birthDate = copyAndStripTimestamp(date); } }

OO in Java - Regeln

#5: Value Objects validieren fachlich

public class DateOfBirth { public DateOfBirth(Date date) { Date today = new Date(); if (date.after(today)) { throw new IllegalArgumentException( “Birthday “ + date + “ may not before current time “ + today); } ... } }

OO in Java - Regeln

#6: Value Objects sind „vollwertig“ – Besitzen

•  equals •  hashCode •  toString

–  Implementieren in der Regel •  Serializable •  Comparable

OO in Java - Regeln

Wo ist da die Grenze?

OO in Java - Regeln

Zur Erinnerung:

Ein Value Object repräsentiert

eine fachlich relevante Eigenschaft des Domain Modells.

OO in Java - Regeln

•  Typische Value Objects – FirstName, LastName, DateOfBirth – ZipCode, City, Country – Email, PhoneNumber – Note, Description – Year, Month, ... – Money,...

OO in Java - Regeln

Konsequenzen

True OO in Java - Konsequenzen

•  Fachlichkeit befindet sich in der Domain –  Inkl. Konvertierung, Validierung,

Normalisierung – Keine oder wenige Duplikate

•  „Sprechender“ Code List<Customer>

find(ZipCode code, City city); •  No more *Util, No more *Helper

Ein Name ist ein name und kein String

•  Agenda – OO in Java – As seen in the wild – OO in Java – Problemfelder – True OO in Java – True OO in Java - was ein Quark! – True OO in Java und Frameworks – True OO in Java – Migrationspfad

True OO in Java – was ein Quark!

•  Das muss doch langsam sein!

•  Fakten: – Java Objekterzeugung ist sehr günstig –  Immutability unterstützt Garbage Collector –  Immutability unterstützt inlining

True OO in Java – was ein Quark!

•  Unsere Entwicklungsperformance! – Die Klassenexplosion! Nur unnützer Code!

•  Korrekt ist: – Domain Modell erfordert deutlich mehr

Vorarbeit – Speedup kommt im Projekt – Basisklassen helfen

True OO in Java public abstract class SimpleValueObject<T extends Comparable> implements Serializable, Comparable<SimpleValueObject<T>> { private T value; public SimpleValueObject(T aValue) {...} protected T getValue() {...} public boolean equals(Object o) {...} public int hashCode() {...} public String toString() {...} public int compareTo(SimpleValueObject<T>o) {...}

True OO in Java public class FirstName extends SimpleValueObject<String> { public FirstName(String aValue) { super(aValue); } public String getText() { return super.getValue(); } }

True OO in Java – was ein Quark!

•  Da schreibt man sich die Finger wund!

// Vorher Customer customer = new Customer(“Max“,“Mustermann“); // Nacher Customer customer = new Customer(new FirstName(“Max“), new SureName(“Mustermann“);

True OO in Java – was ein Quark!

•  Da schreibt man sich die Finger wund!

•  Fakten – Problem besteht an Systemgrenzen

•  Frameworks entschärfen Problem, dazu gleich mehr

– Problem besteht in Unit Tests •  Lösung: Erzeugung Testdaten zentralisieren

Ein Name ist ein name und kein String

•  Agenda – OO in Java – As seen in the wild – OO in Java – Problemfelder – True OO in Java – True OO in Java - was ein Quark! – True OO in Java und Frameworks – True OO in Java – Migrationspfad

True OO und JPA

•  Mapping von Value Objects – Binding via @Embeddable, @Embedded – Spaltendefinition über @Column oder

@AttributeOverride •  Value Objects und JPA-QL

– Navigation bis zu primitiven Eigenschaften •  Value Objects und Resultsets

– Nutzung in ScalarQueries

True OO und JPA

•  True OO und JPA Mapping

@Embeddable public class DateOfBirth { @Column(name=“BIRTHDATE“) private Date date; } @Entity public class Customer { @Embedded private DateOfBirth dateOfBirth; }

True OO und JPA

•  True OO und JPA AttributeOverrides

@Embeddable public class DateOfBirth { private Date date; } @Entity public class Customer { @Embedded @AttributeOverride(name=“date“, column=@Column(name=“BIRTHDATE“)) private DateOfBirth dateOfBirth; }

True OO und JSF

•  Binding von Value Objects – Direkte Unterstützung durch Unified EL

•  Konvertierung von Value Objects – JSF Konverter

True OO und JSF

•  Java Services Faces und GUI Binding

<h:outputText value=“#{customer.zipCode}“ /> <h:outputText value=“#{customer.dateOfBirth}“ /> <h:outputText value=“#{customer.dateOfBirth.date}“> <f:convertDateTime locale=“de" dateStyle="short" /> </h:outputText>

True OO und JSF

•  Java Services Faces und Konvertierung

@FacesConverter(forClass = DateOfBirth.class) public class DateOfBirthConverter implements Converter { public Object getAsObject(..., String s)... { if (s == null ) { return null; } return new DateOfBirth(s); } }

True OO und JSF

•  Java Services Faces und Konvertierung

@FacesConverter(forClass = DateOfBirth.class) public class DateOfBirthConverter implements Converter { public String getAsString(..., Object o) ...{ if (o != null) { return o.toString(); } return ""; } }

True OO und JSF

•  Java Services Faces und Konvertierung

@Named public class CustomerController { public DateOfBirth getDateOfBirth() {} public void setDateofBirth(DateOfBirth dob) {} }

Ein Name ist ein name und kein String

•  Agenda – OO in Java – As seen in the wild – OO in Java – Problemfelder – True OO in Java – True OO in Java - was ein Quark! – True OO in Java und Frameworks – True OO in Java – Migrationspfad

True OO in Java - Migrationspfad

Ich starte aber nicht auf der grünen Wiese!

True OO in Java - Migrationspfad

Refactoring ist dein Freund!

Ein Name ist ein name und kein String

•  Agenda – OO in Java – As seen in the wild – OO in Java – Problemfelder – True OO in Java – True OO in Java - was ein Quark! – True OO in Java und Frameworks – True OO in Java – Migrationspfad

Fazit

•  Fachlichkeit gehört IN Domain Modell –  „Primitive Datentypen“ vermeiden – Validierung, Konvertierung, Normalisierung

•  Einfache Kenngrößen beachten – Optimale Anzahl *Util: 0 ;) – Optimale Anzahl *Helper: 0 ;) – Optimale Länge Methodennamen: 20 ;)

•  Framework Features nutzen

Recommended