Die größte Herausforderung unserer Zeit

Wenn ich Sie jetzt fragen würde “Was ist die größte Herausforderung unserer Zeit?”, was würden Sie antworten? Wahrscheinlich beschäftigen wir uns alle mit den unterschiedlichsten Dingen. Wir setzen wahrscheinlich auch alle unterschiedliche Schwerpunkte und Prioritäten in unserem Leben. Aber ich glaube ein Thema ist dabei besonders wichtig. Je nachdem wie erfolgreich wir uns mit diesem Thema auseinandersetzen bestimmt, wie viel Erfolg, Freude und Erfüllung wir erleben. Ich habe mir die eingangs gestellte Frage auch gestellt und beantwortet: Ich bin der Meinung, die größte Herausforderung unserer Zeit ist,

wie wir unsere Zeit einteilen, um eine gute Balance zwischen
Arbeit, Hobbies, Familie & Freunde und Gesundheit zu finden.

Vielleicht erinnern diese Punkte uns an die fünf Grundbedürfnisse, insbesondere an physiologische, soziale und individuelle Bedürfnisse. Aber während da der Fokus auf was uns wichtig ist und was wir brauchen liegt, geht es bei den vier genannten Kategorien um wo wir Zeit investieren müssen. Unsere Bedürfnisse bestimmen diese Punkte und priorisieren sie. Wenn wir uns dann mit den genannten Aspekten beschäftigen, tragen wir zu der Befriedigung unserer Bedürfnisse bei.

Es gibt Dinge, die nicht eindeutig einer Kategorie zugeordnet werden können, oder die alle Kategorien betreffen. Hier soll es aber eher um die Punkte gehen, die gegenseitig um unsere Zeit konkurieren. Um zwischen diesen eine Balance zu finden, müssen wir die uns zur Verfügung stehende Zeit einteilen. Unsere Tage haben 24 Stunden. In einer Woche arbeiten wir in der Regel 5 Tage und haben dann 2 Tage Wochenende. Was machen wir damit? Ein einfaches Rechenbeispiel könnte so aussehen:

168 Stunden pro Woche
– 56 Stunden schlafen (7 * 8 Stunden)
– 3 Stunden Sport (3 * 1 Stunden)
– 7 Stunden Körperhygiene (7 * 2 * 0.5 Stunden)
– 3.5 Stunden Frühstück (7 * 0.5 Stunden)
– 3.5 Stunden Abendessen (7 * 0.5 Stunden)
– 2 Stunden Mittagessen am Wochenende (2 * 1 Stunden)
– 40 Stunden im Büro (5 * 8 Stunden)
– 5 Stunden Mittagspause (5 * 1 Stunden)
– 5 Stunden Büro An- und Abfahrt (5 * 2 * 0.5 Stunden)
= 43 restliche Stunden für Mitmenschen und Hobbies

Ich könnte hier jetzt weiter rechnen und die bestehende Zeit noch auf Familie, Freunde und Hobbies aufteilen. Aber es geht mir hier nicht um ein Rezept für ein ausgeglichenes Leben. Ich glaube es gibt dafür kein allgemeines Rezept, zumindest kenne ich keins. Wenn wir eine Balance zwischen Arbeit, Hobbies, Familie & Freunde und Gesundheit erreichen wollen, müssen wir eine persönliche Zeitplanung für unser Leben vornehmen. Wenn wir es nicht tun und nicht versuchen unsere Zeit einzuteilen, dann werden eine oder mehrere Kategorien zu kurz kommen. Die darunter liegenden Bedürfnisse werden dann nicht befriedigt und wir werden zunehmend unglücklicher. Zeit ist unser bestes Werkzeug, deswegen lasst es uns weise nutzen.

Das ist die größte Herausforderung unserer Zeit.

 

Zeit ist das Element, in dem wir existieren. Wir werden entweder von ihr dahin getragen oder ertrinken in ihr.
~Joyce Carol Oates

 

 

The Dark Side of Pair Programming

Pair Programming bezeichnet das Entwickeln von Software zu zweit. Das hat laut [1] viele Vorteile: Die Qualität der Software wird verbessert, Fehler werden früh erkannt, man hat mehr Spaß an der Arbeit, Wissen verbreitet sich im gesamten Team und die Kommunikation im Team verbessert sich. Doch all das funktioniert nicht automatisch. Man bekommt diese Vorteile nicht automatisch wenn man zu zweit vor dem Computer sitzt. In [2] werden beispielsweise häufige Schwierigkeiten beim Pairing beschrieben.

Probleme

In diesem Blogpost möchte ich von meinen negativen Erfahrungen und Beobachtungen mit Pair Programming berichten. Zu jedem Punkt möchte ich auch Maßnahmen vorschlagen, die zu einer Verbesserung führen können.

  Zeit-intensiv

Pair Programming kostet Zeit. Das ist besonders bei heterogenen Pairs der Fall. Man bremst sich aus indem man erklärt und diskutiert. Viele Diskussionen neigen dazu abzudriften und zu längeren Grundsatzdiskussionen zu werden. Das ist sehr frustrierend, weil man beschäftigt sich viel mit sich selbst und mit Meinungen, statt mit den Problemen, die man eigentlich lösen will.
Mitigation: Man sollte größere Diskussionen verschieben und besser in der Retrospektive diskutieren. Außerdem könnte man versuchen homogenere Pairs zu bilden. Man könnte hier auch einen dritten Programmierer dazu nehmen (Mob Programming [3]), nicht um mitzudiskutieren, sondern um schonmal weiter arbeiten zu können, während zwei sich zum diskutieren ausklinken.

  Kontext-Switches

