SlideShare ist ein Scribd-Unternehmen logo
Inversion of Flow


                  Arne Burmeister




© 2011                    digital   ergonomics
Who am I?
                Arne Burmeister


■ geboren 1969 in Lübeck
■ Diplom TU-Berlin 1996
■ verheiratet, 2 Kinder
■ Taucher,
 Motorradfahrer
■ Sun Certified Java Dev
■ Softwarearchitekt
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!
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
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
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);
}
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
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
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>
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
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
Inversion of Flow
 Key/Value Paare und Factories



  Space               Factory


      verwaltet           erzeugt


                  Key Value


  Store              speichert
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
Beispiel
work in space
     private SolarSystem system;
 private ValueSpace space;

 private void printOrbits() throws MissingKeyException
 {
   space.add(singletonKey(SolarSystem. class), system);
   for (Orbit orbit : space.getAll(typeMatcher(Orbit.class))) {
     System.out.println(orbit.getPlanet().getName() + ": "
           + orbit.getPeriodInDays() + " Tage");
   }
 }

 <bean id="caculator" class="OrbitalCalculator" />

<bean class="Inverted">
  <property name="space" ref="space" />
  <property name="system" ref="system" />
</bean>

 <bean id="space" class="DefaultValueSpaceFactoryBean">
   <property name="storeFactory">
     <bean class="MemoryStoreFactory" />
   </property>
   <property name="valueFactories">
     <list>
       <bean class="OrbitFactory">
         <property name="caculator" ref="caculator" />
       </bean>
       …
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
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;
    }
}
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
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
Beispiel
Hierarchische Spaces
     <bean id="system" class="SolarSystem">
     …
     </bean>

     <bean class="space" class="DefaultValueSpaceFactoryBean">
       <property name="parents">
         <list>
           <bean class="SpringValueSource" />
         </list>
       </property>
       <property name="storeFactory">
         <bean class="MemoryStoreFactory" />
       </property>
       <property name="valueFactories">
         <list>
           <bean class="OrbitFactory">
             <property name="caculator" ref="caculator" />
           </bean>
           <bean class="StarFromSystemFactory" />
           <bean class="PlanetsFromSystemFactory" />
         </list>
       </property>
     </bean>
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
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
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
Danke, Fragen?
http://arne.burmeister-teltow.de/

Weitere ähnliche Inhalte

PDF
Storytelling For The Web: Integrate Storytelling in your Design Process
PDF
Artificial Intelligence, Data and Competition – SCHREPEL – June 2024 OECD dis...
PDF
How to Leverage AI to Boost Employee Wellness - Lydia Di Francesco - SocialHR...
PDF
2024 Trend Updates: What Really Works In SEO & Content Marketing
PPTX
Mercurial Partners
PDF
Förderverein der Anne-Frank-Grundschule Teltow e.V.
PDF
2024 State of Marketing Report – by Hubspot
PDF
Everything You Need To Know About ChatGPT
Storytelling For The Web: Integrate Storytelling in your Design Process
Artificial Intelligence, Data and Competition – SCHREPEL – June 2024 OECD dis...
How to Leverage AI to Boost Employee Wellness - Lydia Di Francesco - SocialHR...
2024 Trend Updates: What Really Works In SEO & Content Marketing
Mercurial Partners
Förderverein der Anne-Frank-Grundschule Teltow e.V.
2024 State of Marketing Report – by Hubspot
Everything You Need To Know About ChatGPT
Anzeige

Inversion of flow

  • 1. Inversion of Flow Arne Burmeister © 2011 digital ergonomics
  • 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
  • 14. Beispiel work in space private SolarSystem system; private ValueSpace space; private void printOrbits() throws MissingKeyException { space.add(singletonKey(SolarSystem. class), system); for (Orbit orbit : space.getAll(typeMatcher(Orbit.class))) { System.out.println(orbit.getPlanet().getName() + ": " + orbit.getPeriodInDays() + " Tage"); } } <bean id="caculator" class="OrbitalCalculator" /> <bean class="Inverted"> <property name="space" ref="space" /> <property name="system" ref="system" /> </bean> <bean id="space" class="DefaultValueSpaceFactoryBean"> <property name="storeFactory"> <bean class="MemoryStoreFactory" /> </property> <property name="valueFactories"> <list> <bean class="OrbitFactory"> <property name="caculator" ref="caculator" /> </bean> …
  • 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
  • 19. Beispiel Hierarchische Spaces <bean id="system" class="SolarSystem"> … </bean> <bean class="space" class="DefaultValueSpaceFactoryBean"> <property name="parents"> <list> <bean class="SpringValueSource" /> </list> </property> <property name="storeFactory"> <bean class="MemoryStoreFactory" /> </property> <property name="valueFactories"> <list> <bean class="OrbitFactory"> <property name="caculator" ref="caculator" /> </bean> <bean class="StarFromSystemFactory" /> <bean class="PlanetsFromSystemFactory" /> </list> </property> </bean>
  • 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