Follow my new blog

Sonntag, 13. März 2011

It is all design – really?

image

Uncle Bob hat unlängst getwittert: “It is all design.” Und dafür hat er auch großes Lob aus Deutschland bekommen.

Ich frage mich hingegen: Wenn denn alles Design ist, warum sollte ich dann dieses Design in textuellem Quellcode durchführen?

Ja, ja, ich weiß, dass Jack W. Reeves schon in den 1990ern “bewiesen” hat, dass Programmierung nicht Herstellung, sondern Design ist. Dem stimme ich im Vergleich zum Baugewerbe oder der Autoproduktion auch zu. Softwareentwickler heißen nicht umsonst Entwickler und nicht Hersteller. Softwareentwicklung ist eine sehr kreative Tätigkeit. Ein Auto zu produzieren oder ein Haus hochzuziehen hingegen nicht. Da wird weitgehend nur ein Plan abgearbeitet. Softwareentwicklung hingegen ist Planerfindung.

Insofern produziert Codieren natürlich Design. “It is all design” könnte also wahr sein.

Aber: Design verhält sich zu Produktion wie Landkarte zu Terrain – das eine ist Abstraktion, das andere Detail, Konkretes. Was nun aber, wenn das Design so kompliziert ist, dass man es nicht einfach darlegen kann, wenn es selbst ein Terrain ist. Man kann es dann nicht runterschreiben. Selbst eine Landkarte will recherchiert sein. Sie kommt aus vielen Quellen zusammen und ist am Ende doch nur ein recht unkreatives Abbild der Realität. Software aber kann nicht irgendwo abgemalt werden. Software als Design muss erdacht werden. Code, der selbst ja nur ein Produktionsplan ist, muss selbst geplant, entworfen werden.

Und damit sind wir beim terminologischen Dilemma. Es ist eben nicht alles zu Design gesagt, wenn man konstatiert, Code sei Design. Man muss dazu sagen, was denn Design überhaupt seiner Natur nach sei. Man muss den allgemeinen Fall in den Blick nehmen:

Design ist ein Plan für etwas Konkretes.

Wenn etwas Konkretes kompliziert ist, dann kann man es nicht “einfach so” herstellen, sondern dann muss man sich darüber vorher mal Gedanken machen. Allemal, wenn das Konkrete etwas Neues ist.

Design braucht also selbst durchaus Design. Und das Design dann womöglich auch wieder usw. usf. Design ist mithin nur relativ, d.h. in Gegenüberstellung zu etwas Konkretem sein Vorläufer:

Design –> Konkretes

Nimmt man jedoch das Design selbst in den Blick, wird es ebenfalls etwas Konkretes, d.h. ein Produkt, das designt werden kann:

Design' –> Design

Und auch das Design des Designs könnte kompliziert sein, so dass es ein Design brauchen könnte:

Design'' –> Design'

So ergibt sich eine Hierarchie von Designs mit dem endgültig Konkreten als Ziel:

