Hallo liebe Freunde des fluessigen,
ich schreibe diese Mail an alle, weil die Antwort vermutlich fuer viele interessant ist. Eigentlich richtet sich meine Frage an Ralf.
Ich habe noch recht gut die Begeisterung und Veraenderungen in Erinnerung, die durch Rod Johnsons Buch "Expert One-on-One J2EE Design and Development" ausgeloest wurden. Schliesslich ist dadurch ja auch die Firma SpringSource entstanden.
Meine (nicht ganz bescheidene) Hoffnung ist, dass das Buch von Ralf ueber Flow-Orientierung etwas aehnliches ausloesen koennte. Voraussetzung fuer einen derartigen Erfolg ist aber wohl, dass es (auch) eine englische Variante des Buches gibt.
Ist das geplant? Oder soll das Buch nur auf deutsch erscheinen?
Viele Gruesse
Ole
--
Martin-Luther-Platz 3 91054 Erlangen Tel.: 09131 / 975 97 90 Handy: 0170 / 241 6339
Hallo Ralf,
natürlich wäre ein FD buch auf englisch ne coole sache.noch cooler wärs allerdings, überhaupt erstmal eines zu haben.
der punkt, an dem ich mich gerieben habe, wo ich noch nicht klar bin: zustand.zustand in flows... da fühle ich mich noch nicht so wohl mit den bisherigen ansätzen. irgendwas fehlt noch.nicht privater zustand von funktionseinheiten. der ist ok und einfach.ich meine gemeinsamen zustand, shared state über funktionseinheiten hinweg.
den haben wir bisher als abhängigkeit modelliert. kann man machen. funktioniert durchaus.dann habe ich ihn mal als funktionseinheit im fluss modelliert. kann man auch machen. funktioniert ebenfalls.aber das ist alles "nur" pragmatische praxis. auch schön - doch es fehlt etwas, ein theoriegerüst dahinter.flow design im allgemeinen finde ich von theoretischer seite her gut untermauert.shared state im speziellen jedoch... nein, da hakt es noch. und ich vertraue meinem gefühl, dass das etwas bedeutet.da will noch etwas herausgearbeitet werden. darüber muss ich noch nachdenken. oder wir hier in der gruppe denken mal drüber nach.zur einstimmung kann jeder eine simple kata machen, z.b. die app kata questionnaire oder auch tic tac toe:oder einen kleinen taschenrechner.
überall kommt shared state vor. und der sollte natürlich nicht im UI oder einer DB gehalten werden.aber wie dann? gibt es ein muster? gibt es regeln, guidance?
ohne das thema noch besser herauszuarbeiten, lohnt ein FD buch nicht so recht.über pragmatische lösungen wie bisher möchte ich dafür hinaus sein.
Meinst Du wirklich gemeinsamen Zustand im Sinne einer gemeinsamen Konfiguration oder gemeinsamer globaler Daten?
Das hoert sich noch relativ einfach aber auch eher unnoetig an.Oder meinst Du vielleicht Zustand, wie manche boese Menschen ihn in einer serverseitigen Session aufheben?
Meinst Du wirklich gemeinsamen Zustand im Sinne einer gemeinsamen Konfiguration oder gemeinsamer globaler Daten?Das hoert sich noch relativ einfach aber auch eher unnoetig an.Oder meinst Du vielleicht Zustand, wie manche boese Menschen ihn in einer serverseitigen Session aufheben?Ich meine Daten, die innerhalb desselben Flusses oder in verschiedenen Flows benötigt werden.Und ich meine nicht unbedingt Web-Anwendungen. Sessions also kein spezielles Thema.
Nimm den Taschenrechner als Beispiel. Bei jeder Ziffer wird eine Zahl akkumuliert. Bei jedem Operator wird eine Berechnung mit dem Ergebnis der letzten durchgeführt. 2 Datenwerte sind da Zustand über Interaktionen hinweg.
Und diesen Zustand soll man in einem Cache halten? Kaum. Und selbst wenn: wie wird der Cache in die Flows gebracht? Als Abhängigkeit? Das ist ja meine Frage: In welcher Weise kommen Funktionseinheiten in einem Fluss an shared state?
Cache fuer simple Zahlen ist natuerlich Quatsch.
Aber wenn eine Funtionseinheit/Operation einen Cache gebrauchen kann, dann sollte sie damit initalisiert werden. Dann kann sie darin groessere Datenmengen zwischenspeichern und spaeter wieder heraushohlen.
Grundsaetzlich fliessen die Daten (shared state oder was auch immer) wunderbar in einem Fluss von einer Funktionseinheit zur anderen. Da hat man es doch eigentlich sehr einfach. Selbstverstaendlich sind da mal mehr Daten dabei als eine einzelne Operation braucht. Na und?
Fuer mich sieht es momentan nach einer Suche nach einer Theorie fuer ein nicht existentes Problem aus.
Grundsaetzlich fliessen die Daten (shared state oder was auch immer) wunderbar in einem Fluss von einer Funktionseinheit zur anderen. Da hat man es doch eigentlich sehr einfach. Selbstverstaendlich sind da mal mehr Daten dabei als eine einzelne Operation braucht. Na und?
Fuer mich sieht es momentan nach einer Suche nach einer Theorie fuer ein nicht existentes Problem aus.
Viele Gruesse
Ole
-- Martin-Luther-Platz 3 91054 Erlangen Tel.: 09131 / 975 97 90 Handy: 0170 / 241 6339
----- Ursprüngliche Nachricht -----
Von: Ralf Westphal
Gesendet: 02.03.12 13:07 Uhr
An: event-based...@googlegroups.com
Betreff: Re: Buch auf englisch?
Grundsaetzlich fliessen die Daten (shared state oder was auch immer) wunderbar in einem Fluss von einer Funktionseinheit zur anderen. Da hat man es doch eigentlich sehr einfach. Selbstverstaendlich sind da mal mehr Daten dabei als eine einzelne Operation braucht. Na und?das ist für mich ein entscheidenden "na und?". denn damit geht die wiederverwendbarkeit flöten.so sieht ein flow aus:-(x)-> F1(x, A) -(y)-> F2(y) -(z)-> F3(z, A)an den FEs ist notiert, welche daten sie brauchen. an den verbindungen steht, was fließt.F1 und F3 arbeiten auf denselben daten A. das ist shared state, denn A fließt nicht in den flow hinein. hinein kommt nur x.F2 ist konzentriert auf y.was du vorschlägst, sieht dann z.b. so aus:-(x)-> F1(x, A) -(y,A)-> F2(y, A) -(z,A)-> F3(z, A)plötzlich muss F2 auch noch etwas mit A tun und sei es nur, A durchzureichen. das ist misslich, wenn F2 in einem anderen kontext wiederverwendet werden soll:-(s)-> F8(s) -(y)-> F2(y) -(z)-> F9(z)zustand durchreichen ist technisch einfach. aber es verwässert den flow. jedenfalls solange das durchreichen explizit implementiert werden muss wie heute.
Das habe ich in meiner Implementation (hoffentlich recht elegant) geloest:
- Wiederverwendbare Funktionseinheiten (in der Praxis ca. 70%) arbeiten auf einem generischen Typ, den sie einfach durchreichen.
- Um an ihre Daten zu kommen arbeiten die generischen Funktionseinheiten mit Gettern, Settern und Factories.
- Die Getter, Setter und Factories bekommen sie im Konstruktor uebergeben. Der Konstruktor wird je nach Kontext entsprechend aufgerufen.
- Getter, Setter und Factories sind recht triviale "Closures/Lambdas", die aus einer DSL heraus generiert werden koennen.
Ich bin mir nicht sicher, dass du wirklich verstanden hast, was ich meine.
Deshalb nochmal etwas expliziter:
Zentrale Datenstruktur:
struct A { X x, Y y, Z z, B b, ... }
Der Flow ist dann:
-(X)-> F1(A) -(A)-> F2(A) -(A)-> F3(A)
Operationen:
F1<T, U> bekommt: Generics T=X, U=A; Factory fuer A und Setter fuer A,X
F2<T> bekommt: Generics T=A; Getter fuer A,Y und Setter fuer A,Z
F3<T> bekommt: Generics T=A; Getter fuer A,Z
So ein Getter ist einfach:
public interface Getter<T, U> {
public U get(T t);
}
Ein Setter entsprechend:
public interface Setter<T, U> {
public void set(T t, U u);
}
Eine Factory schliesslich:
public interface Factory<T> {
public T create();
}
Ich hoffe das macht es etwas klarer.
F1, F2 und F3 koennen also absolut generische und wiederverwendbare Funktionseinheiten sein.
Die wissen gar nicht auf welchen Daten sie eigentlich arbeiten und was sie da genau an die naechste Funktionseinheit senden.
Brauchen sie ja auch nicht. Der Compiler sorgt dafuer, dass es passt und die Funktionseiheiten koennen dank Getter, Setter und Factories arbeiten.
Die Getter, Setter und Factories sind schoen in der DSL dokumentiert und alles ist gut (meiner Ansicht nach).