Follow my new blog

Mittwoch, 27. Februar 2008

Hört, hört! - Komponentenorientierung einmal anders

Es ist ja kein Geheimnis, dass ich ein großer Freund der Komponentenorientierung bin ;-) Aber sooft ich auch darüber spreche oder schreibe, es bleibt schwierig, Komponentenorientierung schnell begreifbar zu machen. Erklärungen am Flipchart sind trotz aller Mühe mit Verbildlichungen immer noch abstrakt. Wenn dann Code ins Spiel kommt, ist Komponentenorientierung zwar deutlich konkreter - aber es dauert halt, bis der Code geschrieben oder in seinen Zusammenhängen erklärt ist. Wie also das Verständnis von Komponentenorientierung beschleunigen?

Mit Musik! Denn schon Johannes Heesters wusste: "Mit Musik geht es am besten!" Aber nicht nur die Verzauberung schöner Fraun, sondern auch die Komponentenorientierung. Und das geht so:

Ja, ich habe keine Kosten und Mühen und Peinlichkeiten gescheut, diese didaktisch hoffentlich sehr wertvolle Demonstration von Komponentenorientierung zu produzieren :-) Mein Dank gilt dabei vor allem meiner Tochter Verena, die mir nicht die Flötentöne, sondern die Geigentöne beigebracht hat. Denn ich bin des Geigens nicht mächtig, wie man unschwer erahnen kann, oder?

Was hat das mit Komponentenorientierung zu tun?

Meine Darbietung des Stückes "Bell Ringers" besteht aus Komponenten. Jede Note darin ist eine Komponente. Ich habe das Stück ja nicht gespielt (schon gar nicht vom Blatt), sondern Note für Note einzeln aufgenommen. Hier die Produktionsschritte:

  1. Anforderungen: Der Notentext war meine Anforderung. Ziel war, das Stück am Ende komplett zu gehör zu bringen.
  2. Analyse: Aus den Anforderungen habe ich die Komponenten abgeleitet. Ich habe alle verschiedenen Noten extrahiert. Wenn das Stück vielleicht aus 40 Noten unterschiedlicher Tonhöhe und Dauer besteht, dann sind es aber nur vielleicht 8 verschiedenne Tonhöhen gewesen.
  3. Implementation: Jede Komponente habe ich einzeln implementiert. Für jede der verschiedenen Tonhöhen habe ich mit von Verena zeigen lassen, wie man sie auf der Geige spielt. (Bei einer haben wir uns aber, glaube ich, vertan. Naja, macht nix ;-) Dann habe ich die Kamera angeschaltet und nur genau diesen einen Ton gespielt. Unterschiedliche Notenlängen habe ich dabei nicht unterschieden. Ich habe einfach den Ton lang genug gespielt, so dass ich später dieselbe Aufnahme für achtel, viertel oder auch halbe Noten benutzen konnte.
  4. Integration: Schließlich habe ich die Komponenten zum großen Ganzen zusammengefügt. Im Videoschnittprogramm habe ich die 8 Videoschnippsel mit je einem Ton so aneinandergereiht, wie es der Notentext vorsieht. Jede Note kommt darin mehrfach vor, also habe ich sogar Komponenten wiederverwendet. Und es gibt sogar ganzen Notensequenzen, die sich wiederholen, also habe ich Gruppen von Komponenten (Superkomponenten oder Composite Components) auch wiederverwendet.

Der Aufbau des Gesamtstücks aus Komponenten ist natürlich unschwer zu sehen. Aber das soll auch so sein. Die "Experience" ist damit eine andere als bei einer Einspielung in einem Stück. Macht das etwas? Das hängt vom Anspruch ab.

Wer ein Musikstück "aus einem Guss" haben will, also höchsten Kunstgenuss, der muss sich einen Experten suchen, der es spielen kann. Und dieser Experte hat viel Zeit und Mühe investiert, sein Instrument zu lernen. Und das Einspielen bzw. Üben hat dann auch nochmal einige Zeit gebraucht. Was auf der Bühne so leicht aussieht, ist harte und langwierige Arbeit. Deshalb müssen Künstler auch das Einstudierte öfter spielen, weil sich sonst der Aufwand nicht gelohnt hat.

Also: Genuss aus einem Guss hat die höchste Qualität - braucht aber ein großes Budget und viel Geduld.

Vorteile der Komponentenorientierung

Ich habe nun keine Jahre beim Geigeüben verbracht. Ich habe auch keine Zeit ins Einstudieren des Stückes investiert. Ich habe stattdessen das Stück analysiert und dann die Komponenten in ausreichender Qualität implementiert und integriert. Fertig. Das Ergebnis ist zwar nicht aus einem Guss - aber immer noch gut genug und vor allem flexibel!

Erstens habe ich also viel weniger Zeit aufgewandt für ein immer noch passables Ergebnis. Ich hätte sogar die einzelnen Noten von verschiedenen Laien gleichzeitig (!) einspielen lassen können. Jede einzelne hätte dann von einem Musiker separat auf ihre Qualität geprüft werden können. Nur die besten Einzelnoten/Komponenten wären am Ende ins Ganze eingegangen. (So geschieht es auch bei Profieinspielungen im Studio. Man glaube nicht, dass das, was man auf einer CD hört, einfach so im Studio nach viel Üben "runtergespielt" wurde. Es besteht aus vielen für sich genommen perfekten Schnippseln.)

Und zweitens hat das Ergebnis nun eine Struktur, die ich auch verändern kann. Da überhaupt einzelne Komponenten vorhanden sind - die Videoschnippsel mit den einzelnen Tönen -, kann ich jede getrennt von den anderen modifizieren. Ich kann sie austauschen, in der Länge verändern, umarrangieren oder woanders wiederverwenden.

Genau das ist es nun, was Komponentenorientierung in der Softwareentwicklung will: Statt "Genuss aus einem Guss" (Monolith) lieber eine flexiblere, schneller zu produzierende und leichter zu testende Struktur aus integrierten Einzelkomponenten.

Verstehen Sie jetzt? ;-)

 

PS: Diese Analogie für die komponentenorientierte Softwareentwicklung hinkt nur in einer Hinsicht: Beim Musikstück sieht/hört man einen Unterschied zu einer Einspielung "in einem Rutsch". Bei einer komponentenorientierten Anwendung hingegen ist äußerlichen kein Unterschied zu einer monolithischen zu bemerken.

PPS: Um ehrlich zu sein, hatte ich bei der Produktion des Videos keinen Gedanken an Komponentenorientierung verschwendet. Wie im Vorspann zu lesen, wollte ich einfach eine Hommage an Lasse Gjertsen bringen. Sein Video bei YouTube finde ich einfach klasse.

Dann bin ich aber heute morgen zufällig nach längerer Zeit über mein Video gestolpert und bei einem Gespräch darüber mit meiner Freundin kam mir der Gedanke: Hey, das ist ja komponentenorientiert. Würde mich also freuen, wenn auf diese zufällige Weise aus einem Spaß jetzt etwas Nützliches würde.

Samstag, 23. Februar 2008

Entwickler machen keine Sprünge - oder: Warum Technologien manchmal so schwer zu verkaufen sind [OOP 2008]

Warum sind manche Dinge eigentlich so schwer in der Softwareentwicklung? Verteilte Anwendungen sind imperformant, SOA wird als Maximierung Webservice-Endpunkten verstanden, Anwendungen sind objektorientiert, aber leider unwartbar, ein automatischer Build ist in vielen Projekten ein Fremdwort usw. usf. Warum? Liegt es an unausgereiften Konzepten und ungenügenden Technologien?

Ich glaube, nicht. Mein aktueller Gedanke ist vielmehr, dass allzuoft in der Softwareentwicklung das Unmögliche versucht wird. Sie versucht unrealistische Sprünge zu machen. Entwickler können aber nicht springen. Sie können nur einen Schritt nach dem anderen gehen.

Um zu verstehen, was ich damit meine, zunächst ein kleiner Ausflug in die Psychologie... Sie können aber auch - ein letztes Mal ;-) - springen und gleich beim für die Softwareentwicklung relevanten Abschnitt "Ebenen der Softwareentwicklung" weiterlesen.