Design''(Design'(Design(Konkretes)))

Das halte ich für ein allgemeines Bild vom Verhältnis von Design zu Produkt. Der Entwurf geht dem Konkreten voraus. Und was bedeutet das für die Softwareentwicklung? Deren endgültig Konkretes ist klar: ausführbarer Code. Quellcode ist laut Reeves ein Design dafür. Uncle Bob sieht das ähnlich, wenn er sagt, Testing und Refactoring seien Designtätigkeiten (weil sie Quellcode formen). Für Sie ist die Hierarchie deshalb nur zweistufig:

Quellcode(Maschinencode)

Ich hingegen behaupte mal, dass das eine ganz und gar unnötig beschränkende Sichtweise ist. Wenn wir sie als Ende der Fahnenstange ansehen, dann müssen wir uns bei der Softwareentwicklung nur noch stärker bemühen, den textuellen Quellcode in den Griff zu bekommen. Refactoring-Tools müssen besser werden, Test-Tools müssen besser werden, die Ausbildung zum Quellcodeschmied muss besser werden… dann wird es schon gehen.

In den letzten 60 Jahren ist die Softwareentwicklung aber nicht besser geworden, weil sie auf der jeweils höchsten Abstraktionsstufe stehengeblieben wäre. Wir entwickeln heute natürlich Komplizierteres viel schneller als vor 60 Jahren. Nur tun wir das nicht mit besseren Maschinencode-Tools. Die Hierarchie sieht vielmehr so aus:

OO-3GL(IL-Code(Machinencode))

Oder sie sah sogar einmal so aus:

OO-3GL(3GL(Assembler(Maschinencode)))

Wir sind voran gekommen, weil wir uns auf höhere Abstraktionsebenen geschwungen haben!

Statt besser mit Maschinencode umgehen zu können, lassen wir ihn lieber generieren. Statt besser mit Assembler umgehen zu können, lassen wir den Code lieber generieren. Statt C zu schreiben, lassen wir den Code von einem C++-Compiler generieren. (Zumindest habe ich das noch 1990 erlebt. Es war aber eine vorübergehende Phase, die hier jedoch eine schöne Illustration des generellen Trends gibt.)

Warum also sollten wir da stehenbleiben? Was ist so heilig an der Hierarchie

C#(IL-Code(Maschinencode))

oder

Java(JBC(Maschinencode))

Ist denn der Softwareentwicklung die Phantasie ausgegangen? Haben sich alle im Schmerz eingerichtet, den es macht, 3GL-Code direkt zu schreiben und auch noch fehlerfrei und evolvierbar zu halten?

Nein, ich finde Uncle Bobs Position uninspirier(t/end). Er hat in “Clean Code” das Richtige gesagt und Gutes bewirkt. Danke dafür! Bei Refactoring und Test-first (und seinem Hobby Clojure) jedoch stehenzubleiben und auszurufen “It is all design.”, das finde ich zuwenig.

Warum nicht einen Schritt weiter denken? Wer füllt das Fragezeichen in dieser Hierarchie mit Leben:

<?>(C#(IL-Code(Maschinencode)))

Ist das der Platz für UML? Das glaube ich nicht. UML führt nicht direkt zu 3GL-Code – oder wenn, dann nur sehr umständlich. UML ist de facto ein Werkzeug, das vor allem der Beruhigung von Management dient. Regelmäßig geben auf Entwicklerveranstaltungen (in der .NET-Community) höchstens 15% der Anwesenden an, dass sie mit UML entwerfen.

Oder ist das der Platz für DSLs? Martin Fowler scheint das zu glauben, wenn er nicht gerade derselben Meinung wie Uncle Bob ist. Dagegen spricht für mich, dass DSLs selbst zunächst entworfen werden müssen, bevor sie helfen, 3GL-Code zu entwerfen:

Meta-DSL(DSL(C#(IL-Code(Maschinencode))))

Das scheint mir einer breiten Adoption entgegen zu stehen. Die Konzepte und Notation auf einer Ebene anzuwenden ist kompliziert genug wie wir am Beispiel C# sehen. Da hilft es wenig, Entwicklermassen zu empfehlen, zuerst Kompetenz auf einer Meta-Ebene zu erwerben, um immer wieder neue Konzepte und Notationen zu entwickeln, die dann erst zum Entwurf von Quellcode eingesetzt werden können. Der begrenzte Erfolg von MDSD scheint mir diese Sicht zu bestätigen.

Und nun? Ich kann leider nicht umhin, einen Anwärter auf die Position einer Entwurfssprache für 3GL in Flow-Design zu sehen. (Wer hätte das gedacht? ;-)

Flow-Design(C#(IL-Code(Maschinencode)))

Die bisher entwickelten Konzepte und die Formensprache für Flow-Design ist einfach zu erlernen und deckt viele typische Entwurfsbedürfnisse für Quellcode ab. Es gibt klare Übersetzungsregeln für Flow-Design Entwürfe in 3GL-Code. Die Ergebnisse sind übersichtlich und skalieren. Flow-Design ist nicht domänenspezifisch; einmaliger Lernaufwand zahlt sich also in allen Problemlebenslagen aus.

Soweit mal mein kühnes Statement :-) Aber ich bin natürlich offen dafür, dass man mir die Nutzlosigkeit einer Design-Abstraktionsebene oberhalb von Quellcode erklärt. Einstweilen erlaube ich mir jedoch, Uncle Bob bewusst misszuverstehen. Ich sage auch: It is all design. Aber ich meine damit etwas anderes. Für mich findet Design auf einer höheren Ebene statt als “Quellcoderumgeschubse”.

Kommentare:

Achim hat gesagt…

Ich empfehle zu dem Thema immer gerne diesen Vortrag: http://confreaks.net/videos/282-lsrc2010-real-software-engineering Mit der Perspektive von "Architektur" und "Produktion" lösen sich viele Probleme ganz von selbst auf. Deine Argumentation im unteren Teil bzgl. Programmiersprachen finde ich etwas einseitig. Java wurde z.B. explizit so designed, daß sich Entwickler nur schwer "selbst in's Knie" schießen können. Natürlich ist so eine Sprache limitiert. Bei C# sieht die Welt schon besser aus, aber noch lange nicht perfekt.

Was du forderst, ist eigentlich nur die Möglichkeit, abstraktere Highlevel Konzepte DRY ausdrücken zu können. In den von dir angeführten Sprachen ist das schwer bis unmöglich. Lisp, Ruby, Python, ... sind da weiter. Und genau deshalb fließen deren Abstraktionsmöglichkeiten immer mehr in C# ein oder führen zu neuen Sprachen wie F#.

Ralf Westphal - One Man Think Tank hat gesagt…

@Achim: Der Vortrag ist schön. Hatte ich neulich auch mal getwittert.

Mit Java magst du dir in ein paar Punkten weniger ins Knie schießen können - aber das sind Begrenzungen auf einem gewissen Abstraktionsniveau. Aus denen folgt nicht, dass man mit Java auf einem guten Abstraktionsniveau Software planen kann. Java ist und bleibt eine 3GL. Genauso C# und Lisp und Ruby und Python. Dynamik hin oder her: die Denkmodelle sind am Ende alle grundlegend gleich. Imperative Sprachen mit OO-Konzepten. Nice. Wir wollen nicht weniger. Macht sie aber nicht zu guten Werkzeugen für eine Planung.

Der Beweis? Immer noch warte ich auf die Massen an wartbarer Software, die durch OO-Denke entstanden sind. Nach 20 Jahren sollte es doch lange Reihen von Software geben, die sich mit OO nicht in die Unwartbarkeit gepinselt haben. Dem ist aber nicht so.

Und Patterns? Haben nicht wirklich geholfen. Sie sind keine Planungswerkzeuge.

Und Refactoring? Cool - aber man muss schon eine Idee davon haben, wohin man refaktorisieren will. Und woher kommt die? Aus SOLID? Sorry, das ist mir zuwenig.

Und so bleibe ich dabei: Es fehlt der breite Wille, eine Abstraktionsebene oberhalb von 3GL zu suchen. Refactoring und TDD sind nur Lokalanästhetika :-)

Achim hat gesagt…

Ok, ich glaube eine ähnliche Diskussion hatten wir schonmal und ich erinnere mich grob, an welcher Stelle wir uns nicht einigen konnten. ;-) Aber trotzdem:

Daß die angegebenen Sprachen im Prinzip alle gleich sind, halte ich für Unsinn. Wenn man es so sehen will, kann man natürlich zwanghaft diesen Standpunkt einnehmen, aber das hat nichts mit der Realität zu tun. Paul Graham analysiert dieses Märchen von den gleichwertigen Programmiersprachen übrigens sehr schön in http://www.amazon.de/Hackers-Painters-Big-Ideas-Computer/dp/1449389554/ref=sr_1_1?ie=UTF8&s=books-intl-de&qid=1300050286&sr=8-1. Wenn dem so wäre, hätte nach C++ niemand Java oder C# erfinden müssen.

Und da du in deinem Post kühne Statements von dir gibst, erlaube ich mir das auch: Was du brauchst, sind einfach fähige Entwickler, die zum einen auf sehr abstraktem Niveau denken können und zum anderen ihr grundlegendes Handwerk (Programmiersprache, SOLID, TDD, Tools, ...) beherschen. Leider findet man beides nur selten in einzelnen Personen vereint.

An der Stelle konnten wir uns auch beim letzten mal nicht einigen. Ich sehe fähige, denkende Entwickler als Grundvoraussetzung für gute, wartbare Software an. Du würdest sie gerne unnötig machen. Aber gute Software ohne Denken wird es meiner Meinung nach nie geben! ;-)

Lars hat gesagt…

@Achim

Auch wenn ich hier manchmal etwas kritisch bin, muss ich Ralf zustimmen.
Es gibt die nächsten Jahrzehnte nicht genug universell gebildete SW-Entwickler. Ich hab im Übrigen noch keinen einzigen kennengelernt.

Also brauchen wir Tools, die auch niedrigschwellig komplexe Probleme lösen können. Und diese Tools müssen in der Theorie möglich sein, da ich die Lösung ja auch denken kann (um mal im übertragenden Sinne philosophisch zu werden).

Die Welt wird immer komplexer und immer individueller...und das ist auch gut so! Aber die Lösungen für Probleme werden somit auch immer spezieller. Das kann alles nur gut gehen, wenn wir irgendwann zu einem Zustand kommen, an dem -jeder- komplexe SW-Probleme lösen kann.
Die Flow-Programmiersprache ist somit wahrscheinlich sogar nur ein Zwischenschritt zu einer vollständig natürlichen Programmiersprache, die komplett ohne so etwas wie Zeichen, vituelle Bausteine oder andere Hilfmittel auskommt.
Das mag vielleicht verrückt klingen....aber ich hab da sogar eine Idee, dass sowas gar nicht so weit hergeholt ist...

Anonym hat gesagt…

Bei diesen (erforderlichen) Weiterentwicklungen dreht sich die Diskussion eigentlich um die Aktzeptanz von weiteren "Einschränkungen" durch Programmierer.

Ende der 1980er gab es immer wieder "Diskussionen" zwischen C/Pascal- und Assembler-Programmierern. [Interpreter einmal außen vor gelassen]

Die Assembler-Anhänger waren der Ansicht, nur in Assembler programmierter Code ist wirklich effizient. Das zeigte sich auch in der Diskussion über Compiler. Welche Compiler-Optimierungen udglm. sind sinnvoll möglich, welcher Compiler erstellt wirklich effizienten Assembler-/Maschinencode. Bei welchen Optimierungen gibt es Probleme (speziell C/C++), ... und hierbei gab es immer wieder Gegenargumente (Widerstand) seitens der Assembler-Programmierer. (ich möchte nur festhalten - glücklicherweise gab es Widerstand, denn das führte zu besseren Compilern)

[Einschub: Natürlich gab es auch Wettbewerb zwischen den Compilerentwicklern untereinander ...]

Unabhängig von der sinnvollen Diskussion über Optimierung usw. drehte sich die Diskussion aus meiner Sicht eigentlich darum, dass durch die Verwendung einer höheren Programmiersprache der Programmierer "Einschränkungen" im Vergleich zu früher Programmiertechniken akzeptieren musste. Aus heutiger Sicht mag die damalige Diskussion unsinnig erscheinen, aber sie zeigt mMn., wie Programmierer (Menschen!) denken.

Heute käme keiner mehr auf die Idee, komplexe Anwendungen in Assembler zu programmieren. [mir ist aber auch klar, dass Assembler auch heute noch seine Daseinsberechtigung hat]

Bei jeder neuen Stufe (zB. auch bei C zu C++, Java bzw. C#) gab es die Diskussion wieder. Die Themen waren zB. die nicht mehr gewünschten/möglichen "Pointer-Methoden" und die Verwendung einer VM. Ist das wirklich effizient, schnell genug, sicher genug, udglm. All dies waren weitere "Einschränkungen".

Viele Altlasten wurden auch "nur" wegen einer besseren Akzeptanz in höhere Systeme übernommen. Die "Abwärtskompatiblität" ist mMn. nur ein Feigenblatt.

Und wenn du jetzt einen nächsten Schritt machen möchstes, was ich für absolut richtig und wichtig halte (es lebe die Evolution), hast du die selbe Problematik: Die Leute müssen weitere "Einschränkungen" akzeptieren! LEIDER SEHEN VIELE NICHT DIE FREIHEITEN, DIE SIE IM GEGENZUG GEWINNEN.

Und dann gibt es noch weitere Aspekte: "Experten" verlieren ihre Wissenshoheit. Was ist mit altem Code? Was ist mit bestehenden Methoden? ...

Ralf Westphal - One Man Think Tank hat gesagt…

@Anonym: Danke für deinen Kommentar. Ich stimme dir in allem zu.

Auch darin, dass heute noch Assembler seine Berechtigung hat. Denn so denke ich auch: C#/OOP verliert durch eine weitere Abstraktionsebene darüber nicht seinen Wert. 3GL wandern nur aus dem absolutistischen Zentrum an einen anderen Platz - an dem sie weniger Schaden anrichten können ;-)

Anonym hat gesagt…

Stimme darin überein eine weitere Abstraktionsebene einzuziehen, aber ich hätte dann doch mehr Anforderungen als Sie mir ein reines Flow Design bieten kann. Da wären zum Beispiel Performance Vorhersagen oder Verifizierung gegenüber den Anforderungen und spezifizierte Schichten (z.B. Architekt & Komponenten Entwickler)

Ob das nicht zuviel des Guten ist, bleibt natürlich zu diskutieren, aber eine solche Schicht sollte nicht nur auf Code Generierung beschränkt sein, denke ich.

Anonym hat gesagt…

[Anonym(1) an Anonym(2) & Ralf]

Derzeit stellt FBP für mich ggf. ebenfalls nur eine reine syntaktische Erweiterung bestehender Programmiermethoden dar. Wo ist dann aber der wirkliche Vorteil im Vergleich zu anderen Methoden wie OOP, Patterns (MVC, ...), TDD, ...?

OK, ein Programmierteam hält sich an (neue) bestimmte Regeln, wie ein System zu implementieren ist. Das gibt es ja vergleichbar im Prinzip jetzt schon. (Auch wenn es durch eine Spracherweiterung einfacher/naheligender sein könnte).

Nur worin ist dann der Vorteil zu sehen? Übersichtlicher wird bei FBP ein System auch nicht wirklich - die evtl. gewonnene Übersicht geht in zusätzlicher neuer Komplexität unter (Ablauf a/synchron, Nachrichtendefinition, ...). Mich würde ja einmal interessieren, wie ein mit FBP implementiertes Warenwirtschaftssystem aussieht. :-)

Ist das dann wirklich ein Fortschritt?

Derzeit hat FBP zu wenig "neue Freiheiten" im Vergleich zu den bisherigen evolutionären Schritten: ASM -> MASM -> C -> C++ -> Java/C#/... -> FBP (???)
[Freiheit im Sinne von: Ich brauche mir bei bestimmten Dingen keine Gedanken mehr machen.]

Ich denke, FBP in der bisherigen Form greift zu kurz was das angestrebte Ziel betrifft.

Aus meiner Sicht scheitert es dzt. bereits bei der Begriff-Definition. Was versteht man unter Design (konkret bis zu welcher Abstraktionsebene). Wer ist der Designer? (ein Programmierer, ein Geschäftsführer, ...) Welches Design ist gemeint? Geschäftsprozess, Interaktion, ...
Und was ist dann unter "besserer Wartbarkeit" zu verstehen? Geschweige denn "Wiederverwendung".
Wie können "Fehler" schneller entdeckt bzw. überhaupt vermieden werden? Wie müsste ein "Editor" dazu ausehen? Wie viel Code sollte überhaupt noch manuell erfasst werden (müssen)?

Konkret: Es fehlt die Zieldefinition.

Rein zu postulieren, dass FBP der nächste logische evolutionäre Schritt ist, ist zu wenig. Es ist aus meiner Sicht dzt. ein reiner Versuchsballon, der sicher diskussionswürdig ist. Nur momentan ein wenig zu "luftig" und zu wenig "konkret".

FBP wandelt ja auch auf dem BPMN-Pfad. Oder habe ich da was falsch verstanden?

Die bisherige Denkweise ist mMn. auch noch zu sehr auf bestehende Techniken verhaftet.

Ralf Westphal - One Man Think Tank hat gesagt…

@Anonym2: Du wünscht dir Performancevorhersagen und Verifizierungen gegenüber Anforderungen?

Performancevorhersagen sind von Maschinencode bis zu OOP nicht leichter geworden. Am Ende hilft nur Ausprobieren. Warum sollte eine nächste Ebene also mehr liefern? Ich denke, da erwartest du zuviel. Eine Performancevorhersage ist nicht Thema einer Entwurfsmethodik. Das ist, als wolltest du einem Architekturplan die Stabilität entnehmen. Die steht da auch nicht drin, sondern muss getrennt durch einen Statiker berechnet werden.

Anforderungsverifikation, also die Frage beantworten "Ist Anforderung X erfüllt?" ist mit Flow-Design ungleich einfacher als durch Starren auf OO-Code.

Den Architekten und "Komponentenentwickler" würde ich gleichfalls erstmal aus dem Bild rauslassen. Architektur und Komponenten sind orthogonal zu der nächsten Ebene, um die es mir geht. Genauso wie das heute bei OO ist.

Ralf Westphal - One Man Think Tank hat gesagt…

@Anonym1 (warum postet ihr Anonymen nicht mit Namen?): Du fragst, "Wo ist dann aber der wirkliche Vorteil im Vergleich zu anderen Methoden wie OOP, Patterns (MVC, ...), TDD, ...?"

Und ich anworte: Der wirkliche Vorteil liegt in der Abstraktion. Ich muss mir um bestimmte Details keine Sorgen mehr machen. Schon vergessen, wie das früher war mit der Registerallokation? Dann haben 3GL ja etwas gebracht; sie verbergen technische Details, die bei der Problemlösung im Wege stehen.

Dito Flow-Oriented Design. Es verbirgt die Details, wie die wichtigen funktionale Abstraktionshierarchien implementiert werden. Es verbirgt die Details notwendiger Abhängigkeiten und es vermeidet unnötige Abhängigkeiten. Ja, auch die Details des Einbringens von nicht-funktionalem Code (async, Verteilung, Sicherheit) werden verborgen.

Prinzipien und Konzepte und Technologien, die die Köpfe von Millionen Entwicklern verwirren, werden weitgehend überflüssig oder versperren zumindest nicht den Blick auf das Wesentliche. Zu nennen sind z.B. Law-of-Demeter, Dependency Injection, Mock Frameworks.

Bei einer nächsten Ebene oberhalb von Code geht es um Fokus. Fokus auf Funktionalität, Fokus auf Verständlichkeit/Nachvollziehbarkeit.

Ich kann da nur jedem Skeptiker raten, das an nicht trivialen Beispielen auszuprobieren. Dazu muss man sich aber drauf einlassen. Eine Möglichkeit das zu tun bietet die Clean Code Developer School im Modul 3: http://www.prodevcollege.de/ccds-modul3.html. Da geht es um Flow-Design anhand einiger Projekte. Und ich kann nur sagen: Da ist noch niemand unbeeindruckt rausgegangen.

Tut mir leid, keine günstigere Botschaft zu haben als, "Umdenken braucht Zeit und Durchhaltewillen." Geschenkt bekommt die nächste Ebene niemand. So wie die Objektorientierung niemand geschenkt bekommen hat. Nur leider ist sie ein Danaergeschenkt ;-) Denn an der Oberfläche schön anzusehen lauern in ihr die Fallen des Denkens in Abhängigkeitsbeziehungen.