Wenn beide Pairing Partner kreativ sind, haben auch beide viele Ideen, die sie ausprobieren wollen. Besonders wenn einer von der Idee des anderen nicht überzeugt ist, aber keine Gegenargumente hat und auch keine Diskussion anfangen möchte, wird er die Idee ausprobieren lassen. Oder wenn einer googeln und der andere dekompilieren will. Das Ausprobieren einer eigenen Idee muss in beiden Fällen dann erstmal warten. Man bremst sich auch hier wieder gegenseitig aus. Unterschiedliche Lösungsansätze können nicht gleichzeitig verfolgt werden sondern müssen synchronisiert werden. Das führt in kreativen Phasen zu viel teurem Hin und Her, weil man muss ja wieder reverten oder den Branch wechseln.
Mitigation: Man sollte in diesen Fällen einen zweiten Computer am selben Schreibtisch benutzen. Dann könnte das Ausprobieren von Ideen besser parallelisiert werden.

  Anstrengend

Durch Erklärungen, Diskussionen und Vorschläge steigt die Lautstärke im Büro. Das kann in Großraumbüros das Arbeiten anderer, auch Pairs, stören. Außerdem neigen Pairs dazu, sich gegenseitig unter Druck zu setzen, sodass sich beispielsweise keiner mehr traut kurz aufzustehen oder eine kreative Pause einzulegen. Ich finde es gut, das Pair Programming in vielen Fällen Prokrastination verhindert, aber schlecht, wenn man keine Zeit oder Ruhe mehr zum Nachdenken hat. Wenn einer sich tief reindenken will, wird das massiv erschwert, wenn der andere ihn durch den Code hetzt, erklärt und diskutiert.
Mitigation: Man sollte regelmäßige Pausen fest einplanen, zum Beispiel mit dem Pomodoro-Timer [4]. Zum Nachdenken könnte man sich auch kurzzeitig in ein anderes Büro zurückziehen.

  SOZIALE REIBUNG

Unterschiedliche Ansichten und Vorlieben führen häufig dazu, dass man sich gegenseitig kritisiert und verletzt. Das führt zu persönlichen Spannungen und häufig auch zu Kompromissen, mit denen keiner richtig zufrieden ist. Man hat dann den Eindruck, beide Pairing Partner würden in unterschiedliche Richtungen ziehen. Und wenn man erstmal unglücklich ist, wird alles noch viel schlimmer.
Mitigation: Wir sollten uns neu bewusst machen, worum es eigentlich geht. Es geht um die Bedürfnisse und Interessen des Kunden und nicht um unsere eigenen. Das ist Kundenorientierung. Oft fehlt uns die richtige Perspektive, wenn wir über Code diskutieren und beleidigt sind, wenn er zu Recht oder zu Unrecht kritisiert wird. Wir sollten uns etwas weniger wichtig nehmen [5]. Dan North empfiehlt die emotionale Verbindung, die wir oft zu unserem Code haben, auf die Bedeutung der Software für die Nutzer zu verlagern [6].

Let’s care less about the beauty of the code and more on the impact on success and happiness of the users. Software is the means to the end. As little software as needed to get there.
~ Dan North

  Soziales Faulenzen

Laut Agile Alliance [2] ist das größte und häufigste Problem, dass Entwickler während der Pairing Sitzung nicht gleichermaßen engagiert arbeiten. Das kann dazu führen, das sich einer zurücklehnt, passiv wird und mit den Gedanken zunehmend woanders ist. Spätestens wenn er das Handy zückt hat er sich abgemeldet. Aber selbst wenn beide aktiv bleiben, gibt es einen Leistungsabfall der beteiligten Personen [7]. Sobald die Leistung des Einzelnen nicht mehr sichtbar ist, sondern nur noch die der Gruppe, sinkt die Leistung des Einzelnen in einer Zweiergruppe auf 93%. Je mehr Personen beteiligt sind, desto weniger investieren diese in die Erreichung des gemeinsamen Ziels und verlassen sich zunehmend auf die Gruppe. Verantwortung wird weniger übernommen, sodass man sich hinter Beschlüssen der Gruppe versteckt. Außerdem trifft die Gruppe risikoreichere Entscheidungen weil niemand die ganze Schuld trägt. Beim Pair Programming führt das dazu, dass beide Entwickler oberflächlicher arbeiten. Man fühlt eine trügersiche Sicherheit, da der andere die Lösung auch gut findet und keine Probleme sieht.
Mitigation: Um die Pairing Partner an gleichmäßiges Engagement zu erinnern, kann ein Tool wie der Pair Activity Monitor unterstützen. Das Tool stellt Tastatur- und Mausaktivität beider Pairing Partner gegenüber. Dadurch wird ein großer Teil der Leistung wieder sichtbar. Metriken wie Tastaturanschläge oder Lines Of Code sind zwar keine aussagekräftigen Indikatoren für Software-Qualität, aber sie eignen sich hervorragend um Leistungdifferenzen innerhalb eines Pairs zu visualisieren. Gute Ideen und gedankliche Leistung werden davon natürlich nicht berücksichtigt. Diese sollten explizit einer Person zugeschrieben und entsprechend erwähnt werden.

Personas

