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

Ein Name ist ein Name und kein String

Embed Size (px)

DESCRIPTION

 

Citation preview

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