Es fehlt die Zieldefinition?

Wie wäre es mit: Software soll endlich ohne Verrenkungen entwerfbar werden. Sie soll heute und in Zukunft verständlich und erweiterbar und leicht testbar sein.

Wenn das mit OO schon so wäre, dann hätten wir nicht das de facto existierende Desaster.

Wer das nicht glaubt, der lade mich gern zu einer Teamstatuserhebung (http://clean-code-advisors.com/die-angebote/teamstatuserhebung) ein. Die ist sogar kostenlos, wenn am Ende das Team sagt, es hätte dabei keine Erkenntnis gewonnen.

Anonym hat gesagt…

[Anonym1]

@Ralf: Es fehlt die Zieldefinition? Wie wäre es mit: Software soll endlich ohne Verrenkungen entwerfbar werden. Sie soll heute und in Zukunft verständlich und erweiterbar und leicht testbar sein.

Sorry, das ist mMn. keine Zieldefinition - aller höchstens eine Vision.

ZB. Gibt es im Projektmanagement bei der Zieldefinition die "SMART-Regel":
S(pezifisch) Ziele müssen spezifisch, eindeutig und positiv beschrieben sein.
M(essbar) Die Zielerreichung sollte messbar sein.
A(ttraktiv) Für das Projektteam sollte es attraktiv sein, das Projektziel zu erreichen.
R(ealistisch) Das Ziel muss realistischer Weise erreichbar sein.
T(erminiert) Das Ziel muss terminiert sein.

Und solange Ziele zu allgemein definiert sind, werden/können Birnen mit Äpfel verglichen werden - es ist ziemlich "beliebig". Zudem fällt es schwer, an einem Strang zu arbeiten und dann gemeinsam daran zu ziehen.

So bleibt es bei Träumerei, die zwar praktische Teillösungen produziert, aber eine wirkliche - auch gemeinsame - Entwicklung in Richtung der Vision fällt damit schwer bzw. ist unmöglich.

Auf dieser allgemeinen Ebene lässt sich zwar schön philosophieren, aber nichts konkretisieren. Philosophieren gehört dazu, aber irgendwann muss es eine Basis geben, auf der aufgebaut wird.

Also, was versteht man unter gutem Design (zB. auch Zielgruppe)? Was heißt konkret "wartungsarm/-frei"? Was heißt konkret "wiederverwertbar"
und und und ...

Sebastian hat gesagt…

Sebastian, [Anonym2]

Performance Vorhersagen sind durchaus schon möglich und bestimmt in der Zukunft mit der Cloud noch interessanter (kann mir ein Anbieter garantieren, dass mein Anwendung schnell genug läuft?)

Siehe Palladio: http://sdqweb.ipd.kit.edu/wiki/Palladio_Component_Model

Dort werden aber 4 Modelle und Rollen verwendet:
1. Komponentendiagram (Architekt)
2. Flussdiagram für Komponenten (Komponenten Entwickler)
3. Deployment Diagram (Deployment Experte, z.B. Administrator)
4. Usage Model (Domain Experte)

Insofern finde ich ein reines Flow Design noch nicht weitsichtig genug. Mit passenden Sichten und Transformationen, z.B. zu einer formalen Anforderungsspezifikation (wie immer die auch aussieht) könnte eine solche Abstraktionssicht noch mehr leisten und den Code wirklich komplett abstrahieren und nicht nur kaschieren.

Ralf Westphal - One Man Think Tank hat gesagt…

@Anonym: SMARTE Ziele sind ne nette Sache. Wenn Sie denn nur in Projekten eine solche Rolle spielen würden, wie du sie hier forderst.

Da sie das aber nicht tun, erlaube ich mir für den Moment, eine SMARTE Zieldefinition für "das nächste Design-Level" zu verweigern. Zumindest, bist du (oder jmd anderes) mir eine solche Zieldefinition für die Objektorientierung nachgeliefert hast.

1. Wo war 1990 (oder so) die SMARTE Zieldef für OOP? 2. Falls es sie gibt: Hat OOP das SMARTE Ziel erreicht?

Nun bin ich gespannt...

Ralf Westphal - One Man Think Tank hat gesagt…

@Sebastian: Das sind alles wichtige Facetten der Softwareentwicklung. Aber es ist nicht meine Absicht, für alle eine Antwort zu bieten. Das tut Assemblerprogrammierung nicht, das tut OOP auch nicht.

Nicht-funktionale Anforderungen sind eine Sache der Architektur. Um die gehts mir aber nicht. Ich will eine Methode, mit der ich Lösungen für funktionale Anforderungen entwerfen kann - auf sovielen Abstraktionsniveaus wie ich mag und leicht testbar und auch noch verständlich/nachvollziehbar, wenn ich aus dem Urlaub komme und das Team weitergeplant hat.

Niemand erwartet all das von DSLs oder MDSD oder Funktionaler Programmierung und Uncle Bob hat auch keine Antwort auf all diese Fragen. Und also sollte es auch niemand von einer neuen Hierarchiestufe in der "Codeplanung" erwarten, wie ich sie hier meine.

Es kann doch nicht so schwer sein: C#-Code schreibt man nicht so einfach hin. Ihn mit Klassendiagrammen und OOAD wirklich wartbar zu planen ist - wie die Geschichte zeigt - keine realistische Aufgabe. Helden mögen das hinkriegen, aber nicht Joe Developer. Da helfen dann auch keine Paketdiagramme oder Sequenzdiagramme. Das Problem beginnt dabei, dass Entwickler Diagramme malen, die entweder nicht standardkonform sind und zweitens nicht konsistent. In jedem Team, das ich in den letzten Wochen gesehen habe, gab es Uneinigkeit darüber, was simple Pfeile in einem Diagramm eigentlich bedeuten.

Nur diese so grundlegenden Probleme zu lösen, ist mein Ansinnen. Ich will nicht die Welt retten. Nein, keine Silberkugel von mir. Ich will nur ein paar Probleme reduzieren, die den gewöhnlichen Entwickler jeden Tag plagen. Und die haben mit mangelnder Abstraktionsfähigkeit mit OO-3GL zu tun.

Anonym hat gesagt…

[Anonym1]

Den Ball "so billig" zurück zu spielen ist gerade in diesem Fall zu einfach! :-) Das Lamentieren bzgl. aktueller Situation hast ja Du angefangen. Es ist auch sicher nicht meine Aufgabe, die ggf. fehlende Zieldefinition von OOP nachzuholen.