Neben den oben beschriebenen negativen Erfahrungen mit Pair Programming sind mir im Laufe der Zeit verschiedene immer wiederkehrende Verhaltensweisen aufgefallen. Auch bei mir selber. Diese Verhaltensweisen, die ich alle als störend empfinde, möchte ich hier in Form von Personas einmal zusammenfassen. Damit sind keine bestimmten Personen, sondern archetypische Charaktere gemeint.

  • Der Abgelenkte
    spielt mit dem Handy, ist gedanklich woanders und lenkt andere mit Fragen oder Geschichten ab.
    Mitigation: Driver-Navigator-Balance, stehend am Whiteboard denken/lösen
  • Der Zuschauer
    schaut einfach nur zu und sagt nichts. Hat auch keine Ideen und kein Interesse.
    Mitigation: Driver-Navigator-Balance, nach Meinung fragen, abholen wenn abgehängt
  • Der Neue
    kennt sich noch nicht gut aus, traut sich noch nicht zu sagen was er denkt. Er fragt lieber viel.
    Mitigation: Ego Suspension
  • Der Bedachte
    lässt sich viel Zeit, denkt mehr und schreibt weniger.
    Mitigation: am Whiteboard denken/lösen (Versuchung abzuhängen ist geringer)
  • Der Eigensinnige
    macht alles selbst und lässt niemanden an die Tastatur. Er entscheidet alleine oder hat schon entschieden.
    Mitigation: Driver-Navigator-Balance, zweiter PC, Ego Suspension, Vorhaben klar kommunizieren und erst dann coden
  • Der Lehrer
    redet viel und erklärt alles über-ausführlich.
    Mitigation: Verständnis äußern, weiter arbeiten, Ego Suspension
  • Der Wichtige
    wird andauernd von irgendjemand gefragt oder geholt. Er weiß viel und hat viel Erfahrung.
    Mitigation: geheimes Büro/Besprechungszimmer
  • Der Überzeugte
    beharrt auf seinem Standpunkt und seiner Sicht der Dinge. Es ist extrem schwer ihn zu überzeugen.
    Mitigation: Ego Suspension
  • Der Hetzer
    braucht keine Ruhe und scheucht den Partner durch den Code (“scroll nochmal nach oben”, “nochmal zurück”), obwohl der gerade etwas anderes nachsehen will. Besonders beim Debuggen.
    Mitigation: Driver-Navigator-Balance, Vorhaben klar kommunizieren und erst dann loslegen
  • Der Alternative
    raucht viel und duscht selten. Sein Tisch und seine Tastatur sind versifft. Er will immer an seinem PC pairen.
    Mitigation: zweiter PC, mehr Abstand

Auch ich erkenne mich von Zeit zu Zeit in einer der beschriebenen Personas wieder. Dabei ist es mir doch wichtig zu einem effizienten und produktiven Arbeitsumfeld beizutragen. Wir müssen uns immer wieder neu daran erinnern und versuchen, möglichst wenig soziale Reibung zu erzeugen und stattdessen gute und engagierte Pairing Partner sein.

Fazit

Gute und konstruktive Pairs sind nicht selbstverständlich. Ich habe einige Probleme und nachteilige Verhaltensweisen beschrieben, die die eingangs erwähnten Vorteile sehr schnell zunichtemachen. Wir müssen uns fragen: Bekommen wir die Vorteile wirklich? Wenn nicht, ist Pair Programming teure Zeit- und Energieverschwendung.

Wenn Pairs sich viel mit sich selbst beschäftigen, nicht gleichermaßen engagiert arbeiten oder die Effekte des sozialen Faulenzens deutlich werden, sollte sich etwas ändern. Und wenn es nicht möglich ist gute Pairs zu bilden, dann ist es sinnvoller nicht zu pairen. Da man die Vorteile nicht hat, gibt es auch keinen Grund mit angezogener Handbremse zu fahren. So ist man wenigstens schneller fertig. Wenn wir aber pairen, dann wollen wir gute Pairing Partner sein um gemeinsam mehr zu erreichen, als wir alleine erreicht hätten.

Don’t try to be right. Try to be helpful. Try to be useful.
~ James Wells

 

 

 

Links

[1] https://www.it-agile.de/wissen/agiles-engineering/pair-programming/
[2] https://www.agilealliance.org/glossary/pairing/
[3] http://mobprogramming.org/
[4] https://en.wikipedia.org/wiki/Pomodoro_Technique
[5] http://www.johnniland.com/suspension-of-ego/
[6] http://dotnetrocks.com/?show=1118
[7] https://en.wikipedia.org/wiki/Social_loafing

Bugs, Problem der Entwickler?

Eigentlich ist ein Bug

“an error, flaw, failure or fault in a computer program or system that causes it to produce an incorrect or unexpected result, or to behave in unintended ways.” (Wikipedia)

Also auf die Software bezogen, erstmal unabhängig von der Ursache. Weil die Entwickler dann analysieren und SM, PO, PM, BA und QS nicht viel machen können, wird Bug oft gleichbedeutend mit “Fehler der Entwickler” verstanden, obwohl die eigentliche Ursache noch gar nicht klar ist. Eventuell gab es implizite Anforderungen, die verloren gegangen sind, oder etwas wurde nachträglich anders gestaltet. Bevor die genaue Ursache bekannt ist (fehlerhafte Entwicklung, mangelnde Spezifikation, keine QS, …) betrifft ein Bug alle am Produkt arbeitenden Personen. Jeder sollte sich fragen, was er hätte tun können, um diesen Bug zu vermieden. Die falsche Vorstellung, dass ein Bug erstmal ein Entwicklungsfehler ist, führt oft zu heimlicher Schuldzuweisung, Frustration und Rechtfertigung der Entwickler. Zusammengefasst, einer kontraproduktiven Fehlerkultur. Wenn sich diese falsche Vorstellung manifestiert, kann es helfen, die Namen der Artefakte und damit deren verstandene Bedeutung zu ändern. Wundern Sie sich aber nicht, wenn das auf Widerstand stösst. Immerhin ist es für viele Nicht-Entwickler eine komfortable Situation per Default “nicht schuld zu sein” und die Verantwortung bei den Entwicklern zu wissen.

Weniger (be)wertend

