Category Archives: allgemein

Be Good – was ein guter Entwickler können muss

Kürzlich wurde ich von einem Junior ganz am Anfang seiner Karriere als Entwickler gefragt: “Wie wird man ein guter Entwickler?”

Jeder halbwegs professionelle Entwickler hat sich diese Frage selbst schon mehrfach gestellt, aber so direkt gefragt bleibt zunächst nur Stottern und Stammeln.

“Ja, klar, äh, ganz einfach, du lernst.. Dingens.. Patterns, hier Visitor und Observer, kennst du ja. Auf jedenfall auch testen, ja, testen ist ganz wichtig. Ja, jetzt weiß ich auch nicht, mehr fällt mir jetzt nicht ein… ich muss weg…”.

Jetzt in aller Ruhe nochmal strukturiert die 4 wichtigesten Punkte, die ein Entwickler verstehen muss:

Kenne deine Domäne

Kaum etwas ist so wichtig, wie tatsächlich zu verstehen, was eigentlich benötigt wird und deswegen gebaut werden soll. Was ist das Geschäftsmodell? Womit verdient dein Kunde / deine Firma ihr Geld? Was sind die Geschäftsregeln und Prozesse? Finden sich diese auch im Code? Gibt es eine gemeinsame Sprache zwischen Fachbereich und Technik? Kannst du dich mit jemandem vom Fachbereich unterhalten ohne dass dieser den vielsagenden 1000 Yard-Blick bekommt und verträumt aus dem Fenster sieht? Verstehst du, wenn jemand aus dem Fachbereich mit dir über Requirements spricht oder muss immer jemand übersetzen?

Du als Entwickler solltest mindestens so gut über die Domäne bescheid wissen wie die Fachbereiche, denn um die Regeln in Software zu gießen musst du meist viel mehr wissen, als wenn du sie nur anwendest.

Verstehe das Problem

Warum stellt der Fachbereich ein Requirement? Und warum genau jetzt? Sollen vielleicht die Sales-Zahlen verbessert werden? Gibt es ein konkretes Problem beim Absatz eines Produktes? Sollen manuelle Schritte automatisiert werden um Geld, Zeit und nerven zu sparen? Was genau soll erreicht werden.

Eine Anforderung kannst / darfst / sollst du hinterfragen und zwar so lange / so oft bis du verstanden hast, was eigentlich das Grundproblem ist. Aus dem Toyota-Production-System gibt es das Prinzip der 5Ys. (Frage 5x Warum um auf die Ursache / die Wurzel eines Problems vorzustossen).

Auch die Fachbereiche profitieren von den Fragen aus der Technik, denn manchmal ist es auf den ersten Blick wirklich schwer, ein Problem zu erfassen.

Technologie ist unwichtig

Natürlich ist es als Enwickler wichtig, sich auf dem aktuellen Stand der Technik zu halten. Es sollte aber unnötig sein, das hier zu erwähnen – überlege jetzt sofort – wann hast du das letzte Mal etwas neues gelernt (Sprache, Konzepte, Pattern, Techniken?). Solltest du mehr als 15 Sek. überlegen müssen oder lautet die Antwort auf irgendetwas was mehr als 2 Wochen her ist solltest du dringend ein Buch aus der Liste unten kaufen und lesen..

Natürlich arbeiten Entwickler auch gerne mit den neuesten Technologien – damit sind wir produktiver, effizienter, besser, stärker, schneller und…

Grundsätzlich ist es aber tatsächlich so, dass die Technik eher eine untergeordnete Rolle spielt. Natürlich arbeitet niemand gerne mit Legacy-Software und hat bei jedem Commit Angst, etwas kaputt zu machen (weil man üblicherweise auch mit jedem Commit etwas kaputt macht, ob man es  wohl merkt oder nicht).

Selbst mit Technologien wie EJB und JSF lässt sich “gute” Software machen, wenn die Umgebung stimmt. Wenn ich die Wahl habe würde ich JSF natürlich nicht mit der Kneifzange anfassen, aber Technik ist meiner Ansicht nach nicht so wichtig wie eine interessante Domäne.

Daten und Verhalten ist nicht dasselbe

Der Einzige Punkt der sich direkt um Entwicklung dreht. Was die meisten Entwickler am Anfang ihrer Karriere nicht verstehen ist, Daten und Verhalten sind zwei paar Stiefel.

Beispiel folgende Klasse

public class Customer {
private String name;
private int age;
private List paymentTypes;
}

Ein unerfahrener Entwickler drückt sofort die ihm bestens bekannte Tastenkombination “Generate Getters + Setters” mit folgendem Resultat.

public class Customer {
private String name;
private int age;
private List paymentTypes;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

//....

}

Folgende Probleme ergeben sich hierbei (die jeder erfahrene Entwickler kennt und hasst).

Der State des Kunden wird nach aussen hin sichtbar. Business-Regeln werden dadurch üblicherweise so abgebildet.

