goodbye crud hello maps! datenmodellierung in … · datenmodellierung in clojure michael sperber...

47
Goodbye CRUD Hello Maps! Datenmodellierung in Clojure Michael Sperber @sperbsen

Upload: hatuong

Post on 17-Sep-2018

219 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Goodbye CRUD Hello Maps! Datenmodellierung in Clojure

Michael Sperber@sperbsen

Page 2: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

• Individualsoftware• branchenunabhängig• Scala, Clojure, Erlang, Haskell, F#, Swift, Elixir,

OCaml• Schulungen, Coaching

www.active-group.defunktionale-programmierung.de

Page 3: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Objekte kapselnveränderlichen Zustand

public class Person {private Long id;private String firstName;private String lastName;private String street;private String suburb;private String state;private String postCode;private int version;private Set<Phone> phones = new HashSet<Phone>();

public void addPhone(Phone phone) {if (!getPhones().contains(phone)) {

getPhones().add(phone);}

}...

}

Page 4: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Getter & Setterpublic String getFirstName() {

return firstName;}

public void setFirstName(String firstName) {this.firstName = firstName;

}

public String getLastName() {return lastName;

}

public void setLastName(String lastName) {this.lastName = lastName;

}

Page 5: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Gleichheit@Overridepublic boolean equals(Object o) {

if (this == o)return true;

if (o == null || getClass() != o.getClass())return false;

Person person = (Person) o;if (firstName != null ?

!firstName.equals(person.firstName): person.firstName != null)

return false;...

}

Page 6: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Hash@Overridepublic int hashCode() {int result = id != null ? id.hashCode() : 0;

result = 31 * result + (firstName != null ? firstName.hashCode() : 0);result = 31 * result + (lastName != null ? lastName.hashCode() : 0);result = 31 * result + (street != null ? street.hashCode() : 0);result = 31 * result + (suburb != null ? suburb.hashCode() : 0);result = 31 * result + (state != null ? state.hashCode() : 0);result = 31 * result + (postCode != null ? postCode.hashCode() : 0);result = 31 * result + (phones != null ? phones.hashCode() : 0);return result;

}

Page 7: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

„Value Objects“

Page 8: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Warum?• als Schlüssel verwendbar• thread-sicher• einfache Unit-Tests• kein Copy-Konstruktor

keine clone-Methode

Page 9: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Eine Welt von Objekten

(© Trustees of the British Museum)

Page 10: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Imperative Programmierung

room1.exit(elephant)hallway.enter(elephant)hallway.exit(elephant)room2.enter(elephant)

Page 11: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Realität und Schnappschuss

Page 12: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

OOP vs. Zustand„Though OOP came from many motivations, two were central. ... [T]he small scale one was to find a more flexible version of assignment, and then to try to eliminate it altogether. “

Alan Kay, History of Smalltalk (1993)

Page 13: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Clojure(ns crud.core(:require[active.clojure.record :refer :all]))

(define-record-type Dillo(make-dillo alive? weight)dillo?[alive? dillo-alive?weight dillo-weight])

Konstruktor

Prädikat

Selektor

Page 14: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Konstruktor, Prädikat, Selektoren(def d1 (make-dillo true 10))=> #crud.core.Dillo{:alive? true, :weight 10}

(dillo? d1)=> true(dillo? 15)=> false

(dillo-alive? d1)=> true(dillo-weight d1)=> 10

Page 15: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Records(define-record-type Rattlesnake(make-rattlesnake thickness length)rattlesnake?[thickness rattlesnake-thicknesslength rattlesnake-length])

(define-record-type Mouse(make-mouse blood size)mouse?[blood mouse-bloodsize mouse-size])

Page 16: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Konstruktion(def h1

[(make-dillo true 10)(make-rattlesnake 5 100)(make-mouse 5 17)(make-rattlesnake 7 200)])

Page 17: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Funktion(defn run-over [a]

(cond(dillo? a)(make-dillo false (dillo-weight a))

(rattlesnake? a)(make-rattlesnake 0 (rattlesnake-length a))

(mouse? a)(make-mouse 0 (mouse-size a))))

Page 18: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Erweitern auf Listen(defn run-over-all [a]

(map run-over a))

Page 19: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Adressbuch(define-record-type Person(make-person first last addresses)person?[first person-get-firstlast person-get-lastaddresses person-get-addresses])

Page 20: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Beispiele(def mike-sperber

(make-person "Mike" "Sperber"{:home "Pappelweg":work "Hechinger Straße"}))

(def sabine-ferber(make-person "Sabine" "Ferber"

{:home "Pappelweg":work "Schwanenstraße"}))

Page 21: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Maps(def addresses

{:home "Pappelweg":work "Hechinger Straße"})

(assoc addresses :home "Lerchenweg")=> {:home "Lerchenweg",

:work "Hechinger Straße"}addresses=> {:home "Pappelweg",

:work "Hechinger Straße"}

Page 22: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Maps in Clojure

Page 23: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Sharing