Bug oder Defekt zu einer Story ist zu sehr wertend (“schlecht”, “falsch”). Das unterstützt und vereinfacht Schuldzuweisung bewusst oder unbewusst. Zwar kann man sagen, das sind “fachliche” Defekte, aber eigentlich ist das immer ein “Problem” mit dem Produkt der Entwickler. Und damit überträgt sich das wertende auf die Arbeit der Entwickler. Die Entwickler können schuld sein, dann wäre diese Sichtweise richtig. Die Entwickler können aber auch nicht Schuld sein, dann wäre es die falsche Sichtweise. Die Ursachen eines Bugs oder Defektes sind vielfältig, warum haben wir also ein Wort gewählt, das implizit die Entwickler “beschuldigt”, ob wir das wollen oder nicht? Sinnvoll wäre ein wertfreier Begriff wie Verbesserung oder Erweiterung, der sich auf alles anwenden lässt. Schließlich wäre die einzig zielführende Reaktion eine Anpassung, egal was die Ursachen sind.

Unterscheidung CR und Bug

Unter einen solchen neutralen Begriff würde auch der CR fallen. Man hätte statt zwei also nur noch ein Artefakt. Angeblich ist die Unterscheidung aber für die Messung und Begründung der internen Wirtschaftlichkeit wichtig. Kein Wunder also, dass alles Bugs und Defekte sind ;). UserStory ist neutral genug. Man könnte trotzdem ein neutrales Artefakt Anpassung haben und für die Unterscheidung verschiedene Eigenschaften wählen. Welche Eigenschaften sollte es geben?

Was wir nicht wollen sind Schuldfragen und Verantwortlichkeit der Mehrarbeit:

  • Entwickler-Schuld
  • BA-Schuld
  • Kunde-Schuld
  • Ungewiss-wer-Schuld-ist

Besser wären verschiedene Bezeichnungen für verschiedene Dinge:

  • Technischer/semantischer Fehler (es funktioniert nicht oder falsch (Rechtschreibfehler))
  • Übersehene Anforderung (es steht auf der Story)
  • Neue Anforderung (es steht nicht auf der Story)

Oder einfach nur

  • Auf Kosten des Teams
  • Auf Kosten des Kunden

Weniger abstraktes, mehrdeutiges, unklares und vorallem weniger Schuldzuweisung, Frustration und Rechtfertigung. Softwareentwicklung betrifft das gesamte Produktteam und nur gemeinsam ist es stark.

A service bus is not for querying or heavy data

Systems get more distributed these days. One way to provision communication between all components or services of a system is with a service bus. A service bus utilizes messages and queues to get information from component/service A to component/service B. But what do we need a service bus for? And what do we need the underlying queues for?

  • Communication to integrate services? No, communication between services can be achieved more easily with less overhead and much faster by using web services (WCF, SOAP, HTTP, …).
  • Service discovery? No, service discovery would be necessary if we wouldn’t know the services of the system. And if we don’t know them, there are better and more specialized solutions available, like Jini or UPnP.
  • Reliability and failure recovery? Yes, that is the main advantage a service bus gives us. Every single message must not get lost, even if services fail, are under high pressure or are down. That is what we need queues for.

Using reliable messaging has many advantages. But it also comes with a few pitfalls. In this post I am going to address two problematic uses of a service bus.

Querying

Queries or request/response style of communication is highly ephemeral and synchronous. All queries are initially triggered by a user and the queried service could query other services. A user will wait for a response but rarely more than about 7 seconds. He or she is likely to cancel the request if it takes longer [1]. If the user gets an error, he/she will simply request again. So first of all, there is no need for a reliable query and its overhead. A query does not need to be queued until the serving endpoint gets the chance to serve it. Instead, queries have to be fast, regardless of how stressed the rest of the system is. Messaging is asynchronous. If part of the system or the service bus itself is under pressure, query-messages would reliably queue up, even if the user canceled the request. If the user requests again, he or she will introduce new messages into the service bus and therefore increase the pressure for services and the bus. So second of all, queries are getting slower in a stressed system and reciprocally slow down the system even more. In the worst case, the queried service fails or cannot respond anymore at all. Then not only will the user not get a response, but all querying services stop working as well. The queried service becomes a single point of failure for all querying services and reliability is in jeopardy. This is especially dramatic if the queried service is something central, like user management.

A better way to do this is to query a cache directly and synchronously, without messaging [2, 3, 4]. Ideally all services store and keep the data they are working with for themselves. Then they would not need to query other services for data. They would notify other services about changes in their data with events over the service bus and those services would handle these events and refresh their data [5, 6]. A cache or backend for frontend would provide a read model for synchronous queries and update itself via received events coming in as messages. In a stressed system those events will reliably queue up but will get handled eventually. That grantees fast queries and high availability but the queried data might not be up to date to the second. But requested and displayed data is never truly current since it could have been changed a second later, while the user still looks at the requested data.
Use the service bus for events (1 publisher -> N subscribers) and commands (N publishers -> 1 subscriber) but not for queries or request/response scenarios [6].

There are messaging protocols for querying, like HTTP, but they are not optimized for reliability and they don’t use queues. HTTP is just taking advantage of TCP/IPs routing fault tolerance.

Sending much data

There is something worse than querying over a service bus: querying huge amounts of data over the service bus. But that could also be attempted with event or command messages as well. Many messaging transports have size limitations for messages so the services would have to exchange lots of them, which leads to coordination overhead and transaction handling spanning multiple messages.

Big amounts of data should be queried synchronously from a cache [7]. If the big amounts of data have to be transported with events or commands, like for image uploads, the services should put the data in a common location and just send a reference [8]. Much data flowing between services indicates unfavorable service boundaries [5].
Since services should be autonomous, loosely coupled and highly cohesive, the only data that is transported between services should be small events and commands, ideally containing only IDs and references.