public void submitOrder(Order order, Customer customer) {
   
        List<Payment> paymentTypes = customer.getPaymentTypes();
        boolean paymentAccepted = false;
        for(Payment payment : paymentTypes) {
            if(payment.getType().equals(order.getPaymentType()) {
               paymentProvider.billCustomer(order.getPrice(), customer);
               paymentAccepted = true;
            }
        }
        if(!paymentAccepted) {
           throw new IllegalStateException("Payment not accepted - but code sucks...");
        }
    
}

Du findest den Code ok? Es gibt noch was zu lernen…

Eigentlich könnte der Code so aussehen:

public void submitOrder(Order order, Customer customer) {
    if(!customer.supportsPayment(order.getPaymentType()) {
       throw new PaymentNotAcceptedException("Customer does not accept Payment", customer, order);
    }
    paymentProvider.billCustomer(order.getPrice(), customer);
}

Du findest selbst diesen Code schlecht? Ich kann von Dir was lernen…

Der Kunde hat eine Liste von unterstützen PaymentTypes (Kreditkarte, PayPal, Bankeinzug oder Bar). Das sind die Daten des Kunden. Ob ein Kunde jetzt eine bestimmte Zahlung unterstützt ist wiederum Verhalten des Kunden. Um zu wissen, welche Zahlungsarten ein Kunde unterstützt muss aber nicht die Liste von Zahlungsarten nach aussen bekannt sein. Idealerweise fragen wir den Kunden einfach – was kannst du denn?

customer.supportsPayment?

Vorteil – kommt eine weitere  Zahlungsart hinzu funktioniert die Anwendung weiterhin, denn supportsPayment funktioniert für beliebig viele Zahlungsarten.

Hier geht es tatsächlich eigentlich um das Stichwort Objektorientierung. Es wurde und wird viel darüber geschrieben. Folgende Bücher empfehle ich hierzu.

Practical Object-Oriented Design in Ruby: An Agile Primer – Hier geht es eigentlich nicht um Ruby sondern um Objektorientierung

Domain Driven Design – Pflichtlektüre für jeden Entwickler

CQRS – The Example – Ein schönes Beispiel für eine alternative Architektur mit Hilfe von CQRS.

 

Forget about Archetypes – Yeoman Generators

Szeario 1:

Ein Projekt startet, die Infrastruktur muss aufgesetzt werden. Dependencies müssen definiert und geladen werden. Die Maven-POMs werden definiert und alle Entwickler überlegen, was tatsächlich gebraucht wird um möglichst schnell mit dem Projekt durchzustarten.

Szenario 2:

Ein Entwickler hat einige Stunden Zeit und möchte sich weiterbilden. Er möchte jedoch nicht einen großteil seiner zur Verfügung stehenden Zeit mit dem Aufsetzen des Projektes verbringen, sondern er möchte direkt anfangen und Coden. Natürlich gibt es viele Demo-Projekte, die man sich beispielsweise auf GitHub klonen oder Maven-Archetypes die man verwenden kann. So richtig gut ist aber keines von beiden.

Szenrio 3:

Ein Entwickler möchte eine neue Technologie kennenlernen, nimmt sich einen der unzähligen Yeoman-Generator, generiert das Skeleton und legt direkt los.

Ich empfehle Szenario 3 – da es oft gar nicht so einfach ist, die richtigen Generatoren zu finden werde ich hier (nicht zuletzt für mich selbst) eine Liste sammeln von Generatoren, die ich gerne und oft verwende (oder zukünftig unbedingt verwenden möchte).

 

Beispiel JHipster

#install yo
npm install -g yo

#install generator
npm install -g generator-jhipster 

#create application
yo jhipster

Welcome to the Jhipster Generator

#ATTENTION, dont use a '.' in your name... I realized that 30minutes later.. see below
[?] (1/8) What is the base name of your application? (jhipster) effectivetrainings.de

[?] (2/8) What is your default Java package name? (com.mycompany.myapp) de.effectivetrainings

#hazelcast? sure!
?] (3/8) Do you want to use Hibernate 2nd level cache? (Use arrow keys)
  No 
❯ Yes, with ehcache (local cache, for a single node) 
  Yes, with HazelCast (distributed cache, for multiple nodes) 

#not sure why I would need that?
[?] (4/8) Do you want to use clustered HTTP sessions? (Use arrow keys)
❯ No 
  Yes, with HazelCast 

#websockets, absolutely!
[?] (5/8) Do you want to use WebSockets? 
  No 
❯ Yes, with Atmosphere 

#mysql, postgres?? what about some embedded database?
[?] (6/8) Which *production* database would you like to use? 
  MySQL 
❯ PostgreSQL 

#ah, here we go!
[?] (7/8) Which *development* database would you like to use? (Use arrow keys)
❯ HSQLDB in-memory 
  MySQL 
  PostgreSQL 

#compass.. hm, I prefer LESS but why not, lets try
[?] (8/8) Would you like to use the Compass CSS Authoring Framework? (y/N) y

#lets see
ls
Gruntfile.js    README.md    bower.json    node_modules    
package.json    pom.xml        spring_loaded    src

#try a build
mvn clean install

#Download a whole lot of dependencies...

#GO!

[...]

[...]

[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5:10.573s
[INFO] Finished at: Thu Feb 20 21:03:08 CET 2014
[INFO] Final Memory: 29M/67M
[INFO] ------------------------------------------------------------------------

#5 Minutes.. wow

#now ensure, all css, scripts and stuff is correctly generated and minified...
grunt
#run it
mvn spring-boot:run

#get another 400 jars of deps

[...]

[...]

#got it!

Und endlich sind da!,

JHipster

 

Spring Boot Generator

Die Mutter aller Generatoren – JHipster

JHipster-Docker Generator

Bau deinen eigenen Generator

 

ASCIIDOC gegen Schreibblockade – Grunt, Gradle und produktives Schreiben

Wer möchte nicht gerne Autor sein.

Ich als Entwickler schreibe viel Dokumentation. Hierfür verwende ich wenn möglich das vorhanden Wiki. Im schlimmsten Fall jedoch schreibe ich Dokumentation mit Word, Excel oder Pages.

Mein erstes Buch habe ich ebenfalls mit Hilfe von Pages geschrieben. Ich würde es nie wieder machen. Viel zu kompliziert und zu unhandlich.

Es sind bereits zwei weitere Bücher in der Mache. Hierfür verwende ich Asciidoc bzw. Asciidoctor und Gradle bzw. Grunt.

Folgendes Gradle-File ist hierfür ausreichend. Hier haben wir bereits Code-Highlighting inklusive.

buildscript {
    repositories {
        mavenRepo name: 'Bintray Asciidoctor repo', url: 'http://dl.bintray.com/content/aalmiray/asciidoctor'
        mavenRepo name: 'Bintray JCenter', url: 'http://jcenter.bintray.com'
    }

    dependencies {
        classpath 'org.asciidoctor:asciidoctor-gradle-plugin:0.7.0'
    }
}

apply plugin: 'asciidoctor'

asciidoctor {
    backend = 'html5'
    options = [
            eruby: 'erubis',
            attributes: [
                    'source-highlighter': 'coderay',
                    toc: '',
                    idprefix: '',
                    idseparator: '-'
            ]
    ]
}

Ascii-Doc Dateien werden per Default im Verzeichnis src/asciidoc gesucht. Dateien die geparsed werden haben Standardmäßig die Endung .adoc oder .asciidoc.

Wir erzeugen ein HTML5 Dokument aus dem Asciidoc-Dokument mit folgendem Befehl.

gradle asciidoctor

Das generierte Dokument ist per Default im Output-Verzeichnis “build/asciidoc” abgelegt.

Achtung: Derzeit ist es noch nicht möglich, PDF aus dem Asciidoc mit Gradle zu generieren. Dies ist bereits implementiert, ist aber erst mit dem Gradle-Plugin 0.8.0 verfügbar, das bisher noch nicht released ist.

Für PDF Generierung wäre das Backend nicht html5 sondern fopub

Generierung mit GRUNT

Eine Alternative hierzu ist beispielsweise die Arbeit mit Grunt. Grunt ist ein JavaScript-Task-Runner, mit dem sich so ziemlich alles automatisieren lässt.

Nehmen wir an, asciidoctor ist bereits installiert und auf der Konsole verfügbar.

Dann definieren wir folgende Datei package.json.

{
  "name": "sources",
  "version": "0.0.0",
  "dependencies": {},
  "devDependencies": {
    "grunt": "~0.4.2",
    "grunt-shell": "0.6.1",
    "grunt-contrib-watch": "~0.5.3"
  },
  "engines": {
    "node": ">=0.8.0"
  }
}

Wir benötigen sowohl das grunt-shell plugin, als auch das grunt-watcher plugin. Ziel ist es, wann immer sich die ascii-doc Datei ändert soll das HTML5-Dokument neu generiert werden.

Zusätzlich definieren wir folgende Grunt-Konfiguration.

module.exports = function (grunt) {

grunt.initConfig({
    shell: {
        generateAsciiDoc: {
            command: 'asciidoctor -b html5 -a last-update-label! -a linkcss mybook.adoc'
        },
        generatePDF : {
            command: 'asciidoctor -b docbook mybook.adoc -a last-update-label!; -a linkcss  fopub mybook.xml'
        }
    },

    watch: {
        scripts: {
            files: '*.adoc',
            tasks: ['shell'],
            options: {
                interrupt: true,
                livereload: true
            },
          },
    },

});

grunt.loadNpmTasks('grunt-shell');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['shell:generateAsciiDoc']);
grunt.registerTask('pdf', ['shell:generatePDF']);
};

Führen wir jetzt auf der Konsole grunt watch aus, so wird das Dokument jedesmal neu generiert wenn wir daran Änderungen vorgenommen haben. Perfekt für die Arbeit am neuen Buch.

Links

Asciidoctor

Asciidoctor Gradle Plugin

ASCII Doc Cheat Sheet

AsciiDoctor Cheat Sheet

AsciiDoctor Writers Guide

Live Reload Browser Plugins

Gelesene Bücher 2013

Wie jedes Jahr ist es an der Zeit zurückzublicken und mein Leseverhalten 2013 zu analysieren.

Ich habe das bereits für 2012 gemacht.

Die Liste an Büchern ist unkommentiert.  Die Bücher die ich besonders interessant gefunden habe sind mit Tipp kommentiert.

Falls die Bücher nicht zu sehen sind, liegt es wahrscheinlich am AdBlocker.

Tipp:

Tipp:

Tipp:

Tipp:

Tipp:

Tipp:

Tipp:

Tipp:

 

Global Day of Code Retreat 2013 @München / E.S.R Labs

Ich habe am 14.12.2013 am Global Day of Code Retreat teilgenommen. Hier sind meine Eindrücke.

Start in den Tag war ab 8:15, ich war ab 8:30 vor Ort. Es gab ausreichend Kaffee und und Frühstück. Viele Teilnehmer waren bereits genauso früh vor Ort.

Geleitet wurde der Tag von Sebastian Benz, den ich auch von der Softwerkskammer kenne.

Worum geht es beim CodeRetreat.

Als Softwareentwickler steht man quasi ständig unter Zeitdruck. Der Kunde möchte eine Funktionalität geliefert haben, einen Bug gefixt haben und das möglichst noch heute. Während ich etwas implementiere habe ich oft das Gefühl, dass unter der Oberfläche eine noch bessere Lösung schlummert. Wenn ich nur ein bisschen mehr Zeit investieren könnte… Und in diesem Moment kommt von Kundenseite die nächste Anfrage, wie lange es denn noch dauert.

Kurzum, wenn wir unsere Arbeit mit der eines Rockstars vergleichen. Wir Softwareentwickler stehen quasi ständig auf der Bühne, haben aber niemals Zeit zu proben und zu üben. Und dabei ist es gerade in unserem Beruf enorm wichtig, seine Fähigkeiten zu trainieren und zu schulen (siehe Code Kata).

Ein Retreat ( ein sich Zurückziehen) gibt uns genau die Möglichkeit zu machen, wofür wir tagtäglich keine Zeit und keine Möglichkeit haben. Dinge auszuprobieren, mit neuen Programmiersprachen zu arbeiten, mit fremden Entwicklern in Pairs zu arbeiten ohne dabei gestört zu werden (naja, vielleicht bis auf die letzten Session, aber dazu später mehr).

Wichtig – egal mit welcher Problemstellung gearbeitet wird – Ziel ist es nicht, das Problem zu lösen. Ziel ist es, perfekten Code zu schreiben und möglichst viel zu lernen. Selbst wenn nur eine einzige Zeile perfekter Code pro Session geschrieben wird ist das völlig in Ordnung.

Ablauf

Ich habe nicht durchgezählt, aber ich schätze dass gut 30 Entwickler teilgenommen haben.

Der Tag ist unterteilt in 6 verschiedene Sessions, in der immer und immer wieder das Gleiche Problem mit leicht veränderten Constraints gelöst wird. Das Problem was an diesem Code-Retreat gelöst wurde ist der Klassiker schlechthin – Convays Game of Life.

Das war für mich ganz spannend, da zum Einen die meisten anscheinend wirklich sehr vertraut mit dem Problem sind (manche sogar zu vertraut) und ich das Game of Life das letzte Mal im zweiten Semester programmiert hatte, was gute 10 Jahre her ist.

Nach jeder Session wird der Code unwiderbringlich gelöscht, was je nach Lösung wirklich hart sein kann. Diese Regel ist eisern und erlaubt (bis auf eine Ausnahme) keine Ausnahme.

In jeder Session (wieder bis auf eine Ausnahme) wird in verschiedenen Pairs gearbeitet, um möglichst viele unterschiedliche Eindrücke zu bekommen.

Session 1 – Get to know the Problem

In der ersten Session wurden keine bestimmten Constraints vorgegeben. Es gilt quasi, sich zunächst mit der Problemstellung vertraut zu machen und zu versuchen, das Problem zu lösen.

Programmiersprache: Java
Umgebung: IntelliJ
Lernfaktor: Ich musste mich wirklich erst nocheinmal mit dem Problem vertraut machen.

Session 2 – Ping Pong Pairing

In dieser Session sollten wir versuchen, Strict TDD zu üben. Einer schreibt den Test, der Andere schreibt die Implementierung. Einer schreibt den Test…

Programmiersprache: Java
Umgebung: IntelliJ
Lernfaktor: Pair-Programming funktioniert, Ping-Pong finde ich ein interessantes Konzept. Mich würde interessieren, ob das jemand auch im richtigen Leben einsetzt

Session 3 – Evil muted Programmer

Die meiner Ansicht nach beste Session des Tages. Es war verboten, mit seinem Pairing-Partner zu sprechen. Kommuniziert wurde nur über den Code. Gearbeitet wurde quasi wieder im Ping-Pong Modus. Der “Gute” gibt einen Test vor, der “Böse” implementiert den Test, aber nur so, dass er gerade eben mal grün wird.

Programmiersprache: Java
Umgebung: IntelliJ
Lernfaktor: Ich war der Gute. Mein Partner hatte es zu Beginn sehr leicht, meine Tests zu sabotieren. Je mehr Tests aber da waren, desto schwieriger wurde es. Irgendwann musste tatsächlich auch Logik implementiert werden. Trotz der Constraints haben wir es geschafft, das Game of Life in dieser Session abzuschliessen. Sehr beeindruckend.

Session 4 – Be as fast as you can

In dieser Session sollte so schnell wie möglich gearbeitet werden. Keine Vorgaben ob Tests zu schreiben sind, wie implementiert wird. Hauptsache, das Game of Life ist so schnell wie möglich implementiert.

Programmiersprache: C#
Umgebung: Visual Studio
Lernfaktor: C# sieht wirklich gut aus und gefällt. Wir haben versucht, das Game of Life Objektorientiert zu lösen und da wir schnell sein wollten – ohne Tests:). Schön zu sehen, nachdem wir angenommen hatten fertig zu sein mussten wir trotzdem Tests schreiben um zu verifizieren, ob die Implementierung wirklich funktioniert. Leider hatte sich ein Fehler eingeschlichen, so dass die Regeln nicht funktioniert haben. Hätten wir Tests von Anfang an geschrieben hätte zum Einen unsere “API” besser ausgesehen und wir hätten den Fehler viel schneller bemerkt. Wir mussten leider mitten im Umbau aufhören, so dass wir eine unfertige Implementierung zurücklassen mussten.

Nach dieser Session sollte der Code nicht gelöscht werden!

Session 5 – Refactor this mess

In der vorherigen Session sollte der Code nicht gelöscht werden, da jetzt der Rechner einfach an das nächste Paar weitergereicht wurde. Und diese sollten unseren Code refactoren und verbessern. Zugegeben, sie hatten keine leichte Aufgabe.

Was mich sehr erstaunt hat waren die Kommentare von einem der beiden, der sich fürchterlich über unsere Implementierung aufgeregt hat. Ich weiß, dass derjenige sehr viel Erfahrung mit Code-Retreats, Katas und auch mit dem Game of Life hat. Er hatte aber offensichtlich vergessen, dass der Tag für Experimente da ist und keinesfalls für fertige Implementierungen.

Andererseits war dies die wirklich falsche Session für Experimente..

Programmiersprache: Java
Umgebung: Eclipse
Lernfaktor: Ich habe einen komplett neuen Ansatz kennengelernt, wie das Problem gelöst werden kann (mit einem endlosen Board). Diese Lösung ist mit Sicherheit nicht in dieser Session entstanden, da sie sehr ausgereift war.

Session 6 – Dictator

Letzte Session des Tages war Dicator. Es gab keine Vorgaben wir gearbeitet werden sollte. Sebastian ging aber durch die Reihen in der Rolle des Architekten-Diktators und hat fleissig Zettel auf die Bildschirme geklebt, was denn refactored werden muss und was nicht gut ist. Es war uns nicht erlaubt, weiterzuarbeiten bis die angeprangerten Refactorings durchgeführt wurden.

Programmiersprache: Java
Umgebung: Eclipse
Lernfaktor: Es stört unglaublich, wenn jemand von aussen vorgibt, was man wann zu tun hat. Wir waren mitten in einem Test als der Dictator von hinten kam und eine viel zu lange Methode angeprangert hat. Interessanterweise hatte mein Pairing-Partner eine Lösung anprogrammiert die ich so noch nicht kannte und die ich auch nicht auf Anhieb durchblicken konnte. Es war also doppelt schwer, Code zu refactoren für den Diktator und gleichzeit noch zu verstehen, welche Lösung wir anstreben.

Fazit

Der Tag war interessant und lehrreich. Ich würde aber beim nächsten Mal ein wenig besser vorbereiten. Ich habe viel zu viel Zeit verschwendet, die verschiedenen Möglichkeiten des Game of Life zu verstehen als auf den eigentlichen Sinn des Tages. Mein Tipp – wieso wird das Problem nicht vorher bekannt gegeben? Nicht jeder programmiert das Game of Life einmal die Woche und ist damit vertraut. Ich würde mich an diesem Tag gerne auf andere Dinge konzentrieren und nicht auf die Implementierung des Algorithmus.

Der Weg zum Meister – meine 10.000 Stunden als Entwickler

Ten thousand hours of practice is required to achieve the level of mastery associated with being a world-class expert — in anything.

Daniel Levitin

Die 10.000 Stunden Regel sollte jedem Entwickler (und auch jedem anderen) ein Begriff sein. Die Regel basiert ganz lose auf den Studien von Anders Ericcson und wurde hauptsächlich durch das Buch “Outliers” von Malcolm Gladwell bekannt.

Die Regel ist nicht wissenschaftlich belegt sondern ist eher als Richtlinie zu verstehen und besagt, dass jeder der auf seinem Fachgebiet führend sein oder werden möchte, mindestens 10.000 Stunden “Deep bzw. Delibate Practice” benötigt.

Was bedeutet Deep Practice?

Karl der Entwickler

Erstellt auf sp-studio.de

Nehmen wir zum Beispiel Karl.

Karl ist Entwickler und das seit 10 Jahren. Karl ist aber niemand, der sich intensiv mit seiner Arbeit und seiner Tätigkeit identifiziert, sondern ein 09:00 – 17:00 Entwickler.

Karl ist auch niemand, der sich in seiner Freizeit mit neuen Themen, Programmiersprachen und Problemstellungen auseinandersetzt.

Karl macht seinen Job – gut und zufriedenstellend – aber nicht herausragend.

Man könnte jetzt annehmen, das Karl die 10.000 Stunden schon lange geknackt hat und als Meister seines Faches zählt.

Mal im Kopf überschlagen:

220 (grob Arbeitstage pro Jahr abzgl. Urlaub) * 8 (Stunden pro Tag) * 10 Jahre = 17.600 Stunden

So gerechnet müsste Karl also ein Superstar und ein Held in seinem Metier sein. Das was Karl aber tagtäglich macht ist keine Deliberate Practice sondern sein Tagewerk, und Tagewerk zählt nicht in die 10.000 Stunden Regel.

Was wäre wirkliche Praxis in Karls Job als Entwickler:

  • Auseinandersetzung mit komplexen Problemen, die neue Denkmuster erfordern
  • Neue Programmiersprachen, Konzepte und Ansätze erlernen und meistern
  • komplexe Algorithmen verstehen
  • Pair Programming und Auseinandersetzung mit Kollegen
  • Konzepte lehren und schulen
  • Fokussierung und Konzentration

Was zählt nur in Teilen:

  • Wiederholte und oft gelöste Aufgabenstellungen (sich wiederholende Aufgaben können für Routine sorgen, aber nur wenn Sie bewusst gelöst werden und nicht “automatisch”)

Was zählt gar nicht:

  • Fachfremde Aufgaben (Rechnungsstellung etc.)

Stellen wir die Rechnung also nochmals auf:

220 (grob Arbeitstage pro Jahr abzgl. Urlaub) * 4 (Stunden pro Tag) * 10 Jahre = 8.800 Stunden

Nehmen wir vereinfacht an, Karl verbringt pro Tag 4 Stunden mit echter Praxis für seine Arbeit. An manchen Tagen vielleicht weniger, an manchen Tagen mehr. Im Mittel könnte das stimmen. Das bedeutet, Karl hat bis dato 8.800 Stunden Praxis gesammelt. Im fehlen also noch genau 1.200 Stunden zum Meister.

Da potentiell die Möglichkeit zur Konzentration und Fokussierung abnimmt, je länger man im gleichen Job arbeitet,  wird auch die Praxis, die Karl pro Jahr sammeln kann abnehmen. Das bedeutet, es ist sehr fraglich, ob er jemals den Status eines Meisters erreichen kann (und vielleicht auch will).

Ich stelle die Rechnung mal grob für mich auf. Ich habe im Jahr 2002 angefangen, mich mit Programmiersprachen zu beschäftigen (ungefähr..).

2002 (grob jeden zweiten Tag eine Stunde) – (250 / 2 * 1)
2003 (grob jeden dritten Tag eine Stunde, da ich hier viel gearbeitet habe) – (250 / 3 * 1)
2004 (im Studium jeden Tag ca. eineinhalb Stunden inkl Wochenenden) – (250 * 1.5)
2005 – (im Studium jeden Tag ca. zweieinhalb Stunden inkl Wochenenden)(250 * 2.5)
2006 – (Praxissemester – hier habe ich ein halbes Jahr lang extrem viel gelernt und gearbeitet)
(125 * 6) + (125 * 2.5)
2007 – (Annahme, 3 Stunden Praxis pro Tag + 150 Extrastunden für die Abschlussarbeit) (250 * 3) + 150
2008 – (Studienabschluss und erstes grosses Projekt mit steiler Lernkurve) (125 * 5)  + (125 * 6)
2009 – (extrem viel gearbeitet und gelernt – Annahme 270 Arbeitstage) (270 * 6)
2010 – (einige neue Projekte, viele unterschiedliche Programmiersprachen und Werkzeuge) 270 * 6 + 100
2011 – 280 * 6
2012 – (großes neues Projekt, neues Team, Teamlead und Scrummaster) – 280 * 6
2013 (Selbstständigkeit)- 80 * 10

Die Rechnung ergibt also folgendes:

(250 / 2 * 1) + (250 / 3 * 1) + (250 * 1.5) + (250 * 2.5) + (125 * 6) + (125 * 2.5) + (250 * 3) + 150 + (125 * 5)  + (125 * 6) + (270 * 6) + 270 * 6 + 100 + 280 * 6 + 280 * 6 + 80 * 10 = ~12.000 Stunden Praxis in 10 Jahren.

(Natürlich ist die Rechnung komplett an den Haaren herbeigezogen, aber trotzdem interessant, wenn man mal so grob zusammenrechnet)

Das entspricht in etwa auch den Erfahrungen anderer Menschen, die sich mit dieser Regel befasst haben. Typischerweise braucht man 10 Jahre und ~10.000 Stunden Praxis, um gut in etwas zu werden ( ich behaupte jetzt einfach mal, dass ich in dem was ich mache ganz OK bin).

Es ist extrem interessant, wenn man sich weiter mit dem Thema Deliberate Practice beschäftigt. Hier sind einige Buchempfehlungen zum Thema:

 

 

Malcolm Gladwell – Outliers

 

Robert Greene – Mastery

 

Doug Lemov – Practice Perfect

Weitere Links:

10.000 Stunden Regel

Was ich so mache um auf meine 10.000 Stunden zu kommen

 

 

 

 

Warum das Team verantwortlich ist – immer

Im letzten Artikel habe ich um ein kleines Lächeln gebeten.

Heute geht es zurück zum Ernst des Lebens, denn wir Entwickler haben eine Aufgabe zu erfüllen. Wir machen das aber üblicherweise nicht allein, sondern hinter jedem Entwickler steht hoffentlich ein schlagkräftiges Team.

Gerade wir Agilisten haben hier sehr viel Glück, denn kaum einer hat jemals vom Ein-Mann-Scrum-Team gehört. Auch interessant wäre, wie die WIP-Limits in eine Ein-Mann-Kanban-Team gesetzt werden?:)