Bewusstseinsstufen

image Bei der Lektüre von Ken Wilber bin ich mal wieder über Integrale Psychologie und das Modell der Bewusstseinsstufen gestolpert. Nach ihr können Menschen in unterschiedlichen Bereichen (auch Linien genannt, z.B. kognitive Intelligenz, emotionale Intelligenz) auf unterschiedlichen Bewusstseinsstufen sein (auch Ebenen genanannt, z.B. Mythisch, Rational). Wieviele Bewusstseinsstufen es genau sind, dazu haben verschiedene Schulen auseinandergehende Meinungen. Über drei ganz grobe herrscht jedoch wohl Einigkeit:

  • Bewusstseinsstufe 1: Prä-Konventionell, egozentrisch
  • Bewusstseinsstufe 2: Konventionell, gruppenzentrisch
  • Bewusstseinsstufe 3: Post- oder Trans-Konventionell, weltzentrisch

Die geistige Entwicklung eines Menschen verläuft in vielen Linien von der niedrigsten Stufe zu höheren. Auf den unterschiedlichen Linien kann er auf verschiedenen Ebenen sein. Die höchste Ebene - allemal in sehr feingranularen Bewusstseinsstufenmodellen - erreichen allerdings nur die allerwenigsten.

Ausgangspunkt der Entwicklung bei allen Menschen ist eine egozentrische Weltsicht. Auf dieser Ebene sind Menschen selbstbezogen, ihr eigenes Wohl ist ihnen am wichtigsten. Neugeborene und auch noch Kleinkinder sind ganz natürlich auf dieser Ebene. Alles muss sich um sie drehen. Sie müssen komplett versorgt werden, also fordern sie das auch ein. Alles geht auf dieser Ebene - solange es unsere Bedürfnisse befriedigt.

Erst allmählich lernen wir dann, von uns selbst abzusehen. Da sind noch andere Menschen in unserer Umgebung, die gehören zu uns. Wir dürfen sie nicht aus dem Blick verlieren, weil es uns sonst schlecht erginge. Die gruppenzentrische Bewusstseinsstufe wird erklommen. Um mit den anderen auszukommen oder sie uns gar wohlgesonnen zu stimmen, lernen wir, uns an Regeln zu halten. Diese Konventionen sind gruppenspezifisch und halten sie zusammen. Familien, Clans, Dorfgemeinschaften, Nationen oder Glaubensgemeinschaften sind Beispiele für solche Gruppen, denen wir uns auf der 2. Bewusstseinsstufe zugehörig fühlen.

Geht die Bewusstseinsentwicklung weiter, dann erkennen wir, dass die Welt nicht nur aus unserer Gruppe besteht. Da sind andere Gruppen mit anderen Konventionen. Wir lernen unsere bisherigen Konventionen zu transzendieren. Die Gruppe wird ein Teil der größeren Welt. Unser Bewusstsein lässt Pluralität nicht nur zu, sondern freut sich an ihr; wir sind weltzentrisch. Das bedeutet nicht, dass wir nach keinen Regeln mehr leben würden. Regeln verlieren nur ihren Absolutheitsanspruch. Wir wählen unsere Regeln selbst - und fühlen uns frei, sie zu hinterfragen und neu zu definieren.

Unmöglich zu springen

Keine dieser Bewusstseinsebenen ist gut oder schlecht. Sie stellen einfach nur Entwicklungsstufen dar. Es sind Haltepunkte auf einem Lebensweg. Wie lange jemand auf ihnen verweilt, ist ganz unterschiedlich. Zu welcher Bewusstseinsstufe er in welcher Linie es während seines Lebens schafft, auch das ist ganz unterschiedlich.

Zentral für das Verständnis dieser Ebenen ist, dass keine übersprungen werden kann. Wir können nicht ohne egozentrisch gewesen zu sein einfach bei Gruppenzentrizität beginnen. Jeder muss auf allen Ebenen unterhalb seiner aktuellen gewesen sein. Es gilt - wenn auch auf einen unüblichen Bereich angewandt - das alte natura non facit saltus.

Ein Vergleich mit der Musik

image Ebene 1: Sehr kleine Kinder leben in ihrer eigenen Musik- oder besser Tonausdruckswelt und produzieren eher Krach. Sie kennen noch keine musikalischen Konventionen. Sie sind egozentrisch, wenn sie einfach Spaß an Klanghölzern oder Trommeln haben - der allerdings Erwachsene die Flucht ergreifen lässt. Durch Anleitung betreten Kinder dann die Welt der Kinderlieder. Sie singen einfach. Und wenn es ihnen immer noch Spaß macht, dann singen sie laut und häufig und auch unerschrocken falsch. Sie haben die Egozentrik noch nicht verlassen.

image Ebene 2: Im nächsten Schritt lernen Kinder dann ein Instrument und betreten damit die Ebene der Konventionen. Sie werden mit Regeln vertraut gemacht, wie Musik in ihrer Gruppe sich anzuhören hat. Diese Regeln sind für abendländische Kinder anders als für indische. Zunächst sind die Melodien einfach, dann werden die Musikstücke immer komplizierter. Von der klassischen Musik bis zur Pop-Musik regieren die Konventionen.

image Ebene 3: Aber auch Jugend Musiziert Preisträger oder gar Orchestermusiker können sich noch weiterentwickeln. Sie können zum Einen über ihre Musikkonventionen hinausblicken und die Vielfalt der Musiktraditionen schätzen oder gar anwenden lernen. Weltmusik ist das Ergebnis. Zum Anderen können sie ihre Konventionen transzendieren und z.B. Gefallen an Jazz finden oder sich an 12-Ton-Musik versuchen. Auch wenn Jazz und 12-Ton-Musik immer noch Regeln unterliegen, definieren sie doch eine höhere "Musikbewusstseinsebene" als Volkslieder, weil sie deren Konventionen anerkennen, reflektieren und dann über sie hinausgehen.


Jede Bewusstseinsstufe definiert sozusagen einen Horizont, bis zu dem und innerhalb dessen Umkreis wir die Welt wahrnehmen. Was wir wahrnehmen, beziehen wir immer auf das innere dieses Gesichtskreises. Auf der präkonventionellen Ebene beziehen wir alles auf uns; unser Wohlbefinden steht im Mittelpunkt. Alles wird daraufhin eingeordnet: Ist es gut für uns, ist es schlecht für uns? Dasselbe gilt für die Gruppe auf Ebene 2 und für die Welt auf Ebene 3.

Bewusstseinsebene bedeutet, dass wir unfähig sind, die Welt anders zu sehen. Wir können nicht umhin, alles auf uns oder unsere Gruppe zu beziehen. Deshalb sind wir ja auf Ebene 1 oder 2. Bewusstseinsstufen sind wie Brillen, die wir nicht abnehmen können. Allerdings können wir uns immer höher entwickeln, sozusagen die Tönung der Brille ändern und ihren Blickwinkel erweitern.

Der Prä-/Trans-Trugschluss

Auf welcher Bewusstseinsebene befindet sich nun ein Mensch? Um bei den drei groben Ebenen zu bleiben: Ist er egozentrisch oder konventionell oder transkonventionell? Interessanterweise kann man das nicht so einfach bestimmen, sagt die Theorie. Denn oberflächlich (!) können prä- und transkonventionelle Menschen in ihren Sichtweisen/Antworten/Handlungen gleich aussehen.

image Auf die Frage, "Darf man bei Rot über die Ampel gehen?" würden die Antworten von Menschen auf Ebene 1, 2 und 3 lauten: Ja, Nein, Ja.

  • Ebene 1: "Ja, klar! Ist mir doch egal, was die Ampell zeigt. Ich geh´ rüber, wenn´s mir passt."
  • Ebene 2: "Nein, man darf nur gehen, wenn die Ampel grün zeigt. Wo kämen wir hin, wenn niemand mehr auf die Verkehrsregeln achten würde?"
  • Ebene 3: "Ja, man darf auch bei Rot gehen, wenn die Umstände es zulassen oder gar gebieten."