There are buses for sending huge amounts of data, like USB, but they are not optimized for reliability and they don’t use queues. And even USB uses messages only for short and simple commands and events. The actual data is streamed over a separate pipe in the bus.

Conclusion

Querying and sending much data over a service bus can have drastic consequences when the services or the service bus itself is under pressure. Sure, we could expensively scale for that as well but in my opinion it is just not necessary. These problems can be solved much easier if a service bus is not used like a hammer to treat every kind of communication like a nail. Use messaging when the communication is inherently asynchronous and consider sending only IDs and references. Don’t try to use messaging for synchronous ephemeral communication.
Using a service bus for every kind of communication just because it is already there, is like writing all the code in the Main() method just because it is already there.


[1] 5 Reasons Visitors Leave Your Website http://www.websitemagazine.com/content/blogs/posts/archive/2014/03/21/5-reasons-visitors-leave-your-website.aspx
[2] Chris Patterson (the man behind MassTransit): “it is best to avoid request/response use in distributed applications” http://docs.masstransit-project.com/en/latest/usage/request_response.html
[3] Udi Dahan (the man behind NServiceBus): Clarified CQRS: query caches synchronously, no messaging http://www.udidahan.com/2009/12/09/clarified-cqrs/
[4] Udi Dahan (the man behind NServiceBus): querying “should be avoided” & “messaging is not for that” https://twitter.com/halllo/status/687701659653390336
[5] Udi Dahan (the man behind NServiceBus): Finding Service Boundaries
http://udidahan.com/2015/02/02/finding-service-boundaries-illustrated-in-healthcare/
[6] Chris Patterson (the man behind MassTransit): Messages for updates and asynchronous background processing https://www.dotnetrocks.com/default.aspx?showNum=798
[7] Udi Dahan (the man behind NServiceBus): Getting lots of data over the bus? “you usually shouldn’t – instead, query a cache.” https://twitter.com/UdiDahan/status/707960622726512641
[8] Particular (the company behind NServcieBus): “Messages are intended to be small.” http://docs.particular.net/nservicebus/messaging/databus

Faster prototypes with Just Objects Prototype

If you are like me, you need to create prototypes to see new business functionality or algorithms in action. That way we can interactively test and demonstrate a solution to customers and coworkers. The downside of many prototypes is that because they look ugly and are not easily presentable, much time can be spent to overcome those shortcomings. The problem with spending much time on making a prototype look nice is that it slows you down and prevents you from doing more meaningful work instead.
I quite often fell into this trap. I used to spend too much time working on the user interface and other rather unimportant parts of a prototype. And all of that just to make a good impression showing it off. Then I had to ask myself: How can we accelerate this? How can we prototype faster, with less ceremony and get a good enough looking functional user interface automatically?
A basic search led me towards the Naked Objects Framework which seemed like a good idea. When I wanted to test it out though, it appeared to be very complicated. I needed a much simpler, straight forward, conventions based tool. So I decided to create one myself. Behold, this is Just Objects Prototype (JOP).

Installation via NuGet is very easy. Just create a new Console Application and run “Install-Package JOP” from the package manager console. JOP uses conventions to help you focus on the logic you want to prototype. To get started, adjust your Main method to look like below.

[STAThread]
static void Main(string[] args)
{
    JustObjectsPrototype.Show.With(new object[0]);
}

When you run this code, it displays the JOP shell with nothing (no objects) in it, just like in the screenshot below.

1

As you can see, there are four parts in that window. Top most is the ribbon. It lets you create and delete object instances as well as invoke custom functionality. The left part shows a list of all the different Types, this JOP prototype knows about. If one of those Types is selected, it shows all the object instances of that Type in the top list and ribbon buttons for its static methods. When one of those object instances is selected, it shows all its properties in the bottom view and ribbon buttons for its instance methods.

Example

Lets look at an example. In this prototype I want to show a simple workflow: Suing Persons. JOP wants you to not think of anything but your object model. That is your data structures and its logic. So if we focus only on what we would need to sue persons, we may come up with persons, addresses and dossiers. And this is how that could look like in C#.

class Person
{
    public string Forename { get; set; }
    public string Surname { get; set; }
    public List<string> Nicknames { get; set; }
    public List<Address> Addresses { get; set; }
    public Dossier Sue(string why)
    {
        return new Dossier { MandateMatter = why, Culprit = this }; 
    }
    public override string ToString()
    {
        return Forename + " " + Surname 
            + (Nicknames != null && Nicknames.Any() ? " (" + string.Join(", ", Nicknames) + ")" : "");
    }
} 

class Address
{
    public string AddressText { get; set; }
}

class Dossier
{
    public bool Finalized { get; private set; }
    public string Reference { get; set; }
    public string MandateMatter { get; set; }
    public Person Culprit { get; set; }
    public void Finalize()
    {
        Finalized = !Finalized;
    }
}

These are just plain old CLR objects. Lets start the prototype with a few test instances.

var objects = new List<object>
{
    new Person { Forename = "Manuel", Surname = "Naujoks" },
    new Address { AddressText = "at home" },
    new Address { AddressText = "at work" },
    new Address { AddressText = "somewhere else" },
};
JustObjectsPrototype.Show.With(objects);

As you can see, the prototype is started with a list of objects. If we had used an Array, no new object instances could have been created since JOP tries to modify that list to keep it in sync with its internal object pool.

2

And know we see our objects in action. We can modify their properties by inserting values or reference other objects from this prototypes’ object pool. We can also invoke their methods with the ribbon buttons. When the user presses the Sue button, for example, a dialog pops up to prompt for the Sue methods’ parameters. You see that dialog in the screenshot below. Notice that we see a second ribbon button for ToString. We override the ToString method so that JOP can show a readable text when displaying a person reference in a different objects’ properties view. As far as JOP is concerned, ToString could theoretically change the objects’ state and therefore lists it as well.