Was bedeutet es aber, im Team zu arbeiten?

Hat man hierdurch weniger Verantwortung? Kann man sich in der “Masse” verstecken? Machts jemand anders?

Definitv nein.

Es gibt einen schönen Spruch, dessen Autor ich leider nicht kenne:

„Wenn der Blinde den Lahmen trägt, kommen sie beide fort.“

Wenn ein Team arbeitet hat es genau zwei Möglichkeiten – entweder das Team arbeitet vereint auf ein Ziel hin – dann sind die meisten Teams kaum zu stoppen. Oder das Team behindert sich selbst (Neid, Misgunst, Misstrauen), dann sind sie nicht schneller oder besser als ein Einzelner Entwickler.

Das Team trägt die Verantwortung, Features, Produkte, Bugfixes bis dorthin zu bringen, wo sie dem Kunden echten Mehrwert generieren – Produktion.

Nicht ein einzelner Entwickler (“Wer hat diesen Bug eingebaut?”, “Ich bin für die Service-Schicht verantwortlich”), sondern das Team ist verantwortlich. Kommen Bugs ins System hat das Team versagt – fehlende Code-Reviews, fehlende Kommunikation oder einfach nur Faulheit.

Andererseits gibt es im Team keine Super-Heros – das Team sorgt dafür, dass das Know-How verteilt wird (ist nicht immer einfach, fällt mir auch manchmal schwer), so dass mit jedem Feature mindestens ein Entwickler etwas lernt.