Anhand der knappen, oberflächlichen Ja/Nein-Antwort lassen sich prä- und transkonventionelle Menschen also nicht so einfach unterscheiden. Die Theorie nennt das den Prä-/Trans-Trugschluss: Menschen werden aufgrund ihrer Antwort auf Ebene 3 angesiedelt, obwohl sie sich noch auf Ebene 1 befinden.

Macht das etwas, die Antwort ist doch gleich? Ja. Einen Egozentriker nicht zu erkennen, kann sehr schädlich sein. Hinter seinem Ja im obigen Beispiel steht kein Verantwortungsbewusstsein; das gehört einfach nicht zu seiner Bewusstseinsstufe. Wenn jemand auf einer unteren Ebene meint, er sei schon auf einer höheren, kommt es also mindestens zu Missverständnissen und Friktionen, wenn nicht gar zu ausgewachsenen Konflikten. Ebene n hat einfach einen anderen Horizont als Ebene n+1. Was auf Ebene n+1 sichtbar ist, mag Ebene n unsichtbar sein. Dann wird es schwer, solches (noch nicht) Sichtbare zu verstehen. Menschen auf einer Ebene müssen sich überfordert fühlen, wenn sie mit Fragen und Konzepten höherer Ebenen konfrontiert werden. Einem Erstklässler das Weltfinanzsystem erklären zu wollen, kann nicht gelingen.

Ein Vergleich mit der Musik

image Dem musikalischen Laien erscheint womöglich das quasi ununterscheidbar gleich, was kleine Kinder an Musik produzieren und was atonale Musiker von Weltrang wie Arnold Schönberg komponieren. Der übliche musikalische Laie steht jedoch auf Ebene 2 und versucht nun Ausdrücke der ihm bekannten Ebene 1 mit der ihm (noch) unverständlichen Ebene 3 zu vergleichen. Das muss scheitern; es ist also kein Wunder, dass es zu Prä-/Trans-Verwechslungen kommen kann.


Aber nochmal: Sich auf einer Ebene zu befinden, ist weder gut noch schlecht, richtig oder falsch. Alle Menschen fangen auf der untersten Stufe an. Und aus den unterschiedlichsten Gründen entwickeln sie sich mehr oder weniger weit.

Ebenen der Softwareentwicklung

Mir scheint das Modell der Bewusstseinsebenen und Entwicklungslinien so plausibel und nützlich, dass ich es nun auf die Softwareentwicklung anwenden möchte. Ich glaube, es gibt Ebenen der Softwareentwicklung, es gibt unterschiedliche "Bewusstseinsebenen" für Softwareentwickler, d.h. Stufen ihrer Entwicklung.

Zunächst einmal sehe ich dafür in der Softwareentwicklung eine eigene Linie. Ich nehme einfach mal soetwas wie einen SEQ, einen SoftwareEntwicklungsintelligenzQuotienten an. So wie Menschen einen unterschiedlichen IQ oder EQ (Emotional intelligence) haben, so haben Softwareentwickler auch einen SEQ. Der mag zu einem gewissen Teil unveränderlich sein, aber ganz sicher kann er durch Ausbildung und Übung stark entwickelt werden.

Wie andere Bewusstseinslinien läuft die des SEQ nun auch von niedrigen zu höheren Bewusstseinsebenen, d.h. Stufen mit einem immer weiteren Horizont und tieferer Reflektion. Hier mal ein Vorschlag für diese SEQ-Ebenen. Ich benenne sie einfach mit dem Konzept, das ich bei ihnen für jeweils besonders charakteristisch halte. Sie stellen für mich den zentralen Lerninhalt oder Fokus dar.

image 

Die Entwicklung des Softwareentwicklers beginnt beim Algorithmus, d.h. bei Anweisungssequenzen. Er lernt, Statements zur Lösung eines Problems aneinander zu reihen: Ausdrücke, Zuweisungen, Kontrollstrukturen. Das EVA-Prinzip und die Trennung von Daten und Funktionen gehören auf diese Stufe.

Auf der nächsten Ebene werden Anweisungen zu Gruppen zusammengefasst und durch Unterprogramme wiederverwendbar gemacht. Der Softwareentwickler lernt, wie er selbst Funktionen als Zusammenfassungen von Anweisungen definieren kann. Auf der Algorithmus-Ebene hat er sie nur genutzt. Zur Ebene 2 gehören auch Konzepte wie Scope und die Unterscheidung zwischen Stack und Heap.

Die nächste Ebene ist wieder durch eine Zusammenfassung charakterisiert: Objekte/Klassen fassen Daten und Funktionen zu Strukturen auf dem Heap zusammen. Das ist der entscheidende Schritt über Ebene 2 hinaus. Vererbung halte ich für nicht so essenziell, dass sie schon auf dieser Ebene gemeistert werden müsste.

Ebene 4 bricht mit dem rein sequenziellen Programmiermodell. Bisher hier war die Reihenfolge, in der Anweisungen abgearbeitet wurden, klar aus dem Quellcode ablesbar. Mit Funktionszeigern können Funktionen jedoch so parametrisiert werden, dass man ihrem Quellcode nicht mehr ansehen kann, woentlang der Kontrollfluss in welchem Fall genau fließt; das kann nämlich vom Inhalt von Funktionsvariablen abhängen. Ruft eine Anweisung eines solche Variable auf, feuert sie über diesen Callback einen Event, der an einer Stelle bearbeitet wird, die nur dem bekannt ist, der die Variable gesetzt hat. Das kann eine aufrufende Funktion sein. Da virtuelle Methoden Funktionszeiger voraussetzen, scheinen mir Vererbung und abstrakte Klassen auch in diese Ebene zu gehören.

Ebene 4 der SEQ schließt für mich die grundlegendere Stufe der Egozentrik ab. Bis hier konnte der Softwareentwickler sich mit seinem Code allein wähnen. Das ändert sich mit Ebene 5...

Auf der nächsten Ebene lernt der Softwareentwickler, dass Funktionen auch gleichzeitig ausgeführt werden können. Sie können auf verschiedenen Threads zusammen versuchen, ein Ziel zu erreichen. Dafür müssen sie Regeln einhalten. Parallelität braucht Konventionen für die Koordination der konkurrierenden Funktionen und den gemeinsamen Ressourcenzugriff.

Aber nicht nur Funktionen können parallel laufen. Auch die Softwareentwicklung findet parallel statt. Komponenten (d.h. binäre Codeeinheiten mit separater Spezifikation) sind zur Organisation paralleler Entwicklung sehr hilfreich. Sie isolieren Entwickler und Entwicklungen von einander (Komplexitätsreduktion), machen produktiver (echte Parallelentwicklung aller Komponenten) und erleichtern punktgenaues Testen (durch separate Kontrakte begünstigte Attrappen). Um quasi industriell im Team zu entwickeln, sind also Konventionen einzuhalten: Architektur, Komponentenstruktur, IoC, Attrappen sind solche Konventionen, die die Zuammenarbeit erleichtern.

Auf der nächsten Ebene wird der bisherigen "Parallelität im Kleinen" zu Steigerung von Responsiveness und Performance eine "Parallelität im Großen" gegenübergestellt. Anwendungen, die aus mehreren Prozessen bestehen, verteilen ihren Code zur parallelen Ausführung, um skalierbarer oder noch performanter zu sein. Am einfachsten ist die Kommunikation zwischen diesen Prozessen mittels RPC. Für eine grundsätzliche Verteilung muss zu den bis hierher vertrauten Konzepten also nur wenig dazugelernt werden. C/S, COM+, Webservices und .NET Remoting gehören auf diese Ebene. Die Konventionen von Ebene 7 sind z.B. die Kontrakte der verteilten Kommunikation und die Planung des Deployments bzw. der Administration. Die Prozesse in einer verteilten Anwendung müssen sich auf einander verlassen können.

Mit Ebene 7 ist die Entwicklung gruppenzentrischer Entwicklerbewusstheit abgeschlossen. Der Softwareentwickler hat gelernt, dass er mit seinem Code nicht allein ist. Zur Laufzeit und im Entwicklungsprozess gibt es Parallelität, die zur Einhaltung von Regeln zwingt. Wer diese Regeln bricht, muss nicht nur für sich Konsequenzen gewärtigen, sondern beeinflusst immer auch andere.

