Ein Name ist ein Name und kein String

66
Ein Name ist ein name und kein String Jens Schumann open knowledge GmbH

description

 

Transcript of Ein Name ist ein Name und kein String

Page 1: Ein Name ist ein Name und kein String

Ein Name ist ein name und kein String

Jens Schumann

open knowledge GmbH

Page 2: Ein Name ist ein Name und kein String

Ein Name ist ein name und kein String

In den nächsten 60 Minuten...

Page 3: Ein Name ist ein Name und kein String

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/

Page 4: Ein Name ist ein Name und kein String

Ein Name ist ein name und kein String

In den nächsten 60 Minuten...

Java und OO gehtJava und OO macht Spaß

Page 5: Ein Name ist ein Name und kein String

Ein Name ist ein name und kein String

Aber...

Page 6: Ein Name ist ein Name und kein String

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; ... }

Page 7: Ein Name ist ein Name und kein String

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; ... }

Page 8: Ein Name ist ein Name und kein String

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

Page 9: Ein Name ist ein Name und kein String

Ein Name ist ein name und kein String

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

Page 10: Ein Name ist ein Name und kein String

Ein Name ist ein name und kein String

Ist das alles?!

Page 11: Ein Name ist ein Name und kein String

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

Page 12: Ein Name ist ein Name und kein String

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?

Page 13: Ein Name ist ein Name und kein String

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?

Page 14: Ein Name ist ein Name und kein String

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!

Page 15: Ein Name ist ein Name und kein String

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)); ... } }

EigenschaftCustomer?

Page 16: Ein Name ist ein Name und kein String

As seen in the wild: Konvertierung

// Use Case: save new birthdate retrieved from webpublic 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?

Page 17: Ein Name ist ein Name und kein String

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 manuallyif (bdCal.get(Calendar.YEAR) >= todayCal.get(Calendar.YEAR)) { return false; }

if (...)...

Ist das OO?

Page 18: Ein Name ist ein Name und kein String

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?

Page 19: Ein Name ist ein Name und kein String

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?

Page 20: Ein Name ist ein Name und kein String

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

Page 21: Ein Name ist ein Name und kein String

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..!?

Page 22: Ein Name ist ein Name und kein String

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!

Page 23: Ein Name ist ein Name und kein String

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

Page 24: Ein Name ist ein Name und kein String

„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

Page 25: Ein Name ist ein Name und kein String

„OO in Java“ - Problemfelder

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

Cases

Page 26: Ein Name ist ein Name und kein String

„OO in Java“ - Problemfelder

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

Page 27: Ein Name ist ein Name und kein String

„OO in Java“ - Problemfelder

• Utils und Helper Inflation– Fachlichkeit und Domain sind weiterhin

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

• Duplicated Code

Page 28: Ein Name ist ein Name und kein String

„OO in Java“ - Problemfelder

• Keine „sprechenden“ Schnittstellen– Parameterhölle

• Strings, Strings, Strings

– Methodennamen beschreiben Parameter– Keine Typsicherheit

Page 29: Ein Name ist ein Name und kein String

„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?

Page 30: Ein Name ist ein Name und kein String

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

Page 31: Ein Name ist ein Name und kein String

OO in Java

Konvention:

Ein Value Object repräsentiert eine fachlich relevante Eigenschaft

des Domain Modells.

Page 32: Ein Name ist ein Name und kein String

OO in Java - Regeln

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

„primitiv“

public class Customer { private Date birthDate;

}

X

Page 33: Ein Name ist ein Name und kein String

OO in Java - Regeln

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

„primitiv“

public class Customer { private DateOfBirth dateOfBirth;

}

Page 34: Ein Name ist ein Name und kein String

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();}

Page 35: Ein Name ist ein Name und kein String

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()); }}

Page 36: Ein Name ist ein Name und kein String

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) {...} }

Page 37: Ein Name ist ein Name und kein String

OO in Java - Regeln

#4: Value Objects normalisieren

public class DateOfBirth { private Date birthDate;

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

}

Page 38: Ein Name ist ein Name und kein String

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); } ... } }

Page 39: Ein Name ist ein Name und kein String

OO in Java - Regeln

#6: Value Objects sind „vollwertig“ – Besitzen

• equals• hashCode• toString

– Implementieren in der Regel• Serializable• Comparable

Page 40: Ein Name ist ein Name und kein String

OO in Java - Regeln

Wo ist da die Grenze?

Page 41: Ein Name ist ein Name und kein String

OO in Java - Regeln

Zur Erinnerung:

Ein Value Object repräsentiert eine fachlich relevante

Eigenschaft des Domain Modells.

Page 42: Ein Name ist ein Name und kein String

OO in Java - Regeln

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

– Money,...

Page 43: Ein Name ist ein Name und kein String

OO in Java - Regeln

Konsequenzen

Page 44: Ein Name ist ein Name und kein String

True OO in Java - Konsequenzen

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

Normalisierung– Keine oder wenige Duplikate

• „Sprechender“ CodeList<Customer>

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

Page 45: Ein Name ist ein Name und kein String

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

Page 46: Ein Name ist ein Name und kein String

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

Page 47: Ein Name ist ein Name und kein String

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

Page 48: Ein Name ist ein Name und kein String

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) {...}

Page 49: Ein Name ist ein Name und kein String

True OO in Java

public class FirstName extends SimpleValueObject<String> { public FirstName(String aValue) { super(aValue); }

public String getText() { return super.getValue(); }}

Page 50: Ein Name ist ein Name und kein String

True OO in Java – was ein Quark!

• Da schreibt man sich die Finger wund!

// VorherCustomer customer = new Customer(“Max“,“Mustermann“);

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

Page 51: Ein Name ist ein Name und kein String

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

Page 52: Ein Name ist ein Name und kein String

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

Page 53: Ein Name ist ein Name und kein String

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

Page 54: Ein Name ist ein Name und kein String

True OO und JPA

• True OO und JPA Mapping

@Embeddablepublic class DateOfBirth { @Column(name=“BIRTHDATE“) private Date date;}

@Entity public class Customer {

@Embedded private DateOfBirth dateOfBirth; }

Page 55: Ein Name ist ein Name und kein String

True OO und JPA

• True OO und JPA AttributeOverrides

@Embeddablepublic class DateOfBirth { private Date date;}

@Entity public class Customer {

@Embedded @AttributeOverride(name=“date“, column=@Column(name=“BIRTHDATE“)) private DateOfBirth dateOfBirth; }

Page 56: Ein Name ist ein Name und kein String

True OO und JSF

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

• Konvertierung von Value Objects– JSF Konverter

Page 57: Ein Name ist ein Name und kein String

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>

Page 58: Ein Name ist ein Name und kein String

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); }}

Page 59: Ein Name ist ein Name und kein String

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 ""; }}

Page 60: Ein Name ist ein Name und kein String

True OO und JSF

• Java Services Faces und Konvertierung

@Namedpublic class CustomerController {

public DateOfBirth getDateOfBirth() {}

public void setDateofBirth(DateOfBirth dob) {}

}

Page 61: Ein Name ist ein Name und kein String

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

Page 62: Ein Name ist ein Name und kein String

True OO in Java - Migrationspfad

Ich starte aber nicht auf der grünen Wiese!

Page 63: Ein Name ist ein Name und kein String

True OO in Java - Migrationspfad

Refactoring ist dein Freund!

Page 64: Ein Name ist ein Name und kein String

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

Page 65: Ein Name ist ein Name und kein String

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

Page 66: Ein Name ist ein Name und kein String