So entwickelt das Team im Lauf der Zeit eine Kaizen-Kultur und entwickelt unglaubliche Schlagkraft.

Das Team ist verantwortlich – immer.


War dieser Blogeintrag für Sie interessant? Evtl. kann ich noch mehr für Sie tun.

Trainings & Know-How aus der Praxis zu

  • Apache Wicket 1.4.x, 1.5.x, 1.6.x
  • GIT – Best Practices, Einsatz, Methoden
  • Spring
  • Java
  • Scrum & Kanban
  • Agiles Arbeiten
Consulting & Softwareentwicklung

  • Requirements Engineering
  • Qualitätssicherung
  • Software-Entwicklung
  • Architektur
  • Scrum & Kanban

Warum Freundlichkeit professionell ist

Im letzten Artikel habe ich darüber philosophiert, warum ein Entwickler kein Scrummaster und ein Scrummaster kein Entwickler ist.

Eine weitere wichtige Lektion die ich gelernt habe ist, man sollte immer Lächeln, egal was passiert. Vor allem als Scrummaster gerät man oft zwischen die Fronten, muss Probleme beseitigen, muss kommunizieren.

Es gibt einen schönen Spruch von Phyllis Diller:

A smile is a curve that sets everything straight.

Egal was passiert, jedes Problem lässt sich leichter mit Freundlichkeit lösen als mit Agression, Argumentation und Druck.