C/S und RPC sind Konzepte für überschaubare Anwendungen. Was aber, wenn die Applikationen weiter wachsen? Nachrichtenorientierung ist das Mittel, um über eine kleine Gruppe von Prozessen hinaus zu blicken. Sie akzeptiert, dass es auch andere Plattformen geben kann; sie akzeptiert, dass verteilte Kommunikation ganz anderen Kriterien folgen muss als lokale. RPC versucht die Verteilung mit Mitteln der lokalen Kommunikation zu kaschieren. Entwickler glauben dadurch, mit ihren lokalen Konventionen auch verteilte Anwendungen realisieren zu können. Das ist aber ein Trugschluss - und mit dem räumt die Nachrichtenorientierung auf. Sie transzendiert also die ego- und gruppenzentrischen Konventionen und Konzepte und öffnet den Blick für eine weitere Welt mit anderen Regeln, die einen bewussteren Umgang erfordern.

Nachrichtenorientierung ist trotz ihrer Kritik an RPC allerdings zunächst immer noch der Punkt-zu-Punkt-Kommunikation verhaftet. Auch nachrichtenorientiert angesprochene WCF-Servicemethoden sehen mehr oder weniger aus wie lokale Funktionen. Das ändern Event-driven Architectures (EDA). Wie lokale Events kehren sie das Denken um. Services werden nicht mehr direkt kontaktiert, sondern auf Warteschlangen oder Bussen (Enterprise Service Bus) registriert. Das entkoppelt Clients und Services massiv; die Client-Service-Regeln wird transzendiert. Die Orts- und Plattformunabhängigkeit steigt.

Mit SOA werden schließlich verteilte Funktionalitäten auf höherer Ebene wiederum zusammengefasst. Zeit und Ort und Granularität für Dienstleistungen unterliegen keinen Konventionen mehr, die Prozess, Maschine oder Plattform vorgeben könnten. Services können über das Internet weltweit verteilt werden. Softwareentwicklung ist damit auf einer wahrhaft weltzentrischen Ebene angekommen.

Konsequenzen des Ebenenmodells für die Softwareentwicklung

Ob die Ebenen der Entwicklung eines Softwareentwicklungsbewusstseins nun genau so geschnitten sind oder in dieser Reihenfolge aufeinander liegen sollten, finde ich nicht so wichtig. Ich halte den obigen Vorschlag für ausreichend gut, um ihn als Erklärungs- und Planungsmodell zu nutzen. Er muss nicht final, sondern nur angemessen sein. Nicht welche Ebenen genau es gibt, sondern dass es überhaupt Ebenen gibt, ist entscheidend.

Dass mein Vorschlag von einigen derzeit kanonischen Vorstellungen abweicht, ist mir bewusst. Dennoch habe ich die Ebenen so angeordnet, weil sie mir so am plausibelsten bzw. natürlichsten erscheinen. Aber ich bin offen für Alternativvorschläge.

Was nützt der ganze Aufwand aber nun? Wozu dieses Modell? Ich meine, es hilft, heutige Probleme zu erklären und sie zukünftig zu vermeiden. Darüber hinaus bzw. deshalb hilft es aber auch, Ausbildung zu planen.

Seiner Erklärungskraft liegen drei Annahmen zugrunde:

  1. Annahme - Entwicklungsstreuung: Softwareentwickler befinden sich auf ganz unterschiedlichen Ebenen.
  2. Annahme - Fehlerhafte Selbsteinschätzung: Softwareentwickler wähnen sich oft auf einer höheren Ebene, als sie tatsächlich schon erreicht haben.
  3. Annahme - Fehlerhafte Fremdeinschätzung: Softwareentwickler werden von anderen auf einer höheren Ebene als der erreichten angesiedelt.

Dass Softwareentwickler sich auf unterschiedlichen Ebenen befinden, kann - so glaube ich - kaum strittig sein. Ausbildungen und Erfahrungshintergründe sind einfach unendlich vielfältig.

Angesichts eines gewöhnlich weniger differenzierten Entwicklungsbildes werden die Konsequenzen solch unterschiedlicher Entwicklung falsch eingeschätzt. Wo es nur 2 oder 3 sehr allgemeine Entwicklungsstufen gibt, z.B. Junior Programmer, Senior Programmer und, hm, Architect, da fällt auch die Wahrnehmung von Unterschieden (oder weniger neutral: Defiziten) anders aus. Man glaubt allemal, sie ließen sich relativ leicht ausgleichen. Eine Schulung in einer neuen Technologie und fertig.

Das halte ich aber für einen fundamentalen Trugschluss. Zusammen mit der Prämisse, dass Entwicklungsstufen nicht übersprungen werden können und den vorstehenden Annahme, ist für mich vielmehr deutlich, warum verteilte Anwendungen trotz oder wegen WCF immer noch vielen Entwicklern Probleme machen. Und mir ist nun auch klar, warum die SOA-Botschaft nicht so ankommt, wie sie ankommen könnte oder sollte.

Wenn WCF (Ebene 8) Entwicklern nahegebracht werden soll, die gerade mal Ebene 4 (Events) gemeistert haben, dann kann das nicht wirklich funktionieren. Wenn SOA (Ebene 10) gepredigt wird, wo gerade mal RPC (Ebene 7) verstanden wurde, dann kann das nicht wirklich funktionieren.

Technologie- und Konzeptverkäufer kennen ihr Publikum zu wenig. Sie sind ihnen oft um Ebenen voraus. Das liegt an der nur groben Klassifizierung von Entwicklerbewusstheit/-erfahrung. Es kommt nicht darauf an, WCF oder SOA usw. einfach nur Entwicklern mit einer bestimmten Zahl von Berufsjahren zu predigen. Es kommt darauf an zu erkennen, auf welchem Bewusstseinslevel sie sind, ja, sein können.

Bewusstseinslevel mag mit Berufsjahren korrelieren - aber einen Kausalzusammenhang gibt es so einfach nicht. Wer SOA säen will, der sollte also nicht fragen, wieviele Berufsjahre im Publikum der Durchschnitt sind, sondern ob der Durchschnitt der Entwickler Ebene 9 erreicht hat. Denn nur wer Ebene 9 gemeistert hat, kann wirklich auf Ebene 10 klettern. Allen anderen ist das Verständnis für das, was Ebene 10 will, mehr oder weniger verschlossen.

Und nochmal: Das ist keine Wertung. Auf der einen oder anderen Ebene zu sein ist weder gut noch schlecht. Schlecht ist allerdings eine fehlerhafte Selbst- oder Fremdeinschätzung. Ihre Folge sind nämlich falsche Anwendungen von Technologien und Konzepten. Und das kostet viel Zeit und Geld.

Zu erkennen, auf welcher Ebene sich ein Entwickler befindet, ist nun durch den Prä-/Trans-Trugschluss nicht leicht. Entscheidet er sich für den Einsatz einer Technologie (z.B. RPC), weil er die Alternativen abwägen konnte (Trans) oder weil er keine Alternativen hatte (Prä)?

Ergebnis 1: Ich glaube, dass Tools, Technologien und Konzepte heute vielfach falsch eingesetzt werden, weil Entwickler versuchen mit ihnen umzugehen, deren SEQ-Bewusstseinsstufe ihrem Einsatz noch nicht entspricht. Da hilft dann auch kein Schnellkurs, der würde nämlich einen Sprung versuchen. Springen ist aber unmöglich. Helfen kann nur, die fehlenden Ebenen schrittweise zu erklimmen.

Niemand schätzt sich oder andere willentlich falsch ein. Fehleinschätzungen wird vielmehr durch eine undifferenzierte Betrachtung der Entwicklung von Programmierkompetenz Vorschub geleistet. Und auch der Glaube an eine ausreichende Ausbildung tut seinen Teil dazu.

Mein Informatikstudium vor 20 Jahren (also noch vor der Objektorientierung) hat mich lediglich durch die ersten drei Ebenen  (Algorithmus, Funktion und Event/Callback) geführt. Von Parallelität und RPC habe ich dort nichts gehört. Ein Arbeitgeber (oder Technologieanbieter) hätte aber natürlich zurecht angenommen, dass ich auch die Ebenen dank meiner Ausbildung gemeistert habe. Ein Trugschluss.