Nur, wenn Du Flow Design als nächsten evolutionären Schritt (mit-)postulierst, dann ist es auch ein wenig Deine Aufgabe die Ziele (nicht nur "Träumereien"), die damit verfolgt werden sollen, genauer als bisher zu spezifizieren bzw. bestehende Zieldefinitionen zu nennen. Immerhin stellst Du das Thema ja auch zur Diskussion.

Durch eine exaktere Zieldefinition (es muss ja nicht gleich jeder Punkt und Beistrich passen) ist auch für "andere" ersichtlich, in welche Richtung es Deiner Meinung nach geht. Aufbauend darauf, können Ziele verfeinert bzw. auch durch weitere Erkenntnisse angepasst werden. Auch wären die aktuellen "Grenzen" besser ersichtlich, die dann ggf. im Design :-) berücksichtigt werden könnten. Gerade auch, weil Flow Design mit an Sicherheit grenzender Wahrscheinlichkeit auch nicht für alle Lösungen die richtige Umsetzungsstrategie ist, sollten die Grenzen bekannt sein. Sonst kommt schneller als einem lieb ist auf, dass Flow Design "unbrauchbar" ist. (siehe auch "agile Programmierung", "Kanban", "SOAP", "WebServices", ...)

Den Gedankengang Von EBC zu FBP zu ... aufzubringen ist ein erster Schritt. Alleine das darüber Nachdenken ist sehr reizvoll. Der Ansatz ist nicht schlecht, nur hat er mMn. dzt. den selben Status, wie Anfangs viele anderen "Ideen". Zuerst klingt alles phantastisch, dann gibt es erste einfache Lösungen, die "alles" bestätigen, und dann, wenn es bei komplexeren Aufgabenstellung bzw. umfangreicheren Projekten problematisch wird, wird einem erstmals "Unfähigkeit" attestiert und in weiterer Folge kommt es auch oftmals noch zur "Kindsweglegung" und was neues wird aus dem Hut gezaubert.