3

The Sue method returns a new Dossier object. After the selected “person has been sued, the newly created dossier is available” under the Dossier type.

4

The “dossier can now be finalized” which changes the Finalized property. That property is private in code and therefore read-only on the view.

Special functionality

There are many more things JOP can do. For example mass object creation and deletion with static methods. To create many new Person object instances at once, we can introduce a dedicated method that just returns the newly created instances. To delete all Person object instances, we can introduce another method that takes an ObservableCollection as a parameter. That ObservableCollection contains all the instances of the specified type that this prototype knows of and synchronizes changes to it with the prototypes’ object pool.

public static List<Person> Create_many_persons(int how_many)
{
    return Enumerable.Range(0, how_many)
        .Select(i => new Person { Surname = "Name " + i, })
        .ToList();
}
public static void Delete_all_persons(ObservableCollection<Person> allPersons)
{
    allPersons.Clear();
}

We can allow or prohibit creation and deletion of object instances with the new and delete button by specifying a UI.Settings object when starting the prototype like below.

JustObjectsPrototype.Show.With(objects, JustObjectsPrototype.UI.Settings.New(s =>
{
    s.AllowNew[typeof(Address)] = false;
    s.AllowDelete[typeof(Address)] = false;
    s.AllowDelete[typeof(Person)] = false;
}));

Conclusion

There are many things JOP can do. In this little tutorial I showed how easy it is to develop just your object model and have JOP render a view around it. There are only a few things that require knowledge of the framework, like deletion of object instances. Even though you can create comprehensive applications with JOP, keep in mind that it is primarily focused on creating prototypes. It is very opinionated and not extensible, but it will enable you to build much better prototypes much faster.

If you like my prototyping solution, check out the Just Objects Prototype GitHub repository and feel free to suggest improvements or ask my anything on twitter at @halllo.

Better WPF DataBinding with CalcBinding

If you are like me, you want to bind Boolean properties to Visibility properties. We implement IValueConverter and therefore increase the complexity in the system. The new Type has to be named and placed correctly and we have to make sure that there is no value converter that already does what we just created. How can we speed up and improve binding and value conversion?

Recently I came across the very sweet WPF library CalcBinding. It allows for custom binding expressions without the need for an IValueConverter implementation. It is a markup extension that lets us write inversions and calculations directly in XAML. Those binding expressions also support two way binding automatically. That prevents the ViewModel from getting all kinds of highly View-related properties, which can obfuscate the abstract view model. Just like the CodeBehinds did in preMVVM age.
In this blog post I give you a quick run through of all the features I find most impressive. You can easily install it with “Install-Package CalcBinding”. Once you import its namespace in the XAML you can take advantage of the new binding like below.

1

The screenshot above shows a multi binding together with arithmetic expressions to produce a single result. The screenshot below shows additional calculations that can be used inside the binding expression. Remarkably, you get the back conversion for free. Not all calculations belong to the View. Keep in mind that calculations in the view can not easily be unit tested.

2

The screenshot below shows how to bind a Boolean to Visibility. Visibility is a Type that lives in View-land and I do not want view-specific Types to be dependencies of my ViewModels. I believe the ViewModel should be as pure as possible. This way I can easily reuse them to support not only WPF views in a MvvmCross solution, for example. Unfortunately MvvmCross has its own framework specific Types like MvxCommand.

3

The screenshot below shows how to use the ternary operator (?:) within the binding expression to concatenate strings. This could be useful if the binding’s StringFormat is not enough.

4

There is one more thing I would like CalcBinding to do. If you already looked into AngularJS or compiled data binding in the Universal Windows Platform, you may like how they support binding to events. Would it not be great if we could do the same in WPF? Exactly. And here is how, utilizing the CalcBinding markup extension. Unfortunately, even though I created a pull request, this is not yet included/supported in the official version of CalcBinding.

5

CalcBinding is amazing. Especially when binding bool properties, it is a huge time saver. And on the side it keeps my ViewModels much cleaner and prevents them from turning into huge CodeBehinds. The only disadvantage I found is that while Visual Studio seems to accept the extensive binding expressions, ReSharper lists them as errors in its solution wide error analysis view. Maybe we can teach it to ignore those. For now, it has a very positive cost-benefit profile and I am going to continue using it. If you like it as well, give credit to Alex141 and star his github project at the link above.

Neuste Werkzeuge und Probleme

Kürzlich hatten wir in unserem Entwicklungsteam Schwierigkeiten nachdem einige Teammitglieder von ReSharper 9 auf ReSharper 10 aktualisiert haben. Es hat sich am Ende herausgestellt, dass die Werkzeuge gar nicht schuld waren. Dennoch hat dieser Zwischenfall eine Diskussion über die Team-interne Verwendung von Werkzeugen ausgelöst. Dabei wurde den Aktualisierten vorgeschlagen von der neuen Version wieder auf die alte zurückzugehen. Plötzlich stand das Installieren der neusten Versionen zur Debatte und es wurde von “der Team-Version” gesprochen. Das Thema haben wir auch in unserer Retrospektive diskutiert und hier wurde dann sogar von Installations-Veto und Installations-Verbot von den Softwarearchitekten gesprochen. Hiermit möchte ich meinen Standpunkt nocheinmal schriftlich klarstellen.

Es handelt sich bei diesem Thema eigentlich um zwei Themen. Das erste betrifft Probleme, die bei der Verwendung von Werkzeugen auftreten. Das zweite betrifft den Umgang mit neuen Versionen an sich. Wenn wir beides vermischen kommen wir zu vermeintlichen Lösungen die gar keine sind.