Heute ist es nicht sehr anders. Von einem Dipl-Informatiker oder BA-Absolventen kann man nicht mehr Ebene 4 erwarten. Darüberliegende Ebenen werden vielleicht in Vorlesungen gestreift, doch das ist nicht gleichzusetzen mit ihrer Meisterung. Eine SEQ-Bewusstseinsebene wirklich zu erreichen bedeutet, mit ihren Technologien und Konzepte wirklich gründlich Erfahrungen gesammelt zu haben. Kann das aber durch die Bank von Informatikstudenten in Bezug auf Parallelverarbeitung oder Komponentenorientierung gesagt werden? Kaum.

Wie gesagt: Es geht nicht darum, dass diese Ebenen in der Ausbildung nicht gestreift würden. Aber solide Bewusstseinsbildung findet nicht statt. Solange in der Ausbildung nicht ausgiebig Erfahrung mit Semaphoren, Deadlockvermeidungsstrategien oder Koordinationsdatenstrukturen gesammelt wird, kann von einem Bewusstsein auf Ebene 5 nicht gesprochen werden. Dasselbe gilt für Contract-first Design, IoC, IDL, Attrappen und schließlich automatische Builds, die aus meiner Sicht zu Ebene 6 gehören.

Projektverantwortliche nehmen aber legitimerweise an, dass zur Ausbildung gehört, alle Ebenen der Softwareentwicklung so tiefgehend zu behandeln, dass am Ende Softwareentwickler stehen, die zumindest sicher auf Ebene 8, wenn nicht sogar auf Ebene 9 oder 10 zu verorten sind.

Leider ist das nicht die Realität. Deshalb kommt es zu Fehleinschätzung. Deshalb kommt es zu teuren Fehlnutzungen von Technologien und Konzepten.

Ergebnis 2: Die Ausbildung sollte ein klares Ebenenkonzept wie oben entwickeln und am state-of-the-art ausrichten. Und sie sollte dafür sorgen, dass ihre Absolventen je nach Abschluss ein gut ausgeprägtes und SEQ-Bewusstsein auf erwartbarer Ebene haben. Erwartungshorizonte für die einzelnen Ebenen sollten mit der Industrie abgestimmt oder zumindest öffentlich sein. Die derzeitigen Curricula sind ein guter Ausgangspunkt, aber ihnen mangelt es an einem expliziten Ebenenkonzept. Sie lassen sich deshalb schwer vergleichen und stehen in keinem Gesamtzusammenhang. An ihnen kann nicht abgelesen werden, wieviel Anteil an einem Maximalbild sie haben.

Ergebnis 3 und Fazit: Ich halte es für sehr nützlich, die Softwareentwicklung insgesamt und den einzelnen Softwareentwickler ins Verhältnis zu einem SEQ-Bewusstseinsstufenmodell zu stellen. Ob es das obige oder ein anderes ist - egal. Solange die Prämisse anerkannt wird, dass es überhaupt Stufen gibt und höhere nicht "angesprungen", sondern ausschließlich durch Schritte über niedrigere erreicht werden können, solange ist es mir recht. Eine Differenzierung in mehr als 4-5 Ebenen setze ich ebenfalls voraus.

Mir hat diese Strukturierung der Softwareentwicklung jedenfalls schon sehr geholfen. Wenn es zu Missverständnissen kommt oder ich Unverständnis bemerke, dann kann ich jetzt viel gezielter abklopfen, wo es hakt. Durch Fragen kann ich leicht klären, auf welcher SEQ-Stufe Gesprächspartner stehen. Wenn ich das weiß, kann ich zusammen mit ihnen überlegen, wie ich ihnen auf die für ihre Situation nötige Ebene hinaufhelfe. Das mag dann etwas Zeit kosten - am Ende ist es aber unumgänglich. Entwickler machen einfach keine Sprünge.

Dienstag, 19. Februar 2008

dotnetpro.tv lernt von Willi, oder: Zufällige Begegnung relativer Prominenter

dotnetpro.tv macht ja gerade eine Kreativpause. Nach mehr als 30 Folgen habe ich einfach mal über ein Redesign nachdenken wollen. Eigentlich hatte ich auch schon eines in petto... aber dann habe ich Willi getroffen. Willi ist nämlich einer meiner Helden aus dem Fernsehen. Oder genauer: Willi ist der Moderator einer tollen "Welterklärungsserie" für Kinder - "Willi wills wissen" -, die ich immer mit meiner Tochter schaue. Die Sendung mit der Maus war sozusagen gestern ;-) Heute ist Willi. (Naja, und "Wissen macht Ah!" und "pur+" - jedem Sender seine "Welterklärung" ;-) Aber alle gut gemacht. Da kann man echt was lernen. Sehr kurzweilig!)

Neulich hab ich also Willi auf dem Münchener Flughafen getroffen. Allerdings war ich der einzige, der ihn erkannt hat. Keine Paparazzi, die ihn umlagert hätten. Nix. Keine Köpfe, die sich ihm nachdrehten. Kein Getuschel "Hast du den gesehen? Der ist doch aus dem Fernsehen..."

image

Zuerst dachte ich nur, "Hm... den kenn ich doch. Sollte ich ihn grüßen? Hab ich den grad auf der VSone gesehen?" Aber dann fiel mir zum Glück sofort ein, woher ich den kenne, dass es der Willi war. Schließlich hab ich dann Mut gefasst und ihn einfach angesprochen. Willi war total nett - wie man ihn halt aus seinen Sendungen kennt -, bedauerte, keine Autogrammkarten dabei zu haben - war aber sofort bereit für den obigen Schnappschuss. Der war allerdings gar nicht so einfach (deshalb schaue ich auch etwas verkniffen), weil ich mit der Handykamera tüfteln musste, um uns beide abzulichten. Autogramme waren außerdem auch gestern, würd ich sagen. So ein gemeinsames Bild mit dem persönlich Helden hat doch viel mehr, oder?

Wie die Reaktionen bzw. Nicht-Reaktionen auf dem Flughafen allerdings zeigten, ist Prominenz relativ. Ein andermal saß ich am Gate neben Klinsi und der Bayern-Elf. Da war deutlich mehr los. Autogrammjäger allerorten. Aber um Willi war es still. Mag auch etwas über die Kinderaffinität zumindest der Fluggäste aussagen. Hm... Mich hat auch keiner erkannt. Das sagt etwas aus über die .NET-Affinität der Fluggäste, meine ich mal ;-) So kommt es eben auf die größe der Gruppe an, in der man gekannt ist. Ein paar Tausend .NET-Entwickler im deutschsprachigen Raum, ein paar Hunderttausend Kinder im deutschsprachigen Raum - oder Millionen Menschen weltweit. Naja... egal... zurück zu dotnetpro.tv.

Von Willi lernen

Eigentlich hab ich Willi vor allem angesprochen, um ihm danke für seine tolle Sendung zu sagen - und anschließend meiner Tochter ein kleines Abenteuer erzählen zu können ;-)

image Aber dann hat mich diese Begegnung angestoßen, nochmal über dotnetpro.tv nachzudenken. Wie gesagt, eigentlich hatte ich das neue Format schon in der Tasche. Was mir nun aber aufging war, dass dabei etwas unter den Tisch fallen würde, was ich an Willis Sendung so gut finde: Menschen in ihrem Umfel.

Willi erklärt die Welt (vom Bierbrauen über den Rangierbahnhof bis zur Beerdigung) vor Ort. Er ist bei den jeweiligen Experten vor Ort dort, "wo sie es tun". Er spricht mit ihnen an ihrem Arbeitsplatz während sie arbeiten. Kein Studio, keine Abstraktion, keine Schaubilder. Willi steht mit im Prozess und versucht es auch mal selbst.

Das funktioniert natürlich auch durch seine ansteckend gute Laune. Aber viel wichtiger ist, dass er die Menschen unmittelbar und im doppelten Sinn "im Bild" hat. Wir lernen einfach besser, wenn Menschen uns etwas vorleben und zeigen. Sobald sie sich rausziehen aus der Erklärung, desto abstrakter wird es. Schon eine Stimme aus dem Off, selbst wenn noch Menschen zu sehen sind, erhöht die Distanz.

