Follow my new blog

Montag, 20. Juli 2009

Klage eines ungebackenen Entwicklers

Mehr Ausbildung zum Softwareentwickler in den Betrieben, das scheint mir ein wichtiger und gangbarer Weg für die Zukunft der Branche, die vom IT-Fachkräftemangel gebeutelt ist. So habe ich es in der dotnetpro 8/2009 in meiner Sandbox-Kolumne geschrieben. Daraufhin schreibt mir nun ein junger Fachinformatiker, wie sehr ich (für ihn) mit diesem Artikel und anderen zum Thema Ausbildung den Finger in die Wunde gelegt habe:

Hallo Herr Westphal,
mit großem Interesse habe ich Ihren Artikel "Entwickler selbst backen"
in der aktuelle dotnetpro gelesen.
Ich hoffe sehr das sich einige Firmen den Artikel zu Herzen nehmen und
auch den nicht Vollprofis eine Chance geben.
Ich selbst bin gelernter Fachinformatiker Fachrichtung
Anwendungsentwicklung und habe meine Ausbildung im Februar 
[des Jahres 2009] abgeschlossen. Die defizite der Ausbildung sind mir also bestens
bekannt, zum einen wurde bei uns in der Berufsschule
keinerlei Vorgehensweiße unterrichtet, weder Analyse noch Design
geschweigedenn irgendwelche Modelierungen mit UML
.
Meine zweieinhalb Jahre Ausbildung habe ich in der Schule mit
Struktogrammen und dem Borland Builder 6 mit C++ verbracht, wo wir
es nach zwei Jahren tatsächlich geschafft haben eigene Klassen und
Methoden
zu erstellen (Fehlerbehandlung, Debugging usw. waren alles
Fremdwörter
).

Die Berufsschule hate nicht die Fachkräfte die nötig wären und auch
garnicht die Zeit, der überwiegende Teil wird in Systemintegration
ausgebildet und hat keinerlei Interesse an der Programmierung allgemein,
somit sind die Themen auch nicht gut zu vermitteln.
Somit bleibt noch der Betrieb, ich hatte das Pech das ich einem Betrieb
gelandet bin der nur eine EDV Abteilung besitzt und keine
Dienstleistungen in dem Bereich erbringt. Schulungen oder Einweisungen in richtige
Vorgehensweißen oder z.B. die Verwendung von Visual Studio gab es hier
nicht.

Wer sich nicht selbst weitergebildet hat blieb auf einem sehr niedrigen
Level. Ich bin sehr interessiert daran es richtig zu lernen, ich
arbeite sehr gerne mit
ASP.NET und mit dem CompactFramework und möchte
ein möglichst hohes Level erreichen, leider scheitere ich an den Firmen
die scheinbar durchweg kein Interesse haben Ihre Mitarbeiter zu guten
Entwicklern auszubilden
, und in Eigenarbeit mangelt es mir an Zeit und
manchmal auch an der Motivation (Die Firma dankt es mir eh nicht).

Deshalb habe ich auch kurz nach meinem Ausbildungsende die Firma
gewechselt, ich habe eine Firma gesucht die mir auch Weiterbildungen
anbietet, die verspricht das dass ausprobieren von neuen Technologien
Pflicht ist. Ich bin für diese Firma 200km umgezogen, und nehme weniger
Gehalt in Kauf. Leider musste ich feststellen das es hier keine
Weiterbildung gibt bzw. ich kann mir einmal im Monat mal eine Stunde zu
einem Thema, welches ich im übrigen in meiner täglichen Arbeit garnicht
einsetzen kann/darf, was anhören
. Weitere Themen stehen dann wieder nur
Senior Software Developern zur Verfügung, welcher ich hier in dieser
Firma erst nach 5 Jahren sein werde. Das ausprobieren der neuen
Technologien findet hier garnicht statt
, das Projekt läuft immernoch
auf dem 2.0 Framework und wie was umgesetzt wird, wird vorgegeben. Ich
habe mich im großen und ganzen selbst von Anwendungsentwickler zum
einfachen Programmierer heruntergestuft der den ganzen Tag irgendwelche
Support anfragen bearbeitet. Nun bin ich wieder auf der Suche nach
einer Firma die eventuell Interesse daran hat
sich selbst einen guten Mitarbeiter auszubilden. Ich bin nicht dumm und
eigentlich hochmotiviert ein "guter" .NET Entwickler zu werden, leider
muss ich wohl erst zwei bis fünf Jahre "Berufserfahrung" (meines
Erachtens ist das keine Berufserfahrung wenn ich Tag ein Tag aus
dasselbe mache ohne mich dabei weiterzubilden) sammlen bevor ich eine
Firma finde dem gerecht wird was ich suche.
Ich möchte Ihnen auf diesem Weg für diesen Artikel danken! Und ich hoffe
sehr das es auch in meiner Region Firmen gibt die diesen lesen und ihn
sich zu Herzen nehmen und vieleicht finde ich dann doch eine Firma bei
der mir meine Arbeit, die eigentlich auch mein Hobby ist, mir wieder
Spass macht. Ich hoffe das Konzept School of .NET wird in die Tat
umgesetzt, ich wäre sofort dabei das zu unterstützen!
[…]

