Vortrag auf der "Jax on tour" Konferenz, September 2012:
Wie können wir vermeiden, Architekturen zu entwickeln, die hochkomplex sind und Flexibilität an immer genau den Stellen eingebaut haben, an denen wir sie gerade nicht brauchen? In dieser Session beschäftigen wir uns damit, wie sich durch den „Lean Architecture“-Ansatz Systeme umsetzen lassen, die immer nur das absolut Notwendige und manchmal sogar noch weniger umsetzen und mithilfe von besonders kurzen Feedback-Schleifen so früh wie irgend möglich Erkenntnisse über das gewinnen, was wir ansonsten immer erst verspätet von frustrierten Anwendern zu hören bekommen.
3. Matthias Bohlen Coach für effektive Produktentwicklung
Der Spagat
Flexibilität bringt Geschäft
je flexibler eine Organisation auf den Markt
reagieren kann, desto mehr Geld verdient
sie
Flexibilität kostet Geld
Refactoring gibt es nicht kostenlos
insbesondere nicht auf Architekturebene
Spagat
nur so viel Architektur wie notwendig
aber auch so viel wie langfristig hinreichend
3
Donnerstag, 20. September 12
4. Matthias Bohlen Coach für effektive Produktentwicklung
Was ist Lean?
Denkprinzipien
1. Eliminiere Verschwendung
2. Verbessere Lernprozesse
3. Verzögere Entscheidungen
4. Liefere schnell
5. Baue Integrität ein
6. Ermächtige das Team
7. Sieh immer das Ganze!
Nach Mary Poppendieck
Donnerstag, 20. September 12
5. Matthias Bohlen Coach für effektive Produktentwicklung
Das Ziel von Lean
Wert schaffen ist die Hauptsache
Return on Investment
= (Wert - Kosten) / Investition
Wert: rauf
Kosten: runter
Investitionen: klein
5
Donnerstag, 20. September 12
6. Matthias Bohlen Coach für effektive Produktentwicklung
Was ist Agilität?
Agilisten schätzen...
Individuen und mehr als Prozesse und
Interaktionen Werkzeuge
Funktionierende mehr als umfassende
Software Dokumentation
Zusammenarbeit mit dem mehr als
Kunden Vertragsverhandlung
Reagieren auf mehr als Befolgen eines
Veränderung Plans
6
Donnerstag, 20. September 12
7. Wie kann eine
Softwarearchitektur
aussehen, die
Lean und Agilität
unterstützt?
Foto: Casey Hussein Bisson 7
Donnerstag, 20. September 12
8. Matthias Bohlen Coach für effektive Produktentwicklung
Was ist Softwarearchitektur?
Architektur ist die Menge von
Entscheidungen, von denen Sie
wünschten, Sie könnten sie früh im
Projekt richtig treffen (aber bei denen
die Wahrscheinlichkeit, sie richtig zu
treffen, nicht notwendigerweise größer
ist als bei jeder anderen Entscheidung).
Ralph Johnson
8
Donnerstag, 20. September 12
9. Matthias Bohlen Coach für effektive Produktentwicklung
Mentales Modell des Benutzers
Repräsentation im Bewusstsein
★ entscheidende Domänenkonzepte
★ deren Beziehungen untereinander
★ Vorgänge, die auf diesen
Domänenkonzepten möglich sind
9
Donnerstag, 20. September 12
10. Matthias Bohlen Coach für effektive Produktentwicklung
Verständliche Architektur
sollte das mentale Modell des Benutzers
wiederspiegeln
Das System sollte sich so verhalten, wie
der Benutzer es erwartet
Die Architektur scheint immer durch, da
kann die Oberfläche so gut sein wie sie
will!
10
Donnerstag, 20. September 12
11. Matthias Bohlen Coach für effektive Produktentwicklung
Tony Hoare, 1980
"Es gibt zwei Wege, ein Software-
Design zu konstruieren:
• so simpel, dass es offensichtlich
keine Schwächen hat
• so kompliziert, dass es keine
offensichtlichen Schwächen hat.
Die erste Methode ist weitaus
schwieriger."
11
Donnerstag, 20. September 12
12. Struktur stützt Form
Form versus Struktur Form ermöglicht Verhalten
12
Donnerstag, 20. September 12
13. Struktur stützt Form
Form versus Struktur Form ermöglicht Verhalten
12
Donnerstag, 20. September 12
14. Struktur stützt Form
Form versus Struktur Form ermöglicht Verhalten
12
Donnerstag, 20. September 12
15. Struktur stützt Form
Form versus Struktur Form ermöglicht Verhalten
12
Donnerstag, 20. September 12
16. Form
"Essenz" der Struktur
wahrnehmbar, interessant
wertliefernd
konstant
Foto: Maik Maid
13
Donnerstag, 20. September 12
17. Struktur
notwendig für die Form
wahrnehmbar, doch weniger interessant
Kosten erzeugend
stabil
Foto: Ralph Aichinger
14
Donnerstag, 20. September 12
18. Verhalten
das, was in der Form passieren kann
interessant
Nutzen stiftend
variabel, flexibel
Foto: Benjamin Thompson
15
Donnerstag, 20. September 12
19. Form Struktur Verhalten
Essenz der Stütze der was in der
Struktur Form Form passiert
wahrnehmbar notwendig interessant
Wert Kosten Nutzen
liefernd erzeugend stiftend
konstant stabil variabel
16
Donnerstag, 20. September 12
20. Form Struktur Verhalten
Essenz der Stütze der was in der
n
Struktur Form Form passiert
wahrnehmbar notwendig interessant
lea
Wert Kosten Nutzen
liefernd erzeugend stiftend
konstant stabil variabel
16
Donnerstag, 20. September 12
21. Form Struktur Verhalten
Essenz der Stütze der was in der
n
Struktur Form Form passiert
il
wahrnehmbar notwendig interessant
lea
ag
Wert Kosten Nutzen
liefernd erzeugend stiftend
konstant stabil variabel
16
Donnerstag, 20. September 12
22. Architektur ermittelt Benutzertätigkeiten
Rollen, Aufzeichnungen
zwei Formen Endbenutzer
User Experience Leute
Interface Designer
Wa Sich ständig ändernde
sd Funktionalität
Wa as
sd Sy
as ste
Sy m
Benutzergedanken ste tu
m t
Klassen und Objekte ist
Domänenexperten
Architekten
Datenbankschemata
Langzeitstabile Struktur
17
Donnerstag, 20. September 12
23. Was das System ist
Subsysteme
Form Interfaces, APIs
Domänenobjekte
Module
Struktur Pakete
Klassen
18
Donnerstag, 20. September 12
24. Was das System tut
Use Case
Form Kontext
Methodenfreie Rollen
Methodenreiche Rollen
Struktur
Algorithmen
19
Donnerstag, 20. September 12
25. Matthias Bohlen Coach für effektive Produktentwicklung
Mit der Form beginnen
Fragen Sie die Stakeholder
Analysieren Sie die Form des Systems
Partitionierung nach Gemeinsamkeit und Veränderlichkeit
Wählen Sie einen Entwurfsstil
meistens ist das Objektorientierung
Gießen Sie die Form in Code
Form als abstrakte Basisklassen und methodenfreie Rollen
Lassen Sie die Entwicklerteams die Struktur und das
Verhalten entwerfen
20
Donnerstag, 20. September 12
26. Matthias Bohlen Coach für effektive Produktentwicklung
User Story
Als ein Kontoinhaber
möchte ich Geld überweisen
(von meinem Sparkonto auf mein Girokonto)
um etwas anzuschaffen
Wer? Akteur = Kontoinhaber
Was? Tätigkeit = Geld überweisen
Warum? Ziel = Anschaffung
21
Donnerstag, 20. September 12
27. Matthias Bohlen Coach für effektive Produktentwicklung
Use Case "Geld intern überweisen"
Schritt Akteur-Intention Systemverantwortung
1. Kontoinhaber wählt Bank zeigt Quellkonto, eine
Quellkonto und Liste von Zielkonten und ein
verlangt Überweisung Feld zur Eingabe des Betrags
2. Kontoinhaber wählt Bank zeigt
Zielkonto, gibt den Überweisungsinformationen
Betrag ein und (Quellkonto, Zielkonto,
bestätigt Datum, Betrag) und verlangt
eine TAN, um die
Überweisung zu legitimieren
3. Kontoinhaber gibt TAN Bank bewegt das Geld und
ein und bestätigt führt die Konten.
22
Donnerstag, 20. September 12
28. Matthias Bohlen Coach für effektive Produktentwicklung
Vom Use Case zur Technik
"Geld überweisen" ist etwas Fachliches
"Geld bewegen und Konten führen" ist
etwas eher Mechanisches
Letzteres nennen wir eine Gewohnheit.
Im Architekturteam finden wir eine Form
für diese Gewohnheit und überlassen es
dem Entwicklungsteam, die Struktur
dafür aufzubauen.
23
Donnerstag, 20. September 12
29. Matthias Bohlen Coach für effektive Produktentwicklung
Vom Was zum Wie
Schritt Geld bewegen und Konten führen
1. Bank verifiziert, dass genügend Geld da ist
2. Bank aktualisiert die Konten
3. Bank aktualisiert die Kontoauszüge
24
Donnerstag, 20. September 12
30. Matthias Bohlen Coach für effektive Produktentwicklung
Vom Was zum Wie
Schritt Geld bewegen und Konten führen
1. Bank verifiziert, dass genügend Geld da ist
Quellkonto
2. Bank aktualisiert die Konten
3. Bank aktualisiert die Kontoauszüge
24
Donnerstag, 20. September 12
31. Matthias Bohlen Coach für effektive Produktentwicklung
Vom Was zum Wie
Schritt Geld bewegen und Konten führen
1. Bank verifiziert, dass genügend Geld da ist
Quellkonto
2. Bank aktualisiert die Konten
Quellkonto und Zielkonto aktualisieren
ihre Stände.
3. Bank aktualisiert die Kontoauszüge
24
Donnerstag, 20. September 12
32. Matthias Bohlen Coach für effektive Produktentwicklung
Vom Was zum Wie
Schritt Geld bewegen und Konten führen
1. Bank verifiziert, dass genügend Geld da ist
Quellkonto
2. Bank aktualisiert die Konten
Quellkonto und Zielkonto aktualisieren
ihre Stände.
3. Bank aktualisiert die Kontoauszüge
Quellkonto
24
Donnerstag, 20. September 12
33. Matthias Bohlen Coach für effektive Produktentwicklung
Szenario in Algorithmus umwandeln
1.Quellkonto 1.Quellkonto verifiziert, dass sein Stand
verifiziert, größer ist als der Minimalstand plus
dass genügend Überweisungsbetrag und wirft eine
Geld da ist Exception, falls das nicht der Fall ist
2.Quellkonto 2.Quellkonto reduziert seinen Stand um den
und Zielkonto Überweisungsbetrag
aktualisieren 3.Quellkonto fordert Zielkonto auf, seinen
ihre Stände Stand zu erhöhen
3.Quellkonto 4.Quellkonto notiert auf seinem Kontoauszug,
aktualisiert dass dies eine Überweisung war
die 5.Quellkonto fordert Zielkonto auf, auf
Kontoauszüge seinem Kontoauszug eine Überweisung
einzutragen.
6.Quellkonto signalisiert Erfolg der
Überweisung.
25
Donnerstag, 20. September 12
34. Matthias Bohlen Coach für effektive Produktentwicklung
DCI: ein Architektur-Stil
D = Data
C = Context
I = Interaction
Daten (repräsentiert durch
Domänenobjekte) spielen interagierende
Rollen innerhalb eines Kontextes, der
dem Use Case entspricht.
Das soll man im Code auch so sehen
können!
26
Donnerstag, 20. September 12
35. Matthias Bohlen Coach für effektive Produktentwicklung
DCI ist wie eine Theateraufführung
Kontext: Geld bewegen und Konten führen
Quellkonto Zielkonto
Rolle
Objekt
Sparkonto Girokonto
27
Donnerstag, 20. September 12
36. Matthias Bohlen Coach für effektive Produktentwicklung
DCI Architekturmuster
Context 1 * Methodless Role
parameter1
parameter2
Domain class Methodful Role
<<instanceof>> <<mixin>>
Domain object in role
28
Donnerstag, 20. September 12
37. /**
* Domain class that captures the concept of a
* bank-internal account in general.
*/
class Account {
private Long balance = 0L
Long availableBalance() { balance }
def increaseBalance(amount) {
balance += amount
}
def decreaseBalance(amount) {
balance -= amount
}
def updateLog (msg, date, amount) {
println toString() + " Account: $msg, $date, $amount"
}
}
Daten
29
Donnerstag, 20. September 12
38. /**
* Domain class that captures the concept of a savings
* account.
*/
class SavingsAccount extends Account {
String toString() { "Savings" }
}
/**
* Domain class that captures the concept of a checking
* account.
*/
class CheckingAccount extends Account {
String toString() { "Checking" }
}
Daten
30
Donnerstag, 20. September 12
39. /**
* Methodless role that captures the form (interface)
* of one part of the Transfer behavior
*/
interface MoneySource {
def transferTo (Long amount, MoneySink recipient)
}
/**
* Methodless role that captures the form (interface)
* of the other part of the Transfer behavior
*/
interface MoneySink {
def transferFrom (Long amount, MoneySource source)
}
Methodenlose Rollen
31
Donnerstag, 20. September 12
40. /**
* Methodful role for the source account
* for the money transfer.
*/
class TransferMoneySource implements MoneySource {
def transferTo (Long amount, MoneySink recipient) {
// This code is reviewable and
// meaningfully testable with stubs!
if (availableBalance() < amount) {
throw new InsufficientFundsException()
}
else {
decreaseBalance (amount)
recipient.transferFrom (amount, this)
updateLog ("Transfer Out", new Date(), amount)
}
}
}
Methodenreiche Rolle
32
Donnerstag, 20. September 12
41. /**
* Methodful role for the recipient account
* for the money transfer.
*/
class TransferMoneySink implements MoneySink {
def transferFrom (Long amount, MoneySource source) {
increaseBalance (amount)
updateLog ("Transfer In", new Date(), amount)
}
}
Methodenreiche Rolle
33
Donnerstag, 20. September 12
42. /**
* Context of the "Transfer Money" use case.
*/
class TransferMoneyContext {
MoneySource source
MoneySink recipient
Long amount
def bindObjects() {
// find objects and assign to source & recipient.
// this would normally be a database lookup!
}
def doIt() {
source.transferTo (amount, recipient)
}
}
Kontext
34
Donnerstag, 20. September 12
43. // this is from class TransferMoneyContext...
MoneySource source
MoneySink recipient
def bindObjects() {
// this would normally be a database lookup!
def savings = new SavingsAccount()
savings.increaseBalance (1000L)
def checking = new CheckingAccount()
// now mix-in the roles of these objects
// so that each object gets the methods needed by
// the use case and by the other roles.
savings.metaClass.mixin TransferMoneySource
checking.metaClass.mixin TransferMoneySink
this.source = savings as MoneySource
this.recipient = checking as MoneySink
}
Objekte an Rollen binden (im Kontext)
35
Donnerstag, 20. September 12
44. // -------------------------------------------------------
// -- Test driver --
// -------------------------------------------------------
def testContext = new TransferMoneyContext()
testContext.amount = 200
testContext.bindObjects()
testContext.doIt()
assert 800 == testContext.source.availableBalance()
assert 200 == testContext.recipient.availableBalance()
Kleiner Testtreiber für den Use Case
36
Donnerstag, 20. September 12
45. Matthias Bohlen Coach für effektive Produktentwicklung
Anderer Stil: Atomic Events Architecture
In vielen Anwendungen sind Use Cases
tatsächlich Overkill
es geht um Events, die auf Objekte wirken
Problem:
Wenn man nicht aufpasst, designt man
Rollenmethoden ins Domänenobjekt hinein
Mischung von Aspekten mit unterschiedlicher
Änderungsrate bringt Ärger!
Lösung:
Rolle und Objekt auseinanderhalten!
37
Donnerstag, 20. September 12
46. Matthias Bohlen Coach für effektive Produktentwicklung
Beispiele für Atomic Events
Ein Buch in einen Einkaufswagen legen
Einem Rechteck eine neue Farbe geben
Doch Vorsicht:
Was ist mit Undo auf die Farbe des
Rechtecks?
Was ist, wenn mehrere Rechtecke
gleichzeitig eingefärbt werden sollen?
38
Donnerstag, 20. September 12
47. Wie kann man im Team an
der Architektur arbeiten?
Foto: Casey Hussein Bisson 39
Donnerstag, 20. September 12
48. Matthias Bohlen Coach für effektive Produktentwicklung
Agile Architekturrunde:
Gemeinsam sind wir Architekten !
Benutzer
Business Kunde
Architekt Designer
Fachbereich Domänen- Entwickler Programmierer
Analyst experte Tester
etc.
40
Donnerstag, 20. September 12
49. Matthias Bohlen Coach für effektive Produktentwicklung
Zusammenarbeit Architekturrunde
Delegation
Delegation
Saturn Architektur Neptun
Saturn-Backlog Neptun-Backlog
Saturn- Neptun-
Team Team
41
Donnerstag, 20. September 12
50. Form geht alle an!
Form ändert sich seltener als Struktur!
Was das System ist Was das System tut
Use Case
Subsysteme
Kontext
Form Interfaces, APIs
Methodenfreie
Domänenobjekte
Rollen
Module Methodenreiche
Struktur Pakete Rollen
Klassen Algorithmen
42
Donnerstag, 20. September 12
51. Form geht alle an!
Form ändert sich seltener als Struktur!
Was das System ist Was das System tut
Use Case
Subsysteme
Kontext
Form Interfaces, APIs
Methodenfreie
Domänenobjekte
Rollen
Module Methodenreiche
Struktur Pakete Rollen
Klassen Algorithmen
42
Donnerstag, 20. September 12
52. Form geht alle an!
Form ändert sich seltener als Struktur!
Was das System ist Was das System tut
Use Case
Subsysteme
Kontext
Form Interfaces, APIs
Methodenfreie
Domänenobjekte
Rollen
Module Methodenreiche
Struktur Pakete Rollen
Klassen Algorithmen
Daher: Im Architekturteam die Form aufbauen,
in den anderen Teams die Strukturen schaffen!
42
Donnerstag, 20. September 12
54. Matthias Bohlen Coach für effektive Produktentwicklung
Schlanke Architekturdokumentation
Aspekt Bedeutung Medien
Form Subsysteme, APIs, von Bilder und
außen sichtbares Vodcasts im Wiki,
Verhalten APIs im Code
Struktur Subsystem-interne Code
Klassen und
Schnittstellen
Verhalten wichtige Abläufe im Bilder im Wiki,
System den Rest im Code
Stil Entwurfsprinzipien Wiki
44
Donnerstag, 20. September 12
55. Matthias Bohlen Coach für effektive Produktentwicklung
Dokumentation
Querschnittskonzepte
Persistenz, Logging,
Transaktionsbehandlung, Authentifizierung,
Autorisierung, usw.
Design-Entscheidungen
Datum, Ausgangslage, Problemstellung,
gewählte/verworfene Optionen,
Entscheidungsweg/Begründung, Wiki
45
Donnerstag, 20. September 12
56. Plädiert der Bohlen jetzt
etwa für den Wasserfall?
Foto: Casey Hussein Bisson 46
Donnerstag, 20. September 12
57. Matthias Bohlen Coach für effektive Produktentwicklung
BDUF und YAGNI, die zwei Extreme
BDUF = Big Design Up Front
heute schon für morgen mitentwerfen
komplett mit allen Details
danach alles runtercodieren
Entwurf von heute unverändert lassen
YAGNI = You Aren't Gonna Need It
nur das entwerfen und codieren, was heute
gebraucht wird
sollte morgen etwas anderes gebraucht
werden, den Entwurf von heute ändern
47
Donnerstag, 20. September 12
58. Matthias Bohlen Coach für effektive Produktentwicklung
Annahmen hinter BDUF und YAGNI
BDUF:
je später wir ändern, desto teurer wird's
langes Nachdenken ist billiger als ändern
also Architektur vor Implementierung
YAGNI:
Änderungen sind einfach / kostengünstig
Ändern ist billiger als langes Nachdenken
also Architektur während Implementierung
48
Donnerstag, 20. September 12
59. Matthias Bohlen Coach für effektive Produktentwicklung
Mein Vorschlag: DBUF
DBUF = Design the Big things Up Front
Entwirf die "großen Sachen" (Form) vorher,
den Rest unterwegs
Was heißt eigentlich "teuer zu ändern"?
Form teurer als Struktur
Struktur teurer als Verhalten
Struktur basiert auf Form
Struktur schaffen ohne Form zu kennen,
bedeutet Nacharbeit und Verschwendung
49
Donnerstag, 20. September 12
60. Matthias Bohlen Coach für effektive Produktentwicklung
DBUF = Design Big things Up Front
Identifizieren Sie frühzeitig
die komprimierteste Darstellung (Form) von
dem, was das System ist
die komprimierteste Darstellung (Form) von
dem, was das System tut
Dann haben Sie eine gute Grundlage zum
Aufbau von Struktur
Bauen Sie die Struktur erst auf, wenn sie
gebraucht wird.
50
Donnerstag, 20. September 12
61. Matthias Bohlen Coach für effektive Produktentwicklung
Zusammen- Architektur besteht aus Form,
fassung Struktur und Stil
Sie sollte das mentale Modell des
Users widerspiegeln (Konzepte
und deren Verhalten)
Lean sind wir, indem wir die
Form "früh" richtig hinbekommen
Agil sind wir, indem wir innerhalb
dieser Form "spät" und "schnell"
Strukturen ändern und Verhalten
schaffen
51
Donnerstag, 20. September 12
62. Matthias Bohlen Coach für effektive Produktentwicklung
Literatur
James Coplien, Gertrud Bjornvig:
"Lean Architecture", Wiley & Sons 2010
Trygve Reenskaug:
http://folk.uio.no/trygver
"The Common Sense of Object Orientated
Programming"
http://folk.uio.no/trygver/2008/
commonsense.pdf
52
Donnerstag, 20. September 12
63. Matthias Bohlen Coach für effektive Produktentwicklung
Mehr Info? Hier melden!
Matthias Bohlen
Coach für effektive Produktentwicklung
Telefon: +49 170 772 8545
E-Mail: mbohlen@mbohlen.de
Web: http://www.mbohlen.de/
Twitter: @mbohlende
Donnerstag, 20. September 12