1. Thema: Tool-Probleme

Was sollten wir tun, wenn wir Probleme mit einem Werkzeug haben? Für mich ist die Antwort eindeutig: Beheben und zwar so schnell wie möglich! Ein Versions-Downgrade kann meiner Meinung nach nur das letzte Mittel sein. Wer ist dafür verantwortlich? Meiner Meinung nach die, die das problematische Werkzeug einsetzen. Und wenn das unbedingt eine bestimmte Person sein muss, dann bitte der CTO. In unserer Abteilung sehen sich die Architekten verantwortlich für den Einsatz von Entwicklungstools. Meiner Meinung nach ist das Schwachsinn. Entwicklungstools haben mit Softwarearchitektur nichts zu tun. Ich befürchte sogar, dass wir unsere Architekten mit Problemen, Fragen und Diskussionen rund um die Tools von den tatsächlichen und wichtigeren Aufgaben bezüglich der Softwarearchitektur abhalten und ablenken. Laut Wikipedia geht es bei Softwarearchitektur um

eine strukturierte oder hierarchische Anordnung der Systemkomponenten sowie Beschreibung ihrer Beziehungen

oder ähnlich

Strukturen eines Softwaresystems: Softwareteile, die Beziehungen zwischen diesen und die Eigenschaften der Softwareteile und ihrer Beziehungen.

Architekten kümmern sich nicht um die Werkzeuge der Bauarbeiter, das machen die Bauarbeiter selber.

2. Thema: Neue Versionen

Ich glaube unsere Architekten beschäftigen sich nur deswegen so viel mit Werkzeugen, weil es sonst keiner macht und sie es gerne kontrollieren wollen. Aber allein die Idee, vorzugeben welche Werkzeuge zu verwenden sind und welche nicht, finde ich höchst fragwürdig. Meiner Meinung nach widerspricht das der Selbstorganisation, dem elften Prinzip des agilen Manifests:

The best architectures, requirements, and designs emerge from self-organizing teams.

Ich meine damit nicht, welches Versionsverwaltungssystem das Team einsetzt oder welche Framework-Version der Buildserver nutzt. Diese Punkte sehe ich tatsächlich im Entscheidungsbereich der Team-übergreifenden Einheiten und den Kundenanforderungen. Aber die Version von Visual Studio und ReSharper sehe ich im Entscheidungsbereich der Teammitglieder. Schließlich kennen die ihre Werkzeuge und Konsequenzen am Besten. Das Argument für eine homogene Versionslandschaft ist Code-Kompatibilität und Pair-Programming-Vereinfachung. Beides kann ich gut verstehen und beides ist in der Realität auch mit heterogener Versionslandschaft kein Problem. Zusätzlich haben wir ja mit Versionskontrolle und CI ausreichende Sicherheitsmechanismen um selbst theoretischste Probleme auf diesem Gebiet zu verhindern.

Aber ist es sinnvoll das ein Teammitglied Visual Studio 2012 und ein anderes Visual Studio 2015 nutzt? Nein. Wo ist das Problem? Das Problem sehe ich in der alten Version. Meiner Meinung nach hat das Team ein doppeltes Ziel. Zum Einen sollten alle im Team die gleiche Version einsetzen und zum Anderen sollten alle die neuste Version einsetzen. Zu jeder Zeit? Nein, statt immediate consistency lieber eventual consistency. Es stellt sich also die Frage nach dem Zeitpunkt der Umstellung. Ich würde sagen, early adopters sofort um die neue Version im praktischen Einsatz zu evaluieren. Wenn es Probleme gibt sollten diese behoben werden (siehe Thema 1) und zwar von den early adopters. Dann sollte das restliche Team maximal zwei Sprints später ebenfalls umsteigen. Um das zu ermöglichen sollte die Verfügbarkeit einer neuen Version von den early adopters angesprochen und das Team damit über den Begin einer Evaluierungsphase informiert werden.

Warum stellen wir überhaupt um? Es geht dabei um Verbesserung und Innovation. Unter dem Strich ist die neue Version besser. Ansonst hätte es sie ja nicht geben müssen. Die neuen Versionen haben weniger Fehler und neue Features. Wenn man sich nicht mit den neusten Tools beschäftigt, kann man auch nicht wissen, wie diese das Arbeiten erleichtern und sogar beschleunigen. Zum Beispiel bietet Visual Studio 2015 mit dem Visual Live Tree und Delegates im Debug-Window zwei Funktionen auf die ich nicht mehr verzichten möchte. Und ReSharper 10 enthält Postfix Templates out of the box. Außerdem, wenn man immer am Ball bleibt ist es auch einfacher auf eine noch neuere Version umzusteigen, die besonders außergewöhnliche Features bietet. Das ist wie beim Mergen von Branches. Je länger man wartet, desto weiter laufen die Pfade auseinander und desto schwieriger ist es, diese wieder zu vereinen.

Es ist wichtig, dass wir hier alle am selben Strang ziehen und zwar nach vorne.

STP LabsDay 2015

Am Donnerstag und Freitag letzte Woche, dem 1. und 2. Oktober, habe ich am zweiten STP LabsDay teilgenommen. Die Firma für die ich arbeite veranstaltet diesen 24-Stunden-Hackathon jedes Jahr. Zusammen mit meinem Partner habe ich ‘einen’ alternativen Client für das STP KMS entwickelt, der im Browser und auf möglichst vielen Geräten läuft. Unser Ziel war es dabei nur eine Codebasis zu haben, plattformunabhängig.