Und das ist einer der Gründe, warum die Softwareentwicklung auch so einen "schlechten Ruf" hat und sich nur durch neue "Buzzwords" den Mantel der Innovation umhängt. Im Grunde hat sich in der Softwareentwicklung nicht so viel getan. Es gibt zwar viele Erweiterungen, aber im Kern ist der Job ident wie früher. [Meine Güte, was wurde nicht mittlerweile wieder alles zu Grabe getragen, was ach so super war ...]

Anonym hat gesagt…

[Anonym]

dazu ein link:

http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918

anonym3

Anonym hat gesagt…

[Anonym1]

@Anonym3: Meinst Du, dass ich ein "old Dog" bin, der Neuerungen wie der Teufel das Weihwasser meidet? :-) Ich heiße jedenfalls nicht Linus.

Nö, ganz im Gegenteil. Ich bin ebenfalls der Überzeugung, dass viele Projekte auf Grund er Unübersichtlichkeit und wegen der umfangreichen "inneren Verstrickungen" scheitern. Da bin ich voll und ganz auf Ralfs Linie. Auch denke ich, dass hier durch die höhere Abstraktion ein Kommunikationsmittel mit "Entscheidungsträgern" besser möglich wäre. Eine einfache Verbindung zwischen Programmierung, Projektplanung und "Präsentation" wäre ja ideal. UML hat es ja bis heute nicht wirklich geschafft - die Komplexität (und auch Beliebigkeit) überfordert mittlerweile tlw. sogar UML-Spezialisten.

Ich reagiere schon länger allergisch auf "gute Ideen", die oftmals nur aus publizistischen Gründen und Selbstdarstellung in die Welt gesetzt werden. Das möchte ich dem Ralf aber keinesfalls unterstellen. Daher bin ich auch so "lästig" und andernfalls würde seinen Blog nicht kontinuierlich verfolgen.

Ralf Westphal - One Man Think Tank hat gesagt…

@Anonym1: Ich denke nicht, dass "billig" war, den Ball zurückzuspielen. Allemal, weil deine Antwort darauf natürlich "verräterisch" ist :-) Du sagst zwar, du willst keine SMARTe Zieldef nachholen - ich behaupte jedoch, dass es die 1. nicht gibt und 2. dass noch nie jemand an eine Methode/ein Konzept wie OOP, SOA, FP, Scrum o.ä. eine solche SMARTe Zieldef angelegt hat. Deshalb 3.: Du kannst keine SMARTe Zieldef für OOP angeben.

SMART macht einfach keinen Sinn in Bezug auf Methoden. SMART hat mit Zielen zu tun, nicht Konzepten.

Ich nenne dir aber gern meine Kriterien für eine bessere Entwurfsmethode. Daran kannst du dann Flow-Design, OOP oder etwas anderes messen:

Sie muss schneller und verlässlicher und leichter erlernbar zum Ziel führen als bisherige Methoden.

Was ist das Ziel? Korrekte und evolvierbare Software, die die funktionalen wie nicht funktionalen Anforderungen erfüllt.

"Schneller", "verlässlicher" und "leichter erlernbar" halte ich für messbar. Das muss man nur wollen. In meinen Trainings und bei Teamstatuserhebungen tue ich das auch schon. Das mag wissenschaftlichen Anforderungen an Datenerhebungen nicht genügen - aber man zeige mir die Methode in der SWentwicklung, die je wissenschaftlich begründet als besser übernommen wurde.

Bei meinen "informellen" Messungen nun kommt ganz klar heraus:

Flow-Design produziert verlässlicher und schneller korrekten Code, weil die Funktionseinheiten von vornherein kleiner sind und der Review einer Lösung leichter ist als bei OOP. Außerdem sind (fast) keine Attrappen mehr bei autom. Tests nötig.

Flow-Design produziert auch verlässlicher und schneller evolvierbaren Code, weil der Entwurf besser verständlich ist als bei OOP (es gibt mehrere echte Abstraktionsebenen), der Entwurf sich 100% im Code widerspiegelt, die Funktionseinheiten kleiner sind, sich Funktionalität leichter neu arrangieren oder ergänzen lässt, ein Team sehr leicht zusammen an einem Entwurf arbeiten kann, nur 1 Diagrammart zur Darstellung von Funktionalität nötig ist.

Das stelle ich mal in den Raum für all die, die skeptisch sind und es schlicht noch nicht ausprobiert haben. Damit behaupte ich nicht, dass es nix besseres gäbe oder damit nun endlich das Ende der Entwicklung erreicht sei. Ich behaupte lediglich, dass Flow-Design ein ernsthafte Option ist, die man ernsthaft prüfen sollte, wenn man an Korrektheit und besonders Evolvierbarkeit interessiert ist. Und daran, dass man diese Eigenschaft mit einem Team schneller und verlässlicher herstellen will.

Mein Angebot für ein shoot-out mit OOP-Freunden erneuere ich hier auch gern. Wer mag, der trete mit seinem OOP hard core Team gegen Stefan Lieser und mich an. Dann schauen wir, nach welcher Methode evolvierbarer Code verlässlicher herauskommt :-) Wie wäre das?

Ralf Westphal - One Man Think Tank hat gesagt…

@Anonym1: Schade, dass du auf "gute Ideen" allergisch reagierst. Das klingt nämlich unbewusst und unwillkürlich.

Warum nicht "gute Ideen" unvoreingenommen begrüßen - und dann gegen einen Satz an Werten und Prinzipien prüfen. Dann kann es dir egal sein, wer aus welchen Gründen die "guten Ideen" äußert. Da kann sogar der Kommerz aus jeder Pore strömen: wenn die Idee gut ist, ist sie einfach gut.

Oder die Intention ist samariterhaft und idealistisch: wenn die Idee schlecht ist, dann ist sie einfach schlecht.

Intention ist kein Kriterium für die Qualität von Ideen. "Gut gemeint" hat schon viel Leid erzeugt.

Die Frage also: Gegen welche Prinzpien und Wert verstößt Flow-Design oder OOP oder FP oder UML oder sonstwas. Oder welche unterstützen diese Ansätze?