Er würde so gern gebacken werden, aber niemand schiebt ihn wirklich in den Ofen. Die Firmen, bei denen die junge und zumindest motivierte Entwickler arbeitet, sehen ihn als fertig an, nur weil er eine Fachinformatiker-Ausbildung durchlaufen hat. Die aber ist, wie sich bei allem Verständnis für den Willen zu einer “plattformneutralen Ausbildung” zeigt, von nur zweifelhaftem Nutzen. State-of-the-art wird dort nicht vermittelt – was eher weniger an der Ausbildungssprache Borland C++ liegt.

Wie kann es sein, dass die Betriebe das nicht merken? 1. Es findet keine Qualitätskontrolle des in der Ausbildung Vermittelten bei seinem Lehrherren und auch später nicht statt. 2. Allemal als Auszubildender ist er wahrscheinlich so billig gewesen, dass niemand aufgefallen ist, dass er mit dem Ausbildungswissen nichts anstellen konnte. Seine Unproduktivität fiel nicht ins Gewicht. Denn unproduktiv muss er gewesen sein bei dem, was auf dem Lehrplan gestanden hat. Wieviel mehr hätte er schaffen können, wenn die Ausbildung zum einen der Plattform seines Lehrbetriebs entsprochen hätte und zweitens auf der höhe der Zeit stattgefunden hätte? Er hätte seinem Lehrbetrieb geradezu neue Impulse geben können. Nicht auszudenken wäre es doch, wenn ein Auszubildender aus dem Blockunterricht käme und z.B. sagte: “Wow, wir können viel korrekter arbeiten, wenn wir Unit Tests einsetzen.”

Stattdessen setzt man den motivierten Entwickler in eine Ecke und lässt ihn mokeln. Ich spekuliere mal, denn geschrieben hat er davon nichts: Seine Arbeit wurde nicht mit ihm nach Abgabe durchgesprochen. Nicht nur hat man ihm keine weitere Ausbildung/Fortbildung in den Betrieben zugestanden, auch fand sicherlich keine “Förderung im Kleinen” durch Kollegen statt. Es würde ja helfen, wenn sich jemand mit einem Junior-Programme in der Woche 2-3 Mal für ein Stündchen zusammensetzte, um seinen Code echt durchzugehen. Oder mal mit ihm Pair Programming machen. Davon jedoch keine Spur.

Betriebe nehmen klaglos, fraglos einfach an, was da aus der Ausbildung kommt. Und sie haben keinen eigenen Anspruch, wie es dann weitergeht. Außer einem Anspruch: irgendwie muss die Arbeit geschafft werden.

Was sie nicht sehen: vor 150 Jahren wurde die Arbeit auf den Feldern auch geschafft. Dafür war ein Heer von Landarbeitern zuständig. Doch heute schaffen wir es mit einem kleinen Bruchteil an Menschen, eine viel größere Zahl zu ernähren. Die Produktivität in der Landwirtschaft ist explodiert.

Dass das auch in der Softwareentwicklung mit etwas besserer Ausbildung, etwas besserer Kommunikation, etwas mehr Blick auf innere Qualität (Clean Code Developer lässt grüßen) und etwas besseren Prozessen auch der Fall sein könnte… das sehen viele nicht. Und das bedeutet, sie krebsen so dahin. Und das bedeutet, es wird für sie nicht besser, sondern eigentlich immer nur schlimmer. Darüber geht dann die Motivation der Leute verloren.

Der junge Entwickler hat zum Glück die Konsequenz gezogen und versucht, in eine bessere Firma zu kommen. Leider ist er nur vom Regen in die Traufe geraten. Doch er lässt nicht locker. Er will wieder einen Sprung wagen. Er glaubt noch, dass es Firmen mit mehr Interesse an ihren Entwicklern gibt. Ja, die gibt es. Ich wünsche ihm viel Erfolg bei der Suche!