Ein Buch, das hier wirklich schöne Einblicke bietet (auch wenn der Titel ein wenig seltsam anmutet) ist dieses:

Dieses Buch hat mir wirklich nochmal die Augen geöffnet, und ich empfehle es jedem Scrummaster (und auch jedem Teammitglied), einfach mal zu lesen. Es geht nicht darum, Freunde oder so etwas zu finden, sondern dieses Buch erklärt sehr schön und anschaulich, warum es so wichtig ist, jederzeit freundlich zu bleiben, weil man dadurch nur gewinnen kann.

Lächeln ist professionell :)


War dieser Blogeintrag für Sie interessant? Evtl. kann ich noch mehr für Sie tun.

Trainings & Know-How aus der Praxis zu

  • Apache Wicket 1.4.x, 1.5.x, 1.6.x
  • GIT – Best Practices, Einsatz, Methoden
  • Spring
  • Java
  • Scrum & Kanban
  • Agiles Arbeiten
Consulting & Softwareentwicklung

  • Requirements Engineering
  • Qualitätssicherung
  • Software-Entwicklung
  • Architektur
  • Scrum & Kanban

Warum Scrummaster keine Entwickler und Entwickler keine Scrummaster sind (gleichzeitig)

Im letzten Artikel habe ich darüber philosophiert, warum Unit Tests so unglaublich wichtig sind.