Ich habe durch eine Werte- und Prinzipienbrille auf UML und OOP geschaut und sie für zu schwach befunden. Sie verfehlen ihr Ziel, sie erfüllen ihre Versprechen nicht.

Deshalb habe ich für mich einen neuen Ansatz gesucht. Mit Flow-Design habe ich ihn gefunden und sehe (ganz selbstverständlich ;-) derzeit vor allem Nägel für diesen neuen, hübschen Hammer. Wenn du erstmal die "Flussbrille" auf hast, dann siehst du die Flüsse überall. (Fühle mich damit auch in guter Tradition. "Alles fließt" sagte schon Heraklit. ;-)

Gestern haben wir z.B. eine Flow-Oriented Analysis eines Unternehmens gemacht. Das hat den Geschäftsführern die Augen geöffnet.

Überspitzt gesagt: OOAD (die eine Interpretation der ursprünglichen OO-Botschaft) ist dem Mechanischen, dem Statischen verhaftet. Flow-Design hingegen kommt aus der Welt des Lebendigen.

Anonym hat gesagt…

[Anonym1]

@OOP: Sorry Ralf, aber den Ball hin und her zu spielen ist lächerlich. Und zu argumentieren, weil noch niemand eine Zieldefinition für div. Methoden/Konzepte vorgelegt hat - was ich mal pauschal bezweifeln möchte - braucht man das generell nicht (?), genau das ist "billig". ()

Deine Erfahrungen mit Flow Design bestreite ich überhaupt nicht. Es ist schön, dass Du diese Erfahrung hast. Ich glaube Dir das gerne. Und weiter? Was waren das für Projekte? Wie groß war der Aufwand? Vergleichbarkeitsüberlegungen? Warum wurde genau dieser Weg genommen? Wie war der Umlernprozess bei den beteiligten ProgrammiererInnen? ...

@evolvierbarer Code:

Genau mit diesem Angebot (shoot-out) behauptest Du, dass Flow Design die "ultimative Lösungsstrategie" ist.

So, und jetzt definiere mir "evolvierbarer Code". Nach welchen Kriterien betrachtest Du eine Anwendung als "evolvierbar"? In welchem Zusammenhang? Bei welchem Fall?

Und das ist das, was ich mit (Ziel-)Definition meine.

Flow Design kling gut. Nur auf welcher Basis soll sich ein Verwantwortlicher "trauen" dieses Konzept einzusetzen? Mit welchen Argumenten sollen "eingefleischte" Programmierteams davon überzeugt werden?

Solange es auf der Ebene bleibt, dass Du und Stefan Lieser jeden anderen mit Flow Design locker in die Tasche stecken könnt, bleibt es dabei. Durch die bisher unfassbaren/falsifizierbaren Argumente entzieht sich Flow Design damit jeder in weiterer Folge konstruktiven Kritik.

@gute Ideen: Sorry, aber ich habe mich nicht prinzipiell gegen "gute Ideen" gewehrt. Es gibt aber einen Unterschied zwischen "gute Idee" und "Buzzword". Der Unterschied besteht in der Konkretisierung. Und genau die fordere ich ein.

Eine gute Idee zeichnet sich dadurch aus, dass sie sich Gegenargumenten stellt und sich nicht nur mir Killer-Argumenten verteidigt.

@Flow-Design hingegen kommt aus der Welt des Lebendigen.: Aha. Und? Wie jetzt?

Anonym hat gesagt…

Ralf, ist zwar Off-Topic aber man blickt bei deinen Kommentaren kaum noch durch. - Zumindest gehts mir so. Ich würde mir für deinen Blog mal eine vernüftige "zeitgerechte" Umsetzung einer Kommentarfunktion wünschen, wo man eben auch Zitate setzen kann. --> "[quote]".

Danke,
Florian

Lars hat gesagt…

[quote]
Flow Design kling gut. Nur auf welcher Basis soll sich ein Verwantwortlicher "trauen" dieses Konzept einzusetzen? Mit welchen Argumenten sollen "eingefleischte" Programmierteams davon überzeugt werden?
[/quote]

Wahrscheinlich muss das gar nicht der erste Schritt sein. Wenn Flow-Programmierung tatsächlich sehr einfach zu erlernen ist, könnten auch unerfahrere Programmierer damit anfangen. Wenn die Rechnung aufgeht, müssten sie hoch "effiziente" und evolvierbare Software damit erstellen können. Wenn das stimmt und die erfahrenen Programmierer dadurch "von unten" einen Kostendruck bekommen, würden sie gar nicht umhin kommen sich damit auseinander zu setzen.

Wenn etwas wirklich gut ist (im Sinne der Marktwirtschaft) dann setzt es sich auch durch...so oder so...

Sebastian hat gesagt…

Hi Ralf,
das sind zwar in der Tat alles nichtfunktionale Anforderungen, aber das ist Wartbarkeit und Verständlichkeit meiner Meinung nach auch.

Ich finde deinen Ansatz super, sehe aber hier nur den Anfang. Richtig Erfolg kann eine solche Abstraktionsebene genau dann haben, wenn Sie die Betrachtung der unteren Ebenen weitestgehend überflüssig macht. Ich bin erst seit wenigen Jahr Softwareentwickler und auch noch im Studium, würde aber behaupten, der Erfolg von Hochsprachen liegt nicht nur darin eine andere Syntax zu bieten sondern auch die komplexen unteren Schichten komplett zu überdecken. Das sähe beispielsweise anderst aus, wenn man in C# Programmieren würde, aber die einzige Debugging Möglichkeit direkt in IL-Code oder sogar Assembler wäre. Eine solche Abstraktionsebene macht viele Tools auch erst möglich. Ein Profiler für Assembler ist für einen normalen Entwickler wohl kaum eine Hilfe.

Deshalb sehe ich bei Flow basierten Designs erst den Anfang. Das weiter auszubauen und Ziele zu formulieren halte ich dabei auch für zwingend erforderlich, denn im Moment fehlt mir einfach die Vorstellungskraft das Flow Modell auch wirklich auf alle Teile der Softwareentwicklung zu übertragen. Vielleicht gehe ich dabei zu weit, aber da keine Grenzen definiert sind, würde es micht auch interessieren, wie sich Flow Design in anderen Bereichen als die aufgezeigten verhält:
- Wie fügt sich Flow Design in strukturgetriebenen Frameworks oder Anwendungen ein (z.B. GUI Elemente, Spiele, Graph Algorithmen)?
- Wie fügt sich Flow Design in sehr performancelastige Anwendungen (z.B. Spiele) ein?

Hier scheinen mir Flow Designs noch nicht komplett zu sein, OOP ist hier flexibler.

Ralf Westphal - One Man Think Tank hat gesagt…

@Anonym1: Ich definiere "evolvierbarer" ganz einfach als:

Wenn eine Änderung vorgenommen werden soll, dann kann sie 1. schneller vorgenommen werden und 2. die Korrektheit (auch Regressionsfehlerfreiheit) kann leichter sichergestellt werden.

Niemand behauptet, dass sich kein evolvierbarer Code mit reinen OOP-Mitteln (oder nach OOAD) herstellen lässt. Sonst hätte ich kaum CCD mitgegründet. Aber ich behaupte inzw., dass es mit einer bestimmten, dem OO-Code vorgeschalteten Entwurfsmethode leichter ist.

Und das lässt sich nicht beweisen, sondern nur erfahren. Deshalb ist ein shoot-out keine schlechte Sache. Einfach eine direkte Gegenüberstellung von Herangehensweisen anhand desselben Szenarios. Niemand soll dabei zuschaden kommen. Alle sollen anschließend gutgelaunt ein Bier zusammen trinken. Und es kann für alle Seiten nur erkenntnisreich sein - egal, ob eine Seite "verliert" oder nicht.