Um dieses Ziel zu erreichen kamen entweder C# oder JavaScript in Frage. Mit Xamarin kriegt man C# auf Windows, Android, iOS und Mac und mit Silverlight in den Browser. Auf der anderen Seite läuft JavaScript sowieso schon im Browser und mit NW.js kriegt man JavaScript auf Windows und Mac und mit Apache Cordova auf Windows Phone, Android und iOS. Ich habe mich für JavaScript entschieden, da Silverlight mittlerweile uncool ist und das Silverlight-Plugin eh nicht mehr im Chrome läuft. Außerdem sehe ich C# jeden Tag und JavaScript nicht.

Was das Backend betrifft, konnten wir die externe Schnittstelle von STP KMS nutzen, sodass wir uns voll und ganz auf Client-Entwicklung konzentrieren konnten. Unser erster Prototyp lief nach ca. 7 Stunden dank NW.js und Apache Cordova auf allen uns zur Verfügung stehenden Platformen: Wir hatten Windows, Mac, Windows Phone, Android, iPhone und iPad dabei. Programmiert haben wir bis dahin wenig, die meiste Zeit ging für die Administration der Geräte und Deployment-Probleme drauf. Aber in diesem Prototyp hatten wir die Logik unter der Oberfläche mit AngularJS vollständig umgesetzt und uns um das Design überhaupt nicht gekümmert. Es lief dann zwar einwandfrei aber sah echt nichts aus. Also haben wir die restliche Zeit in UI-Design investiert und mit jQuery Mobile für Smartphones optimiert.

Wir hatten nach 24 Stunden eine harte Deadline. Aber das hat uns gereicht. Wir hatten sogar Zeit für Essen, Schlafen und Fitnessstudio. Dank Apache Cordova können wir unseren Client auch für BlackBerry, FirePhone, Tizen und alle anderen Geräte erzeugen, die wir heute noch gar nicht kennen.

Bei der Abschlusspräsentation des STP LabsDay haben wir dann die identische App auf Windows, Mac, Windows Phone, Android, iPhone und iPad gezeigt. Und das kam richtig gut an. Für unser Projekt “cross platform KMS-Aktensicht” haben wir anschließend zwei Awards gewonnen: Den “roadmapper”-Award (Kundenpreis) und den “leider geil”-Award (Zuschauerpreis). Ersteren hat ein echter Kunde der STP höchstpersönlich verliehen und für Letzteren haben alle Zuschauer der Ergebnispräsentation anonym abgestimmt. Den Vorstands-Award haben wir leider nicht mehr gewonnen, der ging an ein anderes Projekt. Dennoch haben wir mit modernen Web-Technologien in kurzer Zeit und ohne Vorwissen richtig viel erreicht und viele beeindrucken können. Und wir haben NW.js und Apache Cordova kennengelernt. Cross platform for the win!

WP_20151001_001
DSC_0105
DSC_0145

NDC Oslo 2015

I want to share a little about my first ever trip to Norway. Today I got back from Oslo, where I visited the NDC 2015 conference. Amazing conference, see some of the photos I took below. Everything else was a little too stressful.

It took me 6.5 hours to get from Karlsruhe to the hotel in Oslo. There I had to pay for the hotel room with my credit card because the hotel was not capable of dealing with the HRS booking my company did in advance. I did not sleep well because it doesn’t get dark in the nights. 11pm (first photo) in Oslo looks like 8pm in Karlsruhe and 3am looks like 9pm. It took me 7.5 hours to get from the hotel back to Karlsruhe.

I was at NDC on June 17th and 18th and those were two great days. The sessions of Ian Cooper and Udi Dahan inspired me the most. Now I need to digest and structure all the notes I took. Best conference I ever went to, thank you NDC! Hopefully I get to go again next year, different hotel maybe.

WP_20150616_001WP_20150617_002WP_20150617_010WP_20150618_001WP_20150618_004 WP_20150618_003 WP_20150618_002WP_20150617_007 WP_20150617_016WP_20150618_007WP_20150618_005 WP_20150617_014 WP_20150617_011WP_20150618_008 WP_20150618_010

“Ich will keine Leben retten”

Vor kurzem habe ich den Satz gehört: “Ich studiere Medizin, damit ich Leben retten kann.” Das hat mich zum Nachdenken gebracht. Studiere ich nicht Medizin, weil ich keine Leben retten will? Eigentlich ist Leben retten ja eine gute Sache, also warum tue ich nicht alles mögliche, um Leben retten zu können? Medizin studieren zum Beispiel. Und wieso steht in meinen Gedanken jetzt über meinem Leben die Überschrift “Ich will keine Leben retten”?

Zunächst einmal retten nicht nur Mediziner Leben. Leben werden auch von Hilfsorganisationen in Krisengebieten und sogar von Soldaten im Krieg gerettet. Es geht nicht nur um Leben retten. Es geht auch um Leben schützen, Leben unterstützen und Leben verschönern. Außerdem bedeutet der Begriff “Leben” mehr als nur körperliche Gesundheit.

Meiner Meinung nach geht es eigentlich darum, einen Beitrag zur Gesellschaft zu leisten. Einen Beitrag zur Gemeinschaft der Menschen. Nach Karlfried Graf Dürckheim hat der Mensch einen doppelten Auftrag.

  1. die Welt gestalten in Werk

  2. reifen auf dem inneren Weg

Die Gestaltung der Welt für die Gemeinschaft der Menschen wird dazu führen, das “Leben” gerettet, geschützt, unterstützt und verschönert werden können. Vielleicht nicht direkt von mir, aber dann indirekt über die nächste oder übernächste Instanz in der Wertschöpfungskette. Zum Beispiel rettet der Hersteller von Seife keine Leben, aber der Arzt, der sich damit die Hände wäscht. Die Antwort auf die oben gestellten Fragen sehe ich in diesem doppelten Auftrag.

Was denken Sie?