Heute möchte ich erklären, warum meiner Ansicht nach Scrummaster niemals Entwickler und Entwickler niemals Scrummaster sein sollten, gleichzeitig.

Ich bin in der glücklichen Situtation, dass ich schon seit langer Zeit in einem interessanten Projekt in einem agilen Umfeld arbeiten kann. In meinem jetzigen Projekt habe ich eine Doppelrolle inne. Ich bin sowohl Entwickler als auch Scrummaster. Leider ist kein Budget für einen dedizierten Scrummaster vorhanden.

Warum ist das ein Problem?

Jeder Entwickler im Team hat bestimmte Vorstellungen, wie das Projekt zu Laufen hat, wie neue Funktionalität implementiert werden soll und wie generell gearbeitet wird. Ich bin zusätzlich so etwas, wie der Technical Lead des Projektes. Ich kümmere mich um Architektur, Qualität und Kommunikation (immer zusammen mit dem Team natürlich).

Ein Scrummaster hingegen sollte keine eigenen Interessen verfolgen,  sondern das primäre Interesse des Scrummasters sollte sein, das Team in jeder Hinsicht zu unterstützen und generell voranzubringen.

In einer Doppelrolle ist das sehr schwierig bis hin zu unmöglich.

Bestes Beispiel ist die Retrospektive, die nach jedem Sprint durchgeführt wird.