Gerade das wollte ich aber (wieder) bei dotnetpro.tv einführen: eine Stimme aus dem Off. Das mache ich jetzt aber nicht mehr. Dank Willi bleiben nun nicht nur die Menschen mehr im Programm bei dotnetpro.tv, sondern werden auch noch mehr. Ich werde mich wieder - wie damals bei dotnet.tv - vor die Kamera verfügen. Und der Experte wird auch vor der Kamera bleiben. Und wir werden beide nicht aus dem Off sprechen. Und ich möchte auch erreichen, dass wir beide am "Expertengegenstand" zusammen und sichtbar "arbeiten". So ist's bei Willi, so soll es auch in Zukunft mehr bei dotnetpro.tv sein. Mehr Menschen, mehr Interaktivität vor der Kamera. Sozusagen das Beste aus dotnetpro.tv und dotnet.tv garniert und verfeinert mit Willi-inspirierter Interaktion direkt "an der Sache".

Jetzt sind noch ein paar Produktionsdetails zu klären - und dann kann es wieder losgehen mit dotnetpro.tv.

Sonntag, 17. Februar 2008

Warum Veränderung es schwer hat in der Softwareentwicklung [OOP 2008]

Grad lese ich "The Art of Change" von Loebbert und muss innehalten, weil mir aufgeht, was oft schiefgeht. In den Gesprächen auf der VSone und anschließenden Architekturworkshop habe ich immer wieder Aussagen gehört wie: "Ich würde gerne anwenden, was Sie sagen, aber in unserem Unternehmen geht das nicht. Der Chef/der Projektleiter/... sagt immer, dass das früher ja auch nicht nötig war."

Auf die genaue Begründung, die dem Chef/Projektleiter usw. in den Mund gelegt wird, kommt es nicht an. Gemeinsam ist allen, dass den Führungspersonen keine Einsicht in die Notwendigkeit eine Veränderung in den Mund gelegt wird.

Angesichts meiner Lektüre habe ich mich nun gefragt, was es so schwierig macht, Veränderungen in der Softwareentwicklung anzuregen und durchzuführen. Meine heutige Erkenntnis: Es ist so schwierig, weil es Missverständnisse gibt und Wahrnehmungsorgane fehlen.

Ordnungen der Veränderung

Missverständnisse beim Gespräch über Veränderungen rühren von einer undifferenzierten Betrachtung her. Die an der Softwareentwicklung beteiligten glauben nämlich oft, dass Veränderungen nicht nötig seien, weil sie ja ohnehin schon die ganze Zeit in einer Projektsituation leben, die von Veränderungen nur so strotzt. Warum also noch mehr verändern, wenn die ständigen Veränderungen heute schon an den Rand des Machbaren gehen?

Undifferenziert ist diese Sichtweise, weil sie alle Veränderungen in einen Topf schmeißt. Neue Funktionalität, neue Technologien, neue Teamorganisation: das alles ist einerlei.

Um notwendige Veränderungen plausibler zu machen, scheint mir daher zunächst wichtig, genauer hinzuschauen. Ich teile Veränderungen daher mal in 5 Ordnungen ein:

0. Ordnung: Veränderungen im Sinne eines Kunden sind für mich Veränderungen 0. Ordnung. Ein neues Feature, eine Fehlerkorrektur, höhere Performance... wird Software modifiziert, um funktionale und nicht funktionale Anforderungen zu implementieren, sind das Veränderungen 0. Ordnung. An ihnen ist aber nicht nur der Kunde interessiert. Sie sind es auch, auf die Führungskräfte besonders ihren Blick richten.

1. Ordnung: Bei Veränderungen 1. Ordnung werden Materialien verändert. Holz wird zu einem Schrank verarbeitet, APIs und Daten zu einer Software. Wenn einer ein Werkzeug in die Hand nimmt (z.B. Visual Studio), damit Material bearbeitet (z.B. den WinForms API) und zu einem Produkt zusammenfügt, dann ist das eine Veränderung 0. Ordnung. Das, was zu tun ist, ist klar. Es muss nur einfach getan werden. Dabei verändern sich die Rohstoffe hin zum Produkt im Sinne der Kundenanforderungen. Das ist die tägliche Arbeit der Softwareentwickler. Veränderungen 1. Ordnung werden vorgenommen, um Veränderungen 0. Ordnung zu bewirken.

2. Ordnung: Veränderungen 1. Ordnung finden in einem Rahmen statt. Das ist die Grundstruktur oder auch Architektur einer Software. Wenn sich dieser Rahmen ändert, dann ist das eine Veränderung 2. Ordnung. Sie ändert nichts an der Rohstoffveränderung/-verarbeitung, nichts an den Features einer Software, sondern nur die strukturellen Zusammenhänge, in denen die Veränderungen 0. und 1. Ordnung stattfinden. Ziel von Veränderungen 2. Ordnung ist das technische Fundament, auf dem Software ruht.

3. Ordnung: Was hergestellt wird, ist eingebettet in einen Herstellungsprozess. Veränderungen an ihm sind Veränderungen 3. Ordnung. Hierzu zähle ich z.B. die Einführung von Unit Tests oder Continuous Integration oder den Umstieg von VSS auf TFS. Werden diese und andere Konzepte bzw. Werkzeuge eingeführt, die die Art ändern, in der Code produziert wird, dann geht es um Veränderungen 3. Ordnung.

4. Ordnung: Schließlich kann sich auch noch der Rahmen ändern, in dem der Herstellungsprozess abläuft. Wenn Teamorganisation und Vorgehensmodell verändert werden sollen, dann sind das Veränderungen 4. Ordnung. Früher ad hoc Tests, heute Unit Tests - das ist eine Veränderung 3. Ordnung. Aber früher ad hoc Programmierung, heute eXtreme Programming, das überhaupt den Ausschlag für Unit Tests gegeben hat - das ist eine Veränderung 4. Ordnung. Ändern sich die Rollen, ändern sich die Vorgehensschritte (z.B. durch Einführung einer QS oder eines Change Management oder von time boxes Releases), dann sind das Veränderungen 4. Ordnung.

5. Ordnung und höher: Veränderungen höherer Ordnung betreffen nicht mehr unmittelbar das Softwareentwicklungsteam, sondern seine Umwelt. Dazu gehören zum Beispiel Firmenzusammenschlüsse oder die Einführung von Teleworking.

Mit diesen Ordnungen von Veränderungen in der Hand, können Sie in Zukunft sehr einfach die Empfehlungen einordnen, die Sie lesen oder hören. Sie lesen einen Artikel über Scrum - und Sie wissen sofort, dass es um Veränderungen 4. Ordnung geht. Sie lesen einen Artikel, der den Einsatz von BizTalk Server empfiehlt - und Sie wissen, dass die Umsetzung der Empfehlung eine Veränderung 2. Ordnung bedeutete. Den üblichen Artikeln in Fachzeitschriften nach dem Motto "Mehr Performance durch xyz" oder "Best Practices für den Einsatz von abc" geht es um Veränderungen 1. Ordnung.

Ordnungsbeziehungen

Die Ordnungen der Veränderung bilden eine Hierarchie, die ich einmal als Pyramide darstelle:

image

Höhere Ordnungen sind darin das Fundament für Veränderungen niederer Ordnung. Veränderungen der Ordnung n führen zu Strukturen, die Voraussetzung für Veränderungen der Ordnung n-1 sind. Oder anders ausgedrückt: Veränderungen der Ordnung n-1 sind eingebettet bzw. basieren auf vorherigen Veränderungen der Ordnung n:

  • Veränderungen an funktionalen und nicht funktionalen Features einer Software setzen Veränderungen an den "Softwarerohstoffen" voraus.
  • Veränderungen an und mit "Softwarerohstoffen" sind immer eingebettet in einen Architekturrahmen und insofern auch abhängig von Veränderungen an ihm.
  • Veränderungen am Architekturrahmen setzen voraus, dass sie auch getestet, produziert und deployt werden können. Sie basieren also auf einem angemessen veränderten Produktionsprozess.
  • Veränderungen am Produktionsprozess sind nur möglich, wenn sich auch das Vorgehensmodell um ihn, also die Teamorganisation verändert.