Dass es dagegen eine Aversion gibt, kann ich eigentlich nicht verstehen. Bis zum Beweis des Gegenteils und nach Erfahrung mit vielen Teamstatuserhebungen behaupte ich deshalb mal: Wer sich so einer Gegenüberstellung nicht aussetzen will, der traut seiner eigenen Methode nicht. (Oder er ist so überheblich, dass er glaubt, das habe er gar nicht nötig; dabei gäbe es nichts zu lernen.)

@Buzzword: Wenn du Flow-Design oder EBC für ein Buzzword hälst, dann verfolgst du entweder die Diskussion nicht und/oder hast es einfach noch nicht probiert.

Solange du dich nicht zu erkennen gibst, finde ich darüber hinaus auch jede weitere Kritik dünn. Denn du sprichst implizit über Vertrauen. Es bestünde kein Grund zu Vertrauen in soetwas buzzwordiges wie Flow-Design. (Dass ja übrigens nicht neu ist, sondern nur eine etwas veränderte Verpackung und Konkretisierung erhalten hat mit EBC.)

Wer aber in einem Forum wie diesem ohne Not anhaltend ohne Realname auftritt, der darf auch kein großes Vertrauen erwarten. Denn wo kein Realname dahinter steht, da kann jeder behaupten, was er will, ohne Schaden zu nehmen. Im Notfall verschwindet er unerkannt.

Ich exponiere mich mit meiner Person und treffe Aussagen, bei denen ich immer daran denken muss, was sie für eine Wirkung auf meinen Ruf haben. Wer anonym mit mir diskutiert, ist also nicht Augenhöhe. Da macht es dann ab einem gewissen Ernsthaftigkeitsgrad keinen Spaß mehr. Fair ist, wenn beide dasselbe Risiko tragen.

Ralf Westphal - One Man Think Tank hat gesagt…

@Sebastian: Ich verstehe, dass die bei Flow-Design noch etwas fehlt. Mir auch. Aber, hey, Objektorientierung hat 40+ Jahre auf dem Puckel.

Flow-Design ist zwar im Grunde auch älter, aber es steht im Schatten von OOP (oder genauer: einer Art von OOP). Wir stehen damit also erst am Anfang.

Soviel kann ich aber sagen:

Flow-Design muss nicht "vollständig" sein. C# muss eben nicht ersetzt werden. Flow-Design soll keine 4GL oder so sein. Flow-Design soll nicht in sich Turing Complete sein.

Ziel ist es, das Denken bei der Planung von OOP-Software in vorteilhafte Bahnen zu lenken.

Na, klingt das nicht sympathisch für alle OOPler?

OOP hat seinen Wert - in gewissen Grenzen. Und die müssen so einfach wie möglich abgesteckt sein. Das schafft OOAD nicht (verlässlich). Das Softwaredesaster allerorten ist der Beweis. Ich war in den letzten Wochen (wieder mal) bei mehreren Softwareunternehmen, die schlicht vor dem Aus stehen, wenn sie nicht neu entwickeln. Sie sind in der Unwartbarkeit angekommen - mit OOP.

Klar, mit OOP kann man auch anders... aber wenn das so schwer ist, dann ist OOP halt ein sehr scharfes Schwert, das nur in die Hände von Meistern gehört. Wir müssen aber mit Lehrlingen und Gesellen allerorten zufrieden sein. Und die Inderchinesenkasachenrumänen machen das nicht besser. Und C++ oder F# retten die Welt auch nicht.

Nochmal: Wer glaubt, mit OOP und seinem Vorgehen echt gut am Start zu sein, der buche mich für eine Teamstatuserhebung. Dann sehen wir, wie es läuft. Und ich brenne darauf, ein Team kennenzulernen, das saubere Software rausschnurrt.

"- Wie fügt sich Flow Design in strukturgetriebenen Frameworks oder Anwendungen ein (z.B. GUI Elemente, Spiele, Graph Algorithmen)?"

Der Einfachheit halber sage ich: Wo ist das Problem? Flow-Design ersetzt kein Framework. Wer Infragistics einsetzt oder eine Zip-Library oder WCF oder oder oder... der kann das weiter tun. Flow-Design definiert lediglich den Rahmen, in dem das geschieht.

"- Wie fügt sich Flow Design in sehr performancelastige Anwendungen (z.B. Spiele) ein?"

Gegenfrage: Wie fügt sich OOP in performancelastige Anwendungen ein? Virtuelle Methoden, GC... das alles schluckt doch Performance, oder? Also besser mal kein C# einsetzen.

Flow-Design hat keine Begrenzung nach Domäne oder bestimmten nicht-funktionalen Anforderungen. Warum ist denn das so schwer zu verstehen? Flow-Design ist zu allerst Flow-Thinking, eine andere Art zu denken. Wer mag, kann einen Flow ganz schlicht in normale Methodenaufrufe übersetzen. No problem.

"Hier scheinen mir Flow Designs noch nicht komplett zu sein, OOP ist hier flexibler."

Flow-Design ist komplett insofern, als dass es OOP nicht ersetzen will. Im Gegenteil! Erstens erfolgt eine Übersetzung von Flow-Designs immer in eine 3GL - und das kann natürlich eine OOP-Sprache sein. Wir lieben C# für seine Features wie Lambda Funktionen oder Iteratoren. Zweitens sind alle Elemente in einem Flow-Design von sich aus Objekte. Yep, richtig gelesen: Flow-Designs sind OOP-Designs.

Allerdings sieht das der nicht, der denkt, OOP sei gleichzusetzen mit OOAD. Ist es aber nicht. Dafür ist aber ein wenig "Geschichtskenntnis" der Sprachentwicklung und der Sprachenpolitik Voraussetzung.

Nicht Flow-Design beschränkt also, sondern die vorherrschende Sicht auf Objektorientierung. Und das ist die OOAD-Sicht, die Sicht, die OOP vor allem mit Daten assoziiert, d.h. die landläufige Sicht, die in jedem Forum explizit oder implizit vertreten wird und auch noch Bücher wie "DDD Applied" perpetuieren. Schade.

Ich kann nur sagen: Leute, weitet euren Blick. Echte OOP bedeutet, alles (!) ist ein Objekt. Nein, nicht nur ein int ist auch ein Objekt, sondern alles, was ihr euch denken könnt, also auch eine Tätigkeit oder eine Beziehung. Egal wie flüchtig. Das (!) ist das wahre fundamentale Umdenken, das bei OOP zuerst einsetzen muss.

Achim hat gesagt…

@Ralf: Ich hab' mich aus der Flow-Diskussion raus gehalten, weil ihr da aus meiner Sicht etwas an der Realität vorbei abstrahiert. Jetzt muß ich aber doch nochmal nachfragen:

Was ist an dem letzten Absatz deines letzten Kommentars denn neu? Tätigkeiten und Beziehungen können auch Objekte sein!? Sehe ich ganz genau so. Und jetzt? Stehe ich gerade auf dem Schlauch? Wo ist da die Neuigkeit? verwirrt ist

Ralf hat gesagt…

Hm, das ist ja schon ein gepflegter "flame war" den ihr euch hier liefert. Habt ihr schon mal in Erwägung gezogen das es unter Umständen gar nicht möglich ist Flow-Design und OOP miteinander zu vergleichen?

Die OOP bietet ein rudimentäres Gerüst aus Modellierungskonzepten mit dem sich prima Programme bauen lassen. Versuche ein höheres Abstraktionsniveau zu erreichen scheitern meist an der Tatsache, das mit Klassen, Objekten und Methoden(!) etc. immer in der Domäne eines Programmiermodells diskutiert wird. Übertragbares Design wird da sehr schnell flüchtig. Die UML lädt das Problem dann noch auf den Grafikbildschirm und ins Portfolio der Tool-Hersteller.