Page 24: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Hochzeit(defn marry

[person-1 person-2](make-person

(person-get-first person-1)(person-get-last person-2)(person-get-addresses person-1)))

Page 25: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Hochzeit(marry mike-sperber

sabine-ferber)=>#crud.address_book.Person{:first "Mike",:last "Ferber",:addresses{:home "Pappelweg“:work "Hechinger Straße"}}

Page 26: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Umzug(defn move[person key to](make-person(person-get-first person)(person-get-last person)(assoc(person-get-addresses person) key to)))

Page 27: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Umzug(move mike-sperber

:home "Lerchenweg")=>#crud.address_book.Person{:first "Mike", :last "Sperber",:addresses{:home "Lerchenweg“:work "Hechinger Straße"}}

Page 28: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Linsen(ns crud.address-book(:require[active.clojure.record :refer :all][active.clojure.lens :as lens]))

Page 29: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Linse

Getter+

Setter

Page 30: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Personen mit Linsen(define-record-type Person(make-person first last addresses)person?[(first person-get-first

person-first)(last person-get-last

person-last)(addresses person-get-addresses

person-addresses)])

Page 31: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Linsen(lens/yank mike-sperber person-first)=> "Mike“(lens/shove mike-sperber person-last

“Sperber") =>#crud.address_book.Person{:first "Mike",:last “Sperber",:addresses {:home "Pappelweg“

:work "Hechinger Straße"}}

Page 32: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Hochzeit(defn marry

[person-1 person-2](lens/shove person-1 person-last

(lens/yank person-2 person-last)))

Page 33: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Umzug(defn move [person key to]

(lens/overhaul personperson-addresses(fn [old]

(lens/shove old key to))))

Page 34: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Linsen auf Maps(def addresses{:home "Pappelweg":work "Hechinger Straße"})

(lens/yank addresses :home)=> "Pappelweg"

(lens/shove addresses :home "Lerchenweg")=> {:home "Lerchenweg",

:work "Hechinger Straße"}

Page 35: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Linsen komponieren(defn move [person key to]

(lens/shove person(lens/>> person-addresses key)to))

Page 36: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Komposition(defn comb-yank [data l1 l2]

(yank (yank data l1) l2))(defn comb-shove [data v l1 l2]

(shove data l1(shove (yank data l1) l2 v)))

(defn >>[l1 l2](lens comb-yank comb-shove l1 l2))

Page 37: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Unveränderliche Daten in Java

„Machste Daten, veränderste einfach nicht.“(Dierk König)

Page 38: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Linsen in Javapublic class Lens<A, B> {

private final Function<A, B> getter;private final BiFunction<A, B, A> setter;

public Lens(Function<A, B> getter,BiFunction<A, B, A> setter) {

this.getter = getter;this.setter = setter;

}...

}

Page 39: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Linsen in Javapublic B yank(A target) {

return getter.apply(target);}

public A shove(A target, B value) {return setter.apply(target, value);

}

Page 40: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Linsen in Javapublic A overhaul(A oldValue,

Function<B, B> mapper) {B extracted = getter.apply(oldValue);B transformed = mapper.apply(extracted);return setter.apply(oldValue,

transformed);}

Page 41: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Kompositionpublic <C> Lens<A, C> compose(Lens<B, C> other) {

return new Lens<>((A a) ->

other.getter.apply(getter.apply(a)),(A a, C c) -> {

B b = getter.apply(a);B newB = other.set(b, c);return setter.apply(a, newB);

});

}

Page 42: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

„Datenbanken“

Quelle: tma.vn

Page 43: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Fakten vs. Zustand

27.1.2015: Eva -> Hans, 100€28.1.2015: Eva -> Fritz, 200€

29.1.2015: Hans -> Fritz, 100€...

Hans27.1.2015: 100€28.1.2015: 100€

29.1.2015: 0€...

Eva27.1.2015: -100€28.1.2015: -300€29.1.2015: -300€

...

Fritz27.1.2015: 0€

28.1.2015: 200€29.1.2015: 300€

...

Rohdaten abgeleiteteDaten

Hans

0€

Eva

-300€

Fritz

300€

Zustand/Cache

Page 44: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Datenbasis als Faktenspeicher

Fakten Veränderung = mehr Fakten

„Vera Mustermann hat Hans Exemplar am 21.5. 100€ überwiesen.“

„Vera Mustermanns Kontostand ist 1000€.“

Page 45: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Datomichttp://www.datomic.com/rationale.html

Page 46: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Unveränderliche Datenbanken• transaktionssicher• immer konsistent• Caching überall• Verteilung einfach• Synchronisation

Page 47: Goodbye CRUD Hello Maps! Datenmodellierung in … · Datenmodellierung in Clojure Michael Sperber @sperbsen •Individualsoftware •branchenunabhängig •Scala, Clojure, Erlang,

Zusammenfassung• unveränderlich ist besser• einfach mit Funktionen höherer Ordnung• z.B. mit Linsen• geht auch in Java