Um Veränderungen n-ter Ordnung durchzuführen, sind also ggf. vorher Veränderungen (n+1)-ter Ordnung vorzunehmen.

Den Ordnungen der Veränderungen entsprechen natürlich Ebenen von Systemen (bestehend aus Strukturelementen und Beziehungen) und Prozessen. Diese Systeme und Prozesse sind es, die verändert werden. Insofern beschreibt die obige Pyramide auch eine Hierarchie von Systemen/Prozessen, die aufeinander aufsetzen:

  • Das System der kundenrelevanten Features basiert auf einem System von Codeeinheiten.
  • Das System der Codeeinheiten basiert auf bzw. manifestiert ein Modellsystem, die Architektur.
  • Die Architektur ist eingebettet in ein Produktionssystem und QS-Prozesse.
  • Produktion und QS sind Ergebnis der Zusammenarbeit innerhalb des sozialen Systems Projektteam.

Keine Veränderung ohne Druck

Veränderungen sind kein Selbstzweck. Niemand verändert sich - allemal kein Unternehmen -, ohne einen Druck wahrzunehmen, der eine Veränderung zumindest nahelegt, um in Zukunft weniger Druck zu verspüren.

Woher kommt der Druck, um Veränderungen verschiedener Ordnung anzustoßen? Vor allem kommt Druck natürlich von außen. Der Kunde äußert Anforderungen, die in Veränderungen 0. Ordnung resultieren, die auf Veränderungen 1. Ordnung basieren. Ebenso sind es vor allem die expliziten Kundenanforderungen, die Veränderungen der 2. Ordnung anstoßen. Aber auch neue Optionen der Technologieanbieter können sie ermuntern.

Doch schon für Veränderungen 2. Ordnung sind die Impule von außen vergleichsweise schwach. Ganz zu schweigen von Veränderungen höherer Ordnung. Kein Kunde wünscht sich eine bestimmte Produktionsweise oder ein konkretes Vorgehensmodell.

Bei gegebenen Systemen und Prozessen ab Ebene 2 stellt sich daher die Frage: Woher kommt Veränderungsdruck? Warum sollten Veränderungen 2., 3. oder 4. Ordnung überhaupt durchgeführt werden?

Und genau da liegt das Hauptproblem vieler Softwareprojekte, scheint mir. Ein mangelnder Druck von außen ist der Grund für die oben erwähnte Aussage von Entwicklern. Ein Blick auf die Pyramide zeigt auch: Für den Kunden - und somit für Führungskräfte - unmittelbar relevant ist nur die Ebene 0. Nur (oder vor allem) Veränderungen 0. Ordnung werden von ihnen wahrgenommen.

Wahrnehmungsorgane für Veränderungsdruck

Ich denke, es mangelt an Wahrnehmungsorganen für Veränderungsdruck. Das hauptsächlich ausgeprägte ist das Ohr für den Kunden. Wenn er sich räuspert, dann wird die Veränderungsmaschinerie angeworfen. Dann sind Veränderungen 0. Ordnung gefragt - egal wie.

Aber wo Veränderungsdruck von außen kommen kann, kann er natürlich auch von innen kommen. Veränderungen n-ter Ordnung können "von innen" Druck auf andere Ebene ausüben, d.h. Veränderungen (n-1)-ter oder (n+1)-ter Ordnung motivieren. Doch diese Form von Druck muss man natürlich wahrnehmen können.

Veränderungen erzeugen Unterschiede. Manche dieser Unterschiede können dann einfach so groß sein, dass sie einen Unterschied auf anderer Ebene nach sich ziehen sollten. Quantitative Unterschiede sind dafür gute Kandidaten. Ein Beispiel aus der Verkehrswelt: Solange es nur wenige Autos gab, regelte der Verkehr sich quasi von selbst. Nur durch eine größere Quantität der Autos war es dann jedoch ab einem bestimmten Punkt nötig, explizite Regelungen einzuführen. Verkehrspolizisten und Ampeln waren die Folge. Veränderungen n-ter Ordnung (Zahl der Autos) zogen also Veränderungen (n+m)-ter Ordnung (Regelungskonzept) nach sich.

Warum sollte Software davon ausgenommen sein? Wenn bei einer Softwaregröße g zu einem Zeitpunkt tg Systeme und Prozesse auf allen Ebenen passend waren, dann heißt das doch ganz selbstverständlich nicht, dass bei einer Softwaregröße h>g zum Zeitpunkt th>tg dieselben Systeme und Prozesse immer noch passend sind.

Dasselbe gilt für weniger konkrete Umwelteinflüsse als funktionale Kundenanforderungen. Zeitrahmen oder Budget sind Umwelteinflüsse, denen ein Softwaresystem auf allen Ebenen angepasst sein sollte. Ändern sich Zeitrahmn und Budget, so kann das eigentlich nur durch Veränderungen unterschiedlicher Ordnung kompensiert werden.

Vom Entwickler bis zum Chef sollten daher alle Beteiligten bei jeder Veränderung in der Umwelt fragen, Veränderungen welcher Ordnungen dadurch für das Projektteam bzw. Softwaresystem angezeigt sind. Wahrnehmungsorgane für Veränderungsdruck auszubilden ist also gar nicht so schwierig. Eigentlich genügt es zunächst, Unterschiede nicht nur in der Umwelt, sondern auch "im System" überhaupt ersteinmal wahrzunehmen. Auch und vor allem, wenn sie nicht antizipiert oder selbst verursacht sind.

Ist es schwieriger geworden, neue Features einzubauen? Nimmt die Menge an Code zu, von der nicht mehr ganz klar ist, wozu sie dient? Steigt der Aufwand, um Performancelecks zu finden? Meldet der Support Fehler, die eigentlich schon länger behoben sein sollten?

Das sind Fragen, die, wenn mit Ja beantwortet, Unterschiede aufzeigen, die Veränderungsdruck darstellen, auch wenn er nicht unmittelbar von einem Kunden ausgeht.

image

Kunden (und ihre Stellvertreter wie Verkauf oder Chef) üben Veränderungsdruck auf Software aus. Aber je älter und größer eine Software wird, desto mehr Druck übt sie auf sich selbst aus. Das ist dann Druck von innen.

Solcher Druck ausgehend von Ebene n kann dann nahelegen, Veränderungen (n+1)-ter oder (n-1)-ter Ordnung durchzuführen. Manchmal ist seine Reichweite aber auch größer. Ändert sich das Vorgehensmodell (4. Ordnung), hat das wahrscheinlich Auswirkungen auf die Produktion (3. Ordnung) oder gar auf die Architektur (2. Ordnung). Umgekehrt können neue architektonische Konzepte (2. Ordnung) wie Contract-first Design Veränderungen am Produktionsprozess (3. Ordnung) nach sich ziehen.

Für unterschätzt halte ich in jedem Fall den Veränderungsdruck von innen, der durch "Massezuwachs" (oder Komplexitätszuwachs) über die Lebenszeit eines Projektes entsteht. Und der Druck, den immer knappere Zeitvorgaben und volatile Kundenwünsche ausüben, schlägt sich noch nicht in angemessenen Änderungen der Ordnung 2-4 nieder.

Die Übersetzung von Druckwahrnehmung (wie bewusst oder unbewusst auch immer) in Veränderungen unterschiedlicher Ordnung geht also oft schief.

Samstag, 16. Februar 2008

Ordnungsaspekte für das Multithreading [OOP 2008]

Auf der VSone 2008 habe ich gerade einen Vortrag über Software Transactional Memory (STM) gehalten und meine Open Source Implementation NSTM vorgestellt. Der Vortrag war gut besucht; das hat mich sehr gefreut und ermutigt, weiter an NSTM zu arbeiten. Ein wenig Hilfe von anderen Entwicklern wäre dabei natürlich schön... Bei den Collections, die für einen STM neu entwickelt werden müssen, ist einiges zu tun. (Vom .NET Fx angebotene Collections wie List<T> oder Queue<T> können nicht einfach "von außen" transaktional gemacht werden, da ihre internen Strukturen nicht auf STM basieren. Nur eine grundsätzliche thread-safety lässt sich von außen durch pauschale Sperren herstellen.)