So etwas wie Flow-Design hilft da eher sich unter Menschen zu verständigen. Wie im Kommentar weiter oben von Ralf beschrieben, kann man Leuten durchaus die Augen für ihre konkreten Prozesse öffnen. Der Fokus liegt meiner Ansicht nach auf Mensch-Mensch-Kommunikation, wärend mit Programmiersprachen (klarer Weise!) die Steuerung einer Maschine erreicht werden soll.

Das Flow-Design irgenwo nach den 3GPLs kommen soll kann ich mir nicht vorstellen. Bildlich gesprochen könnte ich einen Flow-Design-Prozess doch auch durch ein Büro voller Sachbearbeiter implementieren, oder? Dieser Ansatz ist mir bisher noch nicht als "Programmiermodell" untergekommen ;)

Zurück zu den Programmiersprachen: Aus meiner Sicht weisen alle Sprachen die Schwäche auf, daß sie keine Konzepte zur Darstellung des Gesamtsystems bieten (und seiner Prozesse). Ein Architekt oder Designer kann damit vielleicht umgehen, unterstütz wird er in seiner Tätigkeit allerdings nicht. Versuche dort mit vorhandenem Material auszuhelfen sind dann wahrscheinlich so Sachen wie BDD und RSpec.

D'accord`?

Ralf Westphal - One Man Think Tank hat gesagt…

@Ralf: Danke für deinen "moderierenden" Beitrag.

Ich sehe da auch kein Ersetzen von OOP, auch wenn ich die "übliche" OOP-Praxis stark kritisiere.

Du hast Recht, dass Flow-Design eine etwas andere "nächste Ebene" wäre als Assembler über Maschinencode oder 3GL über Assembler.

Flow-Design hat eher etwas von der Abstraktheit von SQL oder Prolog.

Aber einerlei: Am Ende geht es mit Flow-Design eben um einen einfacheren Entwurf von imperativem Code. Dass das mit OOP "prima" ginge, sehe ich nicht. Aber darüber will ich mich nicht wieder auslassen. Lass mich gern wissen, wie du auf "prima" kommst. Ich sehe regelmäßig nur Entwickler, die sich jenseits des Trivialen sehr schwer tun, mit OO-Bordmitteln größere Softwaresysteme zu entwerfen.

Also: Flow-Design ist ein Denkwerkzeug und Entwurfswerkzeug. Wenn ich ein Flow-Design in Code übersetze... dann kommt OO-Code raus. Der geht nicht weg, der soll nicht weggehen. Der soll nur einen Platz bekommen, an dem er keinen Schaden mehr anrichtet ;-)

Ich habs grad wieder in einem Training gesehen: Wenn Entwickler in "Taschen" von OO-Code arbeiten, die durch Flow-Design in Verbindung gesetzt werden und eine Flow-Design "Oberfläche" haben, dann ist alles wunderbar. Fehlen diese Taschen... dann nimmt die Verwirrung ihren Lauf.

Als Denkwerkzeug hilft Flow-Orientation auch außerhalb des Softwareentwurfs. Das ist auch nicht neu. Value Stream Mapping oder BPM sind auch Flow-orientierte Werkzeuge.

Ich vergleiche es mal mit der Medizin:

Der kartesianische Ansatz, den Menschen als Maschine zu betrachten, hat uns weit gebracht. Mit einem schweren Schäde-Hirn-Trauma oder einem akuten Schlaganfall oder einer nach Unfall perforierten Leber oder einem offenen Oberschenkelbruch möchte ich nicht zu einem Schamanen gebracht werden.

Aber die kartesianische Medizin hat ihre Grenzen. An die stoßen wir mit Krebs, Allergien, Depressionen, Migräne und vielem anderen. Da hilft das Modell von der Menschmaschine einfach nicht.

Ähnlich sehe ich es bei der SWentwicklung. Mit OOP kommen wir ne ganze Strecke weit - aber wir stoßen an Grenzen. Da muss dann ein anderes Denken her - was OOP nicht komplett ersetzen muss. Das ist für mich Flow-Orientation mit Flow-Oriented-Architecture und -Modelling.

Ralf hat gesagt…

Das man mit OOPs prima entwerfen kann wollte ich nicht gesagt haben. Aber man kann mit ihnen überschaubare Probleme elegant lösen. Und solange man isoliert und in der Nähe des Trivialen (kleine Programme eben) operiert, lässt sich sicher ein Produktivitätsgewinn gegenüber anderen Paradigmen ausmachen.

Für das Design von ganzen Systemen eignen sie sich auch nach meiner Erfahrung nicht. Falls das so wäre, würden sie wohl Object Oriented Design Languages heißen und Sprachmittel bereitstellen um von sich selbst zu abstrahieren. Die Vermischung von Design und Programmierung stellt für mich auch die größte Schwäche der UML Klassiker dar. Zumal keine zureichende Betrachtung von Prozessen und Nicht-funktionalen Eigenschaften möglich ist.

Ich denke auch das OOP heute an der Grenze ist. Wir haben damit ausreichend von den "bare metal" Problemen abstrahiert und Nutzen erzeugt. Und das werden wir sicher auch noch weiter tun.

Ein nächster Schritt könnte Flow-Design sein. Letztlich haben es Mathematiker und Physiker ja auch irgendwie geschafft hochgradig komplexe Zusammenhänge beschreibbar zu machen. Wer weiß, vielleicht kommen wir am Ende ja bei Differentialgleichungen für Softwaresysteme heraus.

Stefc hat gesagt…

Hallo Ralf, guter Artikel. Mit etwas ähnlichen bin ich seit zwei Jahren am überlegen. Die Frage ist was ist die nächste Abstraktionsebene nach C# oder Java, also dein !

UML ist es mit Sicherheit nicht, DSL glaube ich auch nicht mehr. Ich spekuliere ja stark auf die Workbench von Intensional Software. Heiliger Gral der Softwareentwicklung ;) ?

DSL's in verschiedene Richtungen gibt es ja schon seit Jahren (z.B. SQL,XML,XAML) je länger desto besser das Tooling für solche spezifischen DSL's.

Flow-Design bzw. EBC's halte ich für vielversprechend. Allerdings müssten solche allgemeinen Container eine Art Standardisierung durchlaufen. Wäre schön wenn es einen Set von Interfaces (mit In und Out-Pin's ) für Komponenten wie Logging, Caching, Configuration gibt und das ganze mit einer Version versieht EBC LIB 1.0. Müsste ähnlich sein wie USB 1.1, 2.0, 3.0 oder DDR1, DDR2, DDR3 Memory. Ein Tooling könnte dann solche Standards aufgreifen. Die Implementierung in C# ist dann eine Ebene nach unten gewandert.

Stefc hat gesagt…

Je mehr ich darüber nachdenke, vermute ich das zwischem Flow-Design und OOP (C#,Java,etc) noch was vorher kommt.
Assembler hat aus einem Befehl (LDA 0x45) eine Bytefolge Opcodes generiert. C, Pascal wiederum haben aus einem Befehl eine Reihe Assembler Befehle generiert inzwischen IL Code. Also aus if a then wird eine Menge Maschinencode.
OOP ermöglicht jetzt eine ganze Klasse zu definieren. Die nächste Konsequenz wäre in meinen Augen also eine Sprache die Klassen generiert.
Aber wäre eine solche Sprache schon Flow-Design ?

Ralf Westphal - One Man Think Tank hat gesagt…

@Stefc: Die Sprache, die du meinst, gibt es schon: ebc.xml. Einen Compiler und Visualizer findest du bei http://ebclang.codeplex.com.