Ein Name ist ein Name und kein String

Post on 22-Nov-2014

1.260 views 2 download

description

 

Transcript of Ein Name ist ein Name und kein String

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

EigenschaftCustomer?

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?

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?

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“ CodeList<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!

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

// NacherCustomer 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

@Embeddablepublic 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

@Embeddablepublic 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

@Namedpublic 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