Nun finde ich Ordnung/Überblick immer gut. Deshalb habe ich mich gefreut, beim Blick auf die VSone Agenda eine persönliche Erkenntnis gehabt zu haben. Da war nämlich nicht nur ich mit einem Multithreading-Vortrag vertreten, sondern auch Bernd Marquardt zum Thema OpenMP. Dazu kommt noch, dass ich neulich ein wenig über Microsofts Concurrency Coordination Runtime (CCR) gelesen hatte.

Meine Erkenntnis war nun, dass ich in diesen/zwischen diesen Technologien ein Muster erkannt habe. Und Muster als Strukturierungen der Realität finde ich immer gut. Die erzeugen in mir immer ein Gefühl von Entspannung und Aha nach dem Motto "Achsoooo, so ist das! Eigentlich ganz einfach..." :-)

Das Muster, das ich nun gesehen habe, betrifft die Einteilung von Multithreading-Themen. Herb Sutter hat ja auch schonmal eine Einteilung in "The Pillars of Concurrency" gemacht. Die gliedert die Parallelverarbeitung nach Zwecken. Das ist aber nur eine mögliche Dimension, finde ich. Eine andere ist die Einteilung nach "technischen Aspekten".

Für mich teilt sich Multithreading danach auf in drei grundsätzliche Problembereiche:

  1. Code auf Threads verteilen: Code in einem eigenen Thread laufen zu lassen, kann so einfach sein, wie ThreadPool.QueueUserWorkItem() aufzurufen. Zum ersten Aspekt des Multithreading gehört aber mehr. Denn Code explizit auf Threads zu verteilen ist letztlich umständlich oder gar eine intellektuelle Herausforderung. Viel effizienter wäre es doch, wenn Sie sich über die Parallelisierung von Code gar keine Gedanken machen müssten. Mit implizitem oder zumindest deklarativem Multithreading wäre Ihnen eine Last genommen. OpenMP oder Active C# sind dafür hilfreiche Technologien. Mit ihnen erzeugen Sie Threads nicht mehr explizit im Code, sondern sagen viel pauschaler "Hier soll etwas automatisch parallel laufen. Irgendwie."
  2. Parallelen Code koordinieren: Paralleler Code läuft selten isoliert. Er muss vielmehr in seinen Aktivitäten koordiniert werden. Threads müssen sich abstimmen, in dem was sie tun. Sie wollen einander Aufforderungen schicken oder aufeinander warten. Der .NET Fx bietet dafür z.B. WaitHandle verschiedener Art. Aber andere Technologien machen es noch einfacher, z.B. die Ports der CCr oder Protokolle in Active C#. Ganz allgemein geht es bei der Koordinierung immer um Signale in Warteschlangen, auf die man warten kann.
  3. Gemeinsame Ressourcen parallel nutzen: Wenn Threads dann laufen und sich koordinieren, womit arbeiten Sie dann? Häufig auf gemeinsamen Ressourcen. Die können sie aber nicht einfach so ohne Beachtung der anderen Threads egoistisch nutzen! Parallele Nutzung gemeinsamer Ressourcen läuft immer Gefahr, Inkonsistenzen zu erzeugen  - wenn sie sich nicht koordiniert. Koordinationstechnologien helfen also bei der gemeinsamen Ressourcenutzung. Aber eigentlich ist explizite Koordination genauso ineffizient wie explizite Parallelisierung. Auch hier ist also Abhilfe gefordert. Software Transactional Memory oder auch Space Based Collaboration sind Ansätze, die die Parallelnutzung leichter machen. Sie bieten Abstraktionen, hinter denen konkurrierende Zugriffe und ihre explizite Koordination verschwinden.

Wenn ich zukünftig irgendwo etwas über Multithreading lese, dann werde ich mich sofort fragen, um welchen dieser drei Aspekte es dabei geht. Irgendwie ordnet sich für mich dadurch das Thema besser als bisher.

Und ich habe damit Oberbegriffe in der Hand, die ich auch auf Herb Sutters Zwecke anwenden kann. Wie ist´s z.B. mit der Skalierbarkeit? Welche Aspekte haben Einfluss auf sie? Größere Skalierbarkeit ergibt sich z.B. immer durch weniger Koordination und weniger gemeinsame Ressourcen. Oder wie ist´s mit Responsiveness? Dafür ist es vor allem wichtig, Code einfach parallelisieren zu können. Dann nutze ich Parallelität nämlich eher, um responsive zu bleiben.

Würde mich freuen, wenn diese Aspekte Ihnen auch ein wenig helfen würden, die Multithreading-Welt "geordneter" zu sehen.

Dienstag, 12. Februar 2008

Space Based Collaboration - Jetzt mit mehr Öffentlichkeit

So langsam nimmt die WCF-Alternative doch Fahrt auf. Oder besser: die nächste Abstraktionsstufe oberhalb von WCF. Vor ein paar Jahren waren Spaces nur eine recht akademische Idee. Jetzt aber finden sie den Weg in die Öffentlichkeit. Der Beginn eines neuen Paradigmas.

Neulich hatte ich schon ein paar Gedanken zu einer Technologie nach bzw. komplementär zu WCF geäußert. In die selbe Richtung gingen davor auch schon meine Spekulationen über eine neue Klasse von Anwendungen: serverless real-time online collaborative (SROC) applications. Die scheinen nämlich von Spaces als Grundlage für die Kollaboration besonders profitieren zu können.

Als ich 2006 schon einmal über "Life Beyond WCF" und Virtual Shared Memory geblogt hatte, waren Spaces auch noch weniger greifbar. Aber nun hat Amazon einen Tuple Space in die Öffentlichkeit entlassen - mehr dazu in einige Postings in meinem englischen Blog - und das rennomierte Portal "The Serverside" hat (mithilfe des Space-Produktanbieters GigaSpaces) ein eigenes Knowledge Center zum Thema aus der Taufe gehoben. Das machen die ja nicht, wenn da kein Potenzial wäre.

Alles sehr schöne Entwicklungen wie ich finde :-) Weiter ermutigt hat mich auch ein Abend bei der .NET User Group Hamburg: Da habe ich neulich 2,5 Stunden eine Space Implementation diskutiert und demonstriert - und die Teilnehmer waren sehr interessiert bei der Sache. Die Aussicht, eine Alternative zu WCF auf höherem Abstraktionsniveau in die Hände zu bekommen, fanden fast alle sehr attraktiv. Ein besonderer Glücksmoment war dann, als ein Teilnehmer zu dem Chat-Beispiel, das ich live gebastelt hatte sagte, das sei der kürzeste Code für die Chat-Funktionalität, den er je gesehen hätte. Seufz... genau das wollte ich nämlich rüberbringen: Space Based Collaboration macht Code für die Kommunikation in verteilten Anwendungen kürzer und leichter zu lesen und intuitiver.

image

Nach so positivem Feedback aus der User Group freue ich mich nun, das Team hinter der Implementation auch einmal zeigen zu können. Es hat jetzt nämlich selbst eine Presseveröffentlichung herausgegeben und ist online mit einer Projektbeschreibung zu finden. Rechts zu sehen die Helden der XcoSpaces, der .NET-Implementierung der Space Based Collaboration: Prof. Eva Kühn (vorne rechts) ist die Initiatorin und Koordinatorin des Projektes und unermüdliche Verfechterin des Space-Paradigmas seit vielen Jahren; und Thomas Scheller (vorne links) zusammen Markus Karolus (dahinter) haben die XcoSpaces tapfer implementiert. Es macht Spaß, mit dem Team an der Idee zu arbeiten und sie aus der akademischen in die praktische .NET-Welt zu tragen.

Wer nun neugierig geworden ist, was es denn mit Spaces auf sich hat, der melde sich gern bei mir via Email oder per Blog-Kommentar. Der XcoSpaces-Prototyp zweiter Generation ist für Interessenten kostenlos erhältlich. Eva Kühn et al. und ich sind sehr daran interessiert, Erfahrung im Einsatz von Spaces in realen Problemszenarien zu sammeln.