In der Retrospektive reflektiert das Team über den Vergangenen Sprint, über Dinge die gut und Dinge die weniger gut gelaufen sind. Die Retrospektive dient dem Team als Gesprächsplattform, um Themen in ungezwungener Atmosphäre auf den Tisch zu bringen und zu diskutieren.

Idealerweise durchläuft eine Retrospektive die folgenden Phasen:

  1. Begrüssung
  2. Rahmen schaffen
  3. Daten sammeln
  4. Aktionen identifizieren
  5. Verabschiedung

Die einfachste Variante für Punkt 3 (das Herz der Retrospektive) sind beispielsweise folgende Aufgabenstellung:

  • Identifiziere 3 Punkte, die sehr gut gelaufen sind, die wie unbedingt beibehalten sollten
  • Identifiziere 3 Punkte, die verbesserungswürdig sind.

In der letzten Retrospektive bei uns im Team war ich wieder in der schwierigen Situation, sowohl Entwickler als auch Scrummaster zu sein.
Jedes Teammitglied hat einige Punkte auf Post-Its Notes notiert. Von mir kam der Punkt:

Meiner Ansicht nach haben wir zu viele Stories gleichzeitig in Bearbeitung.

Ein Punkt, der mir sehr auf der Seele brennt, und den ich unbedingt ändern möchte. Dieser Punkt ist im Team jedoch nicht auf Gegenliebe gestossen, da hier dieser Eindruck nicht unbedingt vorhanden ist.

