2. Who am I?
Arne Burmeister
■ geboren 1969 in Lübeck
■ Diplom TU-Berlin 1996
■ verheiratet, 2 Kinder
■ Taucher,
Motorradfahrer
■ Sun Certified Java Dev
■ Softwarearchitekt
3. Why?
Do you not see the logic of my plan?
■ Refactoring zum Durchreichen von Inputwerten?
■ Refactoring für Ablaufänderungen durch
geänderte Abhängigkeiten?
■ Weniger Refactoring in agiler Entwicklung!
4. What you get!
We still got the Mobius Inversion coming up.
■ Inversion of Control
■ Dependency Injection
■ Invert the Flow
■ Spaces und Factories
■ Vor- und Nachteile
5. Once upon a time …
Begin at the beginning
and go on till you come to the end: then stop
■ ein monolithisches Programm
■ Ablaufsteuerung legt Was, Wann und Wie fest
■ Abhängigkeiten müssen vorher bekannt sein
■ Implementierungen sind global oder werden im
Ablauf instanziiert
■ Zwischenergebnisse müssen gespeichert werden
■ Abhängigkeiten müssen bereitgestellt werden
6. Beispiel
Monolithisch
private static final BigDecimal G = new BigDecimal("6.67384E-11");
private static final BigDecimal AE = new BigDecimal("149597870691");
public static void main(String... args)
{
Sun sun = new Sun();
PlanetDto erde = new PlanetDto("Earth",
new BigDecimal("5.974E24"), 0.983, 1.017);
PlanetDto mars = new PlanetDto("Mars",
new BigDecimal("6.419E23"), 1.381, 1.666);
PlanetDto jupiter = new PlanetDto("Jupiter",
new BigDecimal("1.899E27"), 4.95, 5.46);
for (Planet planet : new Planet[] { erde, mars, jupiter }) {
double period = calculatePeriodInDays(sun, planet);
System.out.println(planet.getName() + ": " + period + " Tage");
}
}
public static double calculatePeriodInDays(Star sun, Planet planet)
{
double aInAe = (planet.getApohelInAe() + planet.getPerihelInAe()) / 2.0;
BigDecimal a = AE.multiply(new BigDecimal(aInAe));
BigDecimal z = new BigDecimal(Math.PI).pow(2)
.multiply(new BigDecimal(4)).multiply(a.pow(3));
BigDecimal n = G.multiply(sun.getMassInKg().add(planet.getMassInKg()));
double p = Math.sqrt(z.divide(n, 8, RoundingMode.HALF_UP).doubleValue());
return p / (60 * 60 * 24);
}
7. Inversion of Control
Don't call us, we'll call you!
■ Umkehrung der Ablaufsteuerung, keine zentrale
Steuerung des Programmflusses mehr
■ einzelne Funktionen statt einem monolithischem
Programm
■ Registrierung von Teilen, Steuerung
(Verknüpfung und Aufruf) durch Framework
■ keine Annahmen über das Verhalten des
restlichen Systems, Fokus auf die Funktion
8. Dependency Injection
A small step for a developer, one giant leap for development
■ Dependency Injection ist ein Teil von
Inversion of Control
■ Entkopplung der konkreten Implementierungen
■ Teile werden durch Container zum
Programmstart miteinander verbunden
■ das Wie wird entkoppelt
■ Komplexität wird reduziert
■ Testbarkeit wird verbessert
9. Beispiel
dependencies injected
public class Injected
implements ApplicationListener<ContextRefreshedEvent>
{
private OrbitalCalculator caculator;
private SolarSystem system;
public void onApplicationEvent(ContextRefreshedEvent event)
{
for (Planet planet : system.getPlanets()) {
double period = caculator.calculatePeriodInDays(
system.getStar(), planet);
System.out.println(planet.getName() + ": "
+ period + " Tage");
}
}
<beans xmlns="http://www.springframework.org/schema/beans">
<bean id="caculator" class="OrbitalCalculator"/>
<bean class="Injected">
<property name="system" ref="system"/>
<property name="caculator" ref="caculator"/>
</bean>
10. Inversion of Flow
The force will be with you
■ keine direkte Ablaufsteuerung
■ Ergebnisse „auf Zuruf“
■ Abhängigkeiten über pull statt push
■ Wann wird entkoppelt
■ es wird nur ausgeführt, was nötig ist
11. Space
Results at the end of the universe
■ Quelle aller Eingaben
■ Ablage aller Ergebnisse
■ Space enthält Key/Value Paare
■ Associative Memory mit Schlüssel über Typ und
Name
■ Kann persistent sein, muss aber nicht
■ „self populating“ durch Factories
12. Inversion of Flow
Key/Value Paare und Factories
Space Factory
verwaltet erzeugt
Key Value
Store speichert
13. Space
Where no developer has gone before
■ direkte Anfrage eines Ergebnisses
■ Anfrage löst Berechnung aus
■ initiale Befüllung möglich
■ Abhängigkeiten können Zwischenergebnisse sein
■ Abhängigkeiten müssen nicht vorhanden sein
■ Anfrage von Zwischenergebnisse lösen weitere
Berechnungen aus
■ Zwischenergebnisse werden automatisch
gespeichert
15. Value Factories
I need your magic
■ beinhaltete den Rest von Flow
■ berechnet fehlende Ergebnisse
■ kann Abhängigkeiten anfordern
■ minimale lokale Codeänderungen, wenn sich
Abhängigkeiten ändern
■ Factory kann Rechner oder externer Service sein
■ fehlende Ergebnisse ohne zuständige Factory
führen zu Fehlern
16. Beispiel
value production
public class OrbitFactory
extends AbstractValueFactory<String, Orbit>
{
private OrbitalCalculator calculator;
public OrbitFactory()
{
super(String.class, Orbit.class);
}
public Orbit createValue(Key<String, ? super Orbit> key, ValueSource tuples)
throws MissingKeyException
{
Star sun = tuples.get(singletonKey(Star.class));
Planet planet = tuples.get(Matchers.idKey(Planet.class, key.getId()));
Orbit orbit = new Orbit(sun, planet);
orbit.setPeriodInDays(calculator.calculatePeriodInDays(sun, planet));
return orbit;
}
public Set<Key<String, ? extends Orbit>> createValueKeys(
Matcher<? super Orbit> key, ValueSource tuples)
throws MissingKeyException
{
Set<Key<String, ? extends Orbit>> keys = new HashSet<...>();
for (Planet planet : tuples.getAll(typeMatcher(Planet.class))) {
keys.add(Matchers.idKey(Orbit.class, planet.getName()));
}
return keys;
}
}
17. Dependency Control
Time circuits on. Flux Capacitor... fluxxing.
■ Abhängigkeiten müssen überwacht werden
■ zyklische Abhängigkeiten führen zu Fehlern
■ Überschreiben von Ergebnissen entfernt
abhängige Ergebnisse
■ Zyklen können in Einzelfällen erlaubt sein
18. Multiple Universe
unlimited technology from the whole universe
■ Spaces können aufeinander aufbauen
■ Subspace kann manuell erzeugt werden
■ Value Factory kann Subspaces erzeugen und
anfragen
■ Schichten spiegeln sich in Hierarchie wider
20. Injection of Flow
He who controls the space, controls the universe!
■ Space und Store über Factory
■ Space bekommt Value Factories injected
■ Space bekommt Store über Factory injected
■ für hierarchische Spaces können Eltern an die
Factory gegeben werden
21. Space erverywhere?
Not the answer to life, the universe and everything
■ nur ein Paradigma, nicht für alle Fälle der
sinnvollste Ansatz!
■ Vorteile: Fokus auf Kernaufgabe,
wenig Refactoring notwendig, inhärenter Cache
■ Nachteile: Zusammenhänge unsichtbar,
mehr Integrationstests notwendig?
■ Ausblick: parallele Factoryaufrufe, verteilter
Space mit Cloud Storage
22. The Outer Space
The answer is out there
■ Robert C. Martin: „The Dependency Inversion
Principle“, 1996
■ Martin Fowler: „Inversion of Control Containers
and the Dependency Injection“, 2004
■ Jeremy Miller: „The Dependency Injection
Pattern – What is it and why do I care?“, 2005
■ „Associative Memory“, Cunningham &
Cunningham Wiki, 2005
■ Arne Burmeister: „deVasp“, Java-Net, 2011