Und den anderen Firmen wünsche ich einen Moment der Ruhe, des Abstands, um darüber nachzudenken, wie sie intern die Ausbildungs- und Arbeitssituation verbessern könnten. Es gilt ungehobene Produktivitätsschätze zu heben. Von höherer Motivation und Zufriedenheit mal ganz zu schweigen. Also, auf zum Entwicklerbacken!

Sonntag, 19. Juli 2009

Verständnisvorteil für Flows – Funktionale Programmierung lässt grüßen

Flows sind verständlicher als Schachtelungen, glaube ich inzwischen. Und zwar nicht nur asynchrone Flows, sondern auch synchrone.

Hier hatte ich ja schonmal über Flows sinniert. Inzwischen habe ich dann auch eine kleine Bibliothek für asynchrone Flows gebaut, die CCR Flows (http://ccrflows.codeplex.com). Doch neulich hat ein Engagierter Entwickler mit darauf hingewiesen, dass solche asynchronen Flows womöglich bei kleineren Aufgaben einen Performanceoverhead durch die Asynchronizität erzeugen, der gegen sie spricht. Da war ich erstmal ein wenig geknickt. Ja, das stimmt wohl. Es ist wie bei der Verteilung von Code. Verteilung erzeugt auch einen Overhead bei der Kommunikation gegenüber dem lokalen Stack. Doch ab einer gewissen Aufgabengröße überwiegen die Vorteile von Verteilung und Asynchronizität natürlich auch. Bis dahin ist synchrone lokale Programmierung vorzuziehen. Klar.

Machen deshalb aber Flows ebenfalls bis dahin keinen Sinn? Dazu habe ich ein wenig experimentiert. Hier mein Szenario:

Eine Textdatei mit Zeilen bestehend aus Worten ist umzuformatieren. Es soll eine neue Textdatei mit anderer Zeichenzahl pro Zeile erzeugt werden. Die Worte müssen also neu umgebrochen werden.

Übliche synchrone Lösung

Wenn ich für dieses Szenario mal eine Lösung einfach so hinschreibe, dann sieht sie z.B. so aus:

using(var sr = new StreamReader("quelldatei.txt", Encoding.Default))

using(var sw = new StreamWriter("zieldatei.txt", false, Encoding.Default))

{

    LineBuilder lb = new LineBuilder(sw, 40);

 

    while(!sr.EndOfStream)

    {

        string line = sr.ReadLine();

 

        foreach (var word in line.Split(' '))

            lb.Add(word);

    }

    lb.Emit();

}

Das ist nicht super clean, aber ja auch nicht so umfangreich. Quelldatei zeilenweise lesen, Zeilen in Worte splitten, neue Zeilen aus den Worten zusammebauen und in Zieldatei schreiben.

Für den Zusammenbau und das Wegschreiben lohnt eine Hilfsklasse, finde ich. Über die Worte hinweg muss etwas Zustand gehalten werden (die neue Zeile). Das würde mir den obigen Code zu sehr aufblähen. Die Aufgabe scheint mit eine genügend große Verantwortlichkeit, um eine eigene Klasse dafür zu rechtfertigen:

class LineBuilder

{

    private StreamWriter sw;

    private int max_line_length;

 

    private StringBuilder line = new StringBuilder();

 

 

    public LineBuilder(StreamWriter sw, int max_line_length)

    {

        this.sw = sw;

        this.max_line_length = max_line_length;

    }

 

 

    public void Add(string word)

    {

        if (line.Length + word.Length + 1 > max_line_length)

            Emit();

 

        if (line.Length > 0) line.Append(" ");

        line.Append(word);

    }

 

 

    public void Emit()

    {

        this.sw.WriteLine(this.line);

        this.line = new StringBuilder();

    }

}

Mit 60-70 Zeilen habe ich also eine Lösung für das Problem. Die sieht “normal” aus, finde ich. Ist sie aber deshalb auch verständlich? Hm… joa, so “normal verständlich”, oder?

Flow-basierte synchrone Lösung

Jetzt dagegen eine Lösung auf der Basis von synchronen Flows:

var flow = new SyncFlow<string, string>(SplitFileIntoLines)

    .Do<string>(SplitLineIntoWords)

    .Do<string>(new LineBuilder(40).AddWord)

    .Do(new FileAssembler("zieldatei.txt").WriteLine);

 

flow.Execute("quelldatei.txt");

Wie ist das? Ist finde es viel besser verständlich. Die Verantwortlichkeiten sind deutlicher getrennt. Das Abstraktionsniveau ist einheitlicher. Klar, das wäre irgendwie auch “normal” gegangen, aber auf dem “normalen” Weg muss ich dafür mehr Selbstdisziplin aufbringen, finde ich.

Die Flow-basierte Lösung hingegen zwingt mich dazu, die einzelnen Schritte zu verpacken und damit zu “entwirren”. In der synchronen Lösung sind Lesen und Splitting und Zeilenerzeugung miteinander stark verwoben. Hier hingegen stehen sie sauber nacheinander gelistet als “Stages” in einem Flow. Mit einer anderen Sprache hätte ich vielleicht auch so schreiben können:

“quelldatei.txt” | SplitFileIntoLines | SplitLineIntoWords
      | new LineBuilder(40).AddWord | new FileAssembler("zieldatei.txt").WriteLine

Aber mit C# geht das halt nicht. Die obige Formulierung finde ich allerdings auch nicht so schlimm. Die Do<>()-Aufrufe verbergen den generellen Fluss des Prozesses nicht.

Insgesamt brauche ich für diese Flow-Lösung zwar ein paar mehr Zeilen Code. Aber das finde ich vernachlässigbar. Hier der Rest:

IEnumerable<string> SplitFileIntoLines(string filename)

{

    using (var sr = new StreamReader(filename, Encoding.Default))

    {

        while (!sr.EndOfStream)

            yield return sr.ReadLine();

        yield return null;

    }

}

 

 

IEnumerable<string> SplitLineIntoWords(string line)

{

    if (line == null)

        yield return null;

    else

        foreach (var word in line.Split(' '))

            yield return word;

}

 

 

class LineBuilder

{

    private int max_line_length;

 

    private StringBuilder line = new StringBuilder();

 

 

    public LineBuilder(int max_line_length)

    {

        this.max_line_length = max_line_length;

    }

 

 

    public IEnumerable<string> AddWord(string word)

    {

        if (word == null)

        {

            yield return this.line.ToString();

            yield return null;

        }

        else

        {

            if (line.Length + word.Length + 1 > max_line_length)

            {

                yield return this.line.ToString();

                this.line = new StringBuilder();

            }

 

            if (line.Length > 0) line.Append(" ");

            line.Append(word);

        }

    }

}

 

 

class FileAssembler

{

    private StreamWriter sw;

 

    public FileAssembler(string filename)

    {

        this.sw = new StreamWriter(filename, false, Encoding.Default);

    }

 

    public void WriteLine(string line)

    {

        if (line == null)

        {

            this.sw.Close();

        }

        else

            this.sw.WriteLine(line);

    }

}

Der entscheidende Vorteil liegt für mich in dem Zwang zur Strukturierung der Lösung. Flows geben mir ein Denkmodell: Formuliere jeden Arbeitsschritt so, dass er keine Abhängigkeiten hat. Verlasse dich in einem Arbeitsschritt nur auf den Input und den eigenen Zustand.

Ich denke, das ist Funktionale Programmierung. Und damit habe ich für mich nun verstanden, glaube ich, wo deren Vorteil liegt. Die Zustandslosigkeit finde ich da gar nicht so wichtig. Die ist nett insbesondere für eine Parallelisierung. Unmittelbar relevanter und hilfreicher finde ich jedoch den Flow-Gedanken, den Funktionale Programmiersprachen nahelegen. F# enthält nicht umsonst den |> Operator.

Doch wer will schon auf F# umsteigen müssen, um Verarbeitung mit Flows leichter verständlich zu strukturieren? Wie der Code oben zeigt, geht es auch mit C#. Dafür ist etwas Umdenken nötig – aber es winken höhere Verständlichkeit und auch bessere Evolvierbarkeit als Gewinn auch schon für synchrone Programme.

Montag, 13. Juli 2009

Programme schrittweise aushärten

Wieviel strenge Typisierung brauchen wir eigentlich? Wieviel Schema tut unseren Anwendungen eigentlich gut? Je länger ich darüber nachdenke, desto mehr scheint mir, dass strenge Typisierung und explizite Schemata überbewertet oder gar kontraproduktiv sind.

Wozu brauchen wir eine strenge Typisierung, wozu Schemata? Sie machen effizient. Wenn der Compiler den Typ eines Feldes kennt, kann er maximal schnellen Code für die Zugriffe darauf erzeugen. Und wir brauchen den Code nur zu übersetzen, um zu wissen, ob z.B. eine Zuweisung korrekt ist. Diese Compilation kann sogar im Hintergrund in der IDE stattfinden.

Bei Datenbankschemata ist es ähnlich. Sie optimieren den Platzverbrauch und die Zugriffsgeschwindigkeit. Und, ja, auch automatische Datenkonsistenz ist ein Gewinn von expliziten Datenbankschemata.

Strenge Typisierung und Schemata sind Kinder einer Zeit, als Ressourcen noch knapp waren. Von den 1950er bis Anfang der 1980er  Jahren war Rechenpower teuer, so dass man spätestens nach einem (nächtlichen) Compilerlauf wissen wollte, ob ein Programm korrekt war. Fehlerhafte Probeläufe galt es zu vermeiden. Ebenso war an Speicherplatz zu sparen, was gespart werden konnte. Und jedes Quentchen Performance wollte herausgequetscht sein, um überhaupt annehmbare Laufzeiten zu bekommen.

Strenge Typisierung und explizite Schemata sind also allzu verständliche Entwicklungen. Doch haben Sie sich vielleicht überlebt? Ich denke, wir müssen sie im Kontext ihrer Geschichte sehen. Die damaligen Bedingungen sind nicht zu vernachlässigen. Sie zu vergessen und einfach Typisierung und Schemata absolut setzen, wäre eine Dogmatisierung.

Gerade in den letzten 10 Jahren hat sich nun aber einiges getan. Speicherplatz ist für die meisten Anwendungen keine wirklich knappe Ressource mehr, dito die Prozessorpower – die heute allerdings nicht mehr so einfach wie früher wächst; 2, 4 oder 8 mal 2-3 GHz durch mehrere Kerne ist etwas anderes als weiter wachsende Taktfrequenzen.

Dazu kommt, dass Software immer komplexer wird. Die Anforderungen steigen, die Vielfalt der Geräte steigt, die Technologien werden mächtiger und facettenreicher…

Das Resultat: Es ist immer weniger klar zu erkennen, was eine Anwendung genau können soll. Aber die Ressourcen sind nicht mehr wirklich knapp.

Ich denke, das hört sich nicht mehr danach an, dass wir unheimlich effizient sein müssen, sondern eher flexibel. Flexibel sind von der ersten Codezeile an explizite Klassen und Datenbankschemata aber nicht. Das Gegenteil ist der Fall. Unsere Fixierung auf Schemata für Daten im Speicher und auf der Platte zwingt uns sehr schnell in ein Korsett, dass Änderungen an Software schwierig macht.

Deshalb glaube ich, dass wir von den quasi absolut gesetzten Schemata abrücken müssen. Sie haben ihren Zweck, aber wir sollten nicht glauben, dass wir ohne sie nicht können. Wir müssen vielmehr dahin zu kommen, sie gezielt und zweckmäßig, statt zwanghaft einzusetzen. Explizite, statische Schemata machen Sinn, wo wir genau wissen, wirklich genau!, wie Datenstrukturen aussehen.

Wo wir das aber nicht wissen, wo noch Unklarheit herrscht, da sollten wir uns noch nicht so festlegen. Da sollten wir schemalos arbeiten.

In den 1980ern wurde der Begriff vom “Stepwise Refinement” populär. Programme sollten schrittweise detaillierter formuliert werden. Top-down sollte man vorgehen.

Ich möchte diesem Begriff ein “Stepwise Hardening”, eine schrittweise Aushärtung, hinzufügen. Wir sollten Programme weich beginnen, mit flexiblen Strukturen – und sie dann und nur dann verhärten, wenn wir sicher sind, dass wir mehr Effizienz brauchen. Dynamische Sprachen und schemalose Datenbanken scheinen mir da richtige Schritte auf dem Weg zu einer Balance zwischen Effizienz und Flexibilität.

Heute lassen wir unsere Programme vom ersten Moment an aus hart schematisierten Bausteinen bestehen. Je größer sie werden, desto mehr “harte Brocken” enthalten sie, die sich Änderungen widersetzen:

image

Aber könnte es nicht auch anders sein? Warum fangen wir nicht weich an? Warum härten wir nicht schrittweise aus, wo wir im Verlauf der Entwicklung immer sicherer werden, dass sich etwas nicht mehr ändert? Den Rest lassen wir bis auf Weiteres flexibel, weich:

image

Wie wäre das? Kämen wir nicht schneller voran? Wären wir nicht weniger genervt bei Änderungswünschen? Ich glaube, es lohnt sich, darüber nachzudenken.

Strenge Typisierung und Schemadenken haben ihren Platz; sie sind zurecht gegen einen allzu laxen Umgang mit Speicherplatz angetreten. Aber nun ist es Zeit, die Synthese einzuleiten. Wir brauchen dringend mehr Flexibilität im Inneren, um unsere Software evolvierbar zu halten.

Donnerstag, 2. Juli 2009

CCR Flows - Asynchrone Prozesse mit der CCR verdrahten

Neulich habe ich eine Lanze dafür gebrochen, zwei Probleme der Softwareentwicklung auf einen Streich zu lösen. Das würde Software zukunftsfähiger machen. Denn Abhängigkeiten und Synchronizität sind Behinderungen auf dem Weg in eine glückliche Projektzukunft.

Das Mittel für diese “Wundertat”? Asynchrone Flows, d.h. Funktionseinheiten nicht mehr statisch voneinander abhängig machen und auch nicht mehr synchron miteinander kommunizieren lassen. Stattdessen Verarbeitungsschritte in einem expliziten, getrennten “Bereich” (Separation of Concerns) lose mit eigenständigen Verbindungsgliedern “zusammenstöpseln”.

image

Dazu hatte ich dann ein wenig über einen API spekuliert, der das möglich machen könnte. Damit lag ich – wie sich nun herausgestellt hat – wohl nicht ganz daneben. Denn nach einigen Versuchen habe ich nun so einen Flow API implementiert. Ich nenne ihn CCR Flows, weil er intern auf CCR (Microsoft Concurrency Coordination Runtime) Ports als “Verbindungsglieder” zwischen Prozessschritten setzt.

Die CCR Flows sind jetzt Open Source (sogar inkl. Dokumentation sowie Unit Tests) und liegen bei CodePlex:

http://ccrflows.codeplex.com

Über Feedback und Diskussion dort im Forum würde ich mich freuen. Es gibt natürlich noch etwas daran zu tun. Aber als Einstieg in ein anderes Programmiermodell finde ich den API nicht ganz schlecht. Ein Beispielprogramm in den Sourcen realisiert auch den Beispielprozess meines vorherigen Blogartikels. An dieser Stelle zum Schnuppern aber nur ein kleiner Prozess, der die Worte eines Textes extrahier und dann in zwei Schritten transformiert:

Flow<string>.Do<string>(SplitTextIntoWords).Do<string>(w=>w.ToUpper()).Do<string>(Reverse)

Meine Vermutung, solcher Code lässt sich besser weiterentwickeln, weil schon bei jeder Prozessstufe (stage) viel entkoppelter gedacht wird. Denn diese Stufen kennen ihren Vorgänger und Nachfolger nicht! Sie haben keine Abhängigkeiten.

Wie das genau geht, erklärt die Doku bei CodePlex. Ansonsten fragt mich einfach.

Viel Spaß damit!

Wie gut ist Ihr Job? – Jetzt Umfrage mit Gewinn [OOP 2009]

Vor einigen Tagen hatte ich darüber spekuliert, wie zufrieden wir Softwareentwickler wohl so mit unseren Jobs sind. Daraufhin gab es einige Einsendungen von Fragebogenergebnissen nach dem DGB-Fragebogen zur Jobzufriedenheit. Das hat mich ermutigt und ich habe mit dem Professional Developer College nun die Aktion etwas erweitert:

Jetzt gibt es eine “echte” Umfrage mit Gewinnen, die unter den Einsendern verlost werden, und einer Veröffentlichung der Ergebnisse in der dotnetpro.

Wäre toll, wenn möglichst viele mitmachten, damit wir ein halbwegs repräsentatives Bild von der Jobzufriedenheit in der Branche bekommen. Der Aufwand ist 5 Minuten, der Nutzen hoch für die Gemeinschaft.

Also, auf geht´s. Klickt hier…

Mittwoch, 1. Juli 2009

Blinder Fleck Change Tracking

Habe grad ein paar Postings zum Thema Distributed Domain Driven Design (DDDD oder “D4”?) gelesen. Dabei ist mir wieder der Gedanke gekommen, dass wir uns das Leben noch schwerer machen als nötig. Ich glaube nämlich, zu unserem Glück fehlt uns noch eine deutliche Separation of Concerns (SoC).

Über das DataSet kann man sagen, was man will, es hat eins ganz wunderbar getan: Änderungen verfolgen. DataSet mit Daten füllen, irgendwohin schicken, dort ändern – und dann nur die Änderungen zurückschicken, um sie zu persistieren. Sehr cool!

Und dann kam O/R Mapping – und wir haben für die Änderungsverfolgung (Change Tracking) einen Blinden Fleck entwickelt. Denn entweder haben O/R Mapper kein Change Tracking betrieben, sondern Daten geladen, Objekte befüllt und dann einfach immer komplette Objekte auch wieder gespeichert, wenn man ihnen sagte, dass sich daran etwas geändert hat. Oder sie haben Objekte befüllt, die intern selbst Buch führen über Änderungen an sich. Dann konnte der O/R Mapper später ohne manuelle Meldungen über Änderungen sich selbst geänderte Objekte herauspicken und mit minimalen SQL DML-Statements persistieren.

Klingt bequem, ist bequem. Aber Change Tracking liegt im Blinden Fleck. Wir sehen das nicht. Meistens. Deshalb machen wir uns darüber keine Gedanken. Sollten wir aber. Denn letztlich ist das ein Thema, das immer relevant ist, wenn Mapping ins Spiel kommt.

Deshalb hat mich ja auch D4 wieder darauf gebracht. In verteilten Systemen erzeugen wir nämlich Objekte z.B. in einem Server, die wir zum Client schicken. Ob der Server die aus einer Datenbank befüllt oder nicht, ist egal. Änderungen an diesen Objekten im Client sollen dann wieder zurück zum Server. Aber wie? Geänderte Objekte können in Form “dummer DTOs” eigentlich nur komplett zurückfließen. Aber warum soviel Traffic? Warum können wir nicht nur die Änderungen zurückschicken und in die serverseitigen Instanzen einspielen?

Klar, das geht. Kann man programmieren. Kostet aber Mühe. Event sourcing ist dazu ein Stichwort. Aber warum sollten wir das immer wieder programmieren? Das ist ein so grundsätzliches Problem, dass ich finde, dafür sollte es eine allgemeine Lösung geben.

Und die steckt für mich im Change Tracking, das manche O/R Mapper eh schon tun. Warum wird dieses Change Tracking nicht dort rausgezogen und separat implementiert? Warum gibt es nicht eine Change Tracking Infrastruktur (z.B. auf einem AOP-Fundament), die dann beim O/R Mapping oder auch bei sonstigem Mapping oder Versand von Daten einsetzen kann?

image Für mich sind Change Tracking und Persistenz inzw. ganz klar orthogonale Belange. Sie sollten deshalb auch technologiemäßig ganz klar getrennt werden.  Change Tracking darf nicht unser Blinder Fleck sein.

Wer baut also als erstes eine allgemeine Change Tracking Infrastruktur z.B. auf der Basis von PostSharp? Wer baut einen O/R Mapper, der dann darauf aufsetzt? Das macht dem O/R Mapper-Hersteller weniger Mühe. Und das verschafft dem Change Tracking-Hersteller eine viel größere Zielgruppe. Alle würden profitieren.

Montag, 29. Juni 2009

Wie gut ist Ihr Job? [OOP 2009]

Mögen Sie eigentlich Ihren Job? Sind Sie zufrieden? Nicht nur mit dem Gehalt, nein, so insgesamt. Immerhin verbringen Sie “auf der Arbeit” ca. 1/3 Ihrer Zeit oder gar knapp 50% Ihrer “Wachphasen”. Da wäre es doch gut, diese Zeit zufrieden zu verbringen, oder?

Also: Wie geht es Ihnen mit Ihrem Job?

Wenn es Ihnen schwer fallen sollte, darüber nachzudenken, dann grämen Sie sich nicht. Das ist ganz natürlich. Ein erstes Gefühl haben Sie sicherlich schnell. Aber im Einzelnen werden Sie unsicher sein. Sie haben es nicht imagegelernt, ihre Arbeit bewusst und detailliert zu reflektieren. Ihr Arbeitgeber ist daran kaum interessiert. Und in Ausbildung oder Schule steht das einfach nicht auf dem Lehrplan.

Zum Glück gibt es aber andere, die sich darüber Gedanken machen. Der DGB zum Beispiel. Deshalb hat der eine Studie zur Arbeitszufriedenheit in Auftrag gegeben. Darüber berichtet gerade die Zeitschrift Psychologie heute (7/09) in ihrem Artikel “Kann man sich in seinen Job (neu) verlieben?”.

15 Kriterien werden darin genannt, anhand derer Sie überprüfen können, ob Sie einen guten oder schlechten Job haben:

    1. Gibt es Qualifizierungsangebote? Lerne ich etwas bei der Arbeit?
    2. Habe ich die Möglichkeit, eigene Ideen einzubringen?
    3. Kann ich im Betrieb aufsteigen?
    4. Habe ich Einfluss auf Planung und Menge meiner Arbeit?
    5. Erhalte ich klare Anforderungen und alle notwendigen Informationen?
    6. Wie gut führen meine Vorgesetzten?
    7. Wie gut ist die Betriebskultur?
    8. Bekomme ich Hilfe von meinen Kollegen?
    9. Ist meine Arbeit nützlich für die Gesellschaft?
    10. Gibt es eine faire und verlässliche Arbeitszeitgestaltung?
    11. Muss ich oft unter Zeitdruck arbeiten?
    12. Werde ich herablassend behandelt? Muss ich meine Gefühle verbergen?
    13. Ist meine Arbeit körperlich schwer oder einseitig?
    14. Habe ich häufig Angst um meine berufliche Zukunft?
    15. Kann ich von meinem Einkommen leben? Entspricht das Einkommen meiner Leistung?

Über diese Kriterien mag man im Einzelnen diskutieren. Fehlt da z.B. die Frage nach der Erfüllung durch Spaß am Metier? Oder entsteht Sinnhaftigkeit vor allem durch gesellschaftliche Relevanz oder nicht vielmehr durch ein Gefühl des “gewollt und gebraucht seins” vor Ort im Unternehmen? Als Ausgangspunkt und vor allem Vergleichsmaßstab sind die Kriterien jedoch nicht schlecht.

Wie steht es also mit Ihnen? Wenn Sie Ihre Arbeit daran messen, wie gut oder schlecht ist sie? Das können Sie leicht herausfinden, indem Sie einen Fragebogen kostenlos online ausfüllen. Das dauert 5 Minuten und sieht im Ergebnis dann z.B. so aus:

image

Hier habe ich mal versucht, mich in die Situation eines “abhängig beschäftigten” Softwareentwicklers zu versetzen. Auf der linken Seite der Zufriedenheitsindex dieses fiktiven Entwicklers, der seinen Job als “knapp vorbei an schlecht” einschätzt mit einem Index von 54. Rechts der Durchschnitt der Befragungen aus der Studien über viele Berufsgruppen hinweg.

Auffällig: Bei der Studie liegen die Werte dichter beieinander. Ich halte also den fiktiven Softwareentwickler in einigen Bereichen für sehr zufrieden (z.B. bei Kollegialität oder auch der Möglichkeit, Kontrolle über seine Arbeit auszuüben), andererseits ist er aber auch sehr unzufrieden (z.B. bei der Weiterbildung, der Arbeitszeit/-intensität oder auch den Aufstiegschancen).

Das sind natürlich nur Annahmen aufgrund meiner Begegnungen mit Softwareentwicklern in vielen Betrieben durch meine Berater- und Trainerarbeit. Sozusagen ein “gefühlter Durchschnitt”.

Aber liege ich damit so falsch? Sagen Sie es mir. Füllen Sie auch den Fragebogen aus und schauen Sie, wo Ihre Zufriedenheit positiv – was zu wünsche wäre – oder negativ abweicht. Motivieren Sie Ihre Kollegen es auch zu tun. Sprechen Sie über Ihre Ergebnisse – auch mit Ihrem Chef. Und: Wenn Sie mögen, schicken Sie mir Ihre Auswertungen als Bilder per Email (inkl. einiger Zusatzangaben: Sind Sie selbstständig/angestellt? Wie groß ist das Team, in dem Sie arbeiten? Welche Position haben Sie? Wie groß ist die relevante Organisationseinheit um Sie herum (Unternehmen, Abteilung)?). Ich verspreche, in jedem Fall Ihre Angaben vertraulich zu behandeln, wenn ich aus den eingegangenen Auswertungen eine kleine Galerie zusammenstelle oder – bei genügend Masse – einen Branchendurchschnitt berechne.

Ich bin gespannt, wie Sie sich mit Ihrem Job fühlen!

 

PS: Da es etwas Überwindung kosten mag, mir das Ergebnis zu schicken und sich damit ein Stück zu öffnen, hier meines sozusagen als “Vorleistung”:

image

Sie sehen, ich fühle mich zufriedener als der fiktive Entwickler. Warum? Weil ich sehr selbstbestimmt arbeiten kann. Zwar knickt die Kurve bei der Arbeitsplatzsicherheit ein, da ich ohne größere Organisation im Rücken wenig Puffer habe, aber ansonsten empfinde ich quasi alles “im grünen Bereich”.

Den Einbruch bei “Sinngehalt” zählt für mich nicht wirklich. Meinen Sinngehalt ziehe ich nicht aus einer größeren gesellschaftlichen Relevanz meiner Arbeit. Das gute Feedback aus der Community und auch der Zuspruch meiner Familie wiegen für mich schwerer.

Manche Fragen sind für mich als Freiberufler natürlich auch nicht passend. Den Führungsstil eines Vorgesetzten kann ich nicht bewerten, weil ich keinen habe, musste aber einen Wert im Fragebogen eintragen.

Insofern ist mein Ergebnis wie auch Ihres immer mit einem Körnchen Salz zu schmecken. Aber das finde ich nicht schlimm. Es geht nicht um einzelne Werte, sondern die Tendenz.

Und nun kommen Sie: hier gehts zum Fragebogen.