Was mache ich jetzt als Scrummaster/Entwickler?

Als Scrummaster würde ich den Punkt zwar aufnehmen, evtl auch darüber diskutieren aber wenn der Konsens im Team klar dahin tendiert, dass dies kein Problem darstellt würden daraus wahrscheinlich keine Aktionspunkte entstehen.

Ich als Entwickler weiß, dass wir zu viele Stories in Bearbeitung haben und weniger Stories viel schneller dazu führen würden, dass Dinge wirklich abgeschlossen, lauffähig und in einem Produktivumgebung landen.

Beharre ich jetzt auf meinem Standpunkt und ignoriere meine Scrummaster-Rolle?

Akzeptiere ich meine Rolle als Scrummaster und schlucke meinen Entwicklerstolz herunter?

Die Doppelrolle als Scrummaster/Entwickler ist mehr als suboptimal. Am besten ist es, einen Scrummaster aus einem der anderen Teams (sofern vorhanden) zu bitten, die Leitung der Retrospektive zu übernehmen. Dann könnte ich meine Rolle als  Scrummaster für die Retrospektive vergessen und mich voll und ganz auf die Entwicklerseite und eine erfolgreiche Retrospektive konzentrieren.

Habt ihr damit Erfahrung?

 


War dieser Blogeintrag für Sie interessant? Evtl. kann ich noch mehr für Sie tun.

Trainings & Know-How aus der Praxis zu

  • Apache Wicket 1.4.x, 1.5.x, 1.6.x
  • GIT – Best Practices, Einsatz, Methoden
  • Spring
  • Java
  • Scrum & Kanban
  • Agiles Arbeiten
Consulting & Softwareentwicklung

  • Requirements Engineering
  • Qualitätssicherung
  • Software-Entwicklung
  • Architektur
  • Scrum & Kanban