Menschenbilder

In letzter Zeit habe ich mich mit sozialen Modellen beschäftigt. Zum Beispiel damit, wie wir andere Menschen sehen. Beim Smalltalk mit Kollegen wird bald deutlich, dass einige ein sehr positives, humanistisches Bild der Menschen haben. Andere hingegen sehen eher das Negative in anderen Kollegen (von Freunden und Familie haben sie dann aber wieder eher ein positives Bild).
Hier eine Zusammenfassung der Symptome:

  • Positives Bild der Kollegen
    • Menschen zeigen Eigeninitiative
    • Wertschätzung der Sichtweisen und Ideen von anderen
  • Negatives Bild der Kollegen
    • Kollegen sind faul, müssen zur Arbeit gezwungen werden
    • Menschen haben „kriminelle Energie“, um sinnvolle Regeln zu umgehen

Jeder hat also zwei Modelle, in die die Menschen passen. Ein Modell ist das dominante, in das die meisten Kollegen zu passen scheinen.
Sich selbst sehen die Menschen aber immer positiv.
Diese Modelle in den Köpfen sind etwas anderes als Vorurteile, denn es können immer Situationen benannt werden, in denen sich die „Natur“ des Kollegen gezeigt hat. Das Modell als „Abbild eines Ausschnitts der Wirklichkeit“ ist dabei in sich schlüssig und widerspruchsfrei.

Die Antwort auf die Frage, welches Menschenbild den Kollegen wirklich beschreibt, hat Douglas McGregor 1960 gegeben: Kontextabhängig kann es durchaus sein, dass wir, von außen betrachtet, dem negativen Modell entsprechen. Von unserer Natur her entsprechen wir dem positiven Bild.

Ein Argument für die, die das bezweifeln: Als Kind musste keiner gezwungen werden, das Sprechen zu lernen.

Reihenfolge von Nachrichten in Sequenzdiagrammen

Ein Sequenzdiagramm beinhaltet Lesenslinien von Objekten und Nachrichten, die zwischen den Objekten ausgetauscht werden. Dabei gilt das Kausalitätsprinzip: Eine Nachricht kann erst empfangen werden nachdem sie gesendet wurde. Davon abgesehen ist die Reihenfolge von Nachrichten nur pro Lebenslinie definiert; bei mehreren aktiven Objekten (oder bereits mit der Verwendung von asynchronen Nachrichten) legt ein Sequenzdiagramm weniger fest als intuitiv erwartet wird. Weiterhin kann zwischen dem Senden einer Nachricht und deren Empfang Zeit vergehen. Das ein Sequenzdiagramm die Reihenfolge nicht strikt festlegt ist ein Feature. Denn ansonsten müssten für die verschiedenen Möglichkeiten der Nachrichten-Reihenfolgen mehrere Sequenzdiagramme angelegt werden.

Sequenzdiagramm ohne Reihenfolge

Sequenzdiagramm ohne Reihenfolge

In diesem Beispiel ist nicht definiert, ob getMetaData() vor getNumberOfPlans() aufgerufen wird.
Um genau das zu definieren, also eine Reihenfolge zwischen Nachrichten lebenslinienübergreifend festzulegen, bietet UML das Konstrukt „GeneralOrdering“.
Das folgende Bild zeigt die Verwendung von GeneralOrdering (zugegeben, das Beispiel ist fachlich unglücklich).

Sequenzdiagramm mit Reihenfolge über GeneralOrdering

Sequenzdiagramm mit Reihenfolge über GeneralOrdering

Die Aussage des Diagramms: Der Empfang von getMetaData findet vor dem Empfang von getNumberOfPlans statt, über die Reihenfolge des Versands dieser Nachrichten wird keine Festlegung getroffen.
Für die Verwendung von GeneralOrdering gibt es zwei Gegenanzeichen:

  1. die Frage, ob die Zielgruppe das Diagramm noch versteht
  2. wird GeneralOrdering nicht von allen UML-Tools komfortabel unterstützt

Davon abgesehen bieten Sequenzdiagramme mit GeneralOrdering eine mächtige Möglichkeit, Szenarien zu definieren. Ein Sequenzdiagramm steht für eine Menge von Nachrichtenreihenfolgen, und mit GeneraOrdering kann zwischen einigen dieser Nachrichten eine Art „Precondition“ definiert werden.

Modell eines Staubsaugers

Im Haushalt benutzen wir täglich viele Geräte. Ein Ideenwettbewerb von Kärcher ermuntert Studenten, ein neuartiges Gerät zu entwickeln. Das hat mich dazu gebracht, über Modelle eines Staubsaugers nachzudenken.

Mit bekannte Modelle sind der klassische Staubsauger, der Zentralstaubsauger und der Saugroboter. Das abstrakte Prinzip hinter diesen Maschinen: Staub wird von der Oberfläche gelöst (mit feststehenden Bürsten, rotierenden Bürsten oder durch Saugkraft) und in eine Staubsenke transportiert. Das Teil, das den Staub von der Oberfläche löst, ist bei allen Geräten mobil. Ein Transportteil (ein Schlauch oder ähnliches) verbindet jenen Teil mit der Staubsenke, welche manchmal mobil, manchmal stationär (z.B. beim Zentralstaubsauger) ist.

Natürlich kann das abstrakte Prinzip als Klassendiagramm in UML modelliert werden:

Modell eines Staubsaugers

Modell eines Staubsaugers

Zu den Multiplizitäten: Bei einem Zentralstaubsauger kann es gleichzeitig mehrere Oberflächenreiniger geben. Es kann mehrere Staubsenken geben, z.B. bei einem Saugroboter, der den Staub zwischenspeichert und später in eine Station entlädt.

Der Transportteil ist Definitionssache: Besitzt ein Saugroboter, bei dem der Staub von der Bürste direkt in einen Raum gerät, dessen hinterer Teil die Staubsenke darstellt, einen Transportteil? Auf jeden Fall verbindet ein Transportteil genau einen Oberflächenreiniger mit einer (oder mehreren?) Staubsenke.
Weiterhin ist der Oberflächenreiniger mobil, er wird entweder per Hand oder automatisch über die Oberfläche bewegt.

Erweitertes Modell eines Staubsaugers

Erweitertes Modell eines Staubsaugers

Dieses Modell stellt das Prinzip jedes mir bekannten Staubsaugers dar. Inkrementelle Verbessungen der Geräte folgen ebenfalls diesem Modell. Ein komplett neuartiger Staubsauger wird aber einige Einschränkungen des Modells verletzen. Das Modell hilft also, neuartige Prinzipien anzudenken:

  • Muss der Oberflächenreiniger mobil sein, oder könnte er auch stationär sein?
  • Sind weitere Antriebsformen möglich?
  • Ist eine Staubsenke immer nötig? Bieten mehrere Staubsenken einen Vorteil?

Namensgebung

Namensgebung, Nomenklatur oder auch „Benamsung“ genannt, ist täglicher Teil der Arbeit in der Softwarebranche. Die Wichtigkeit eines sinnvollen Namens, unter dem alle Beteiligten dasselbe verstehen, wird oft in Büchern über Patterns betont. Uncle Bob hat in seinem Buch „Clean Code“ sogar ein ganzes Kapitel über „Meaningful Names“ geschrieben. Und trotzdem fällt in Abstimmungen von Schnittstellen oft der Satz: „Über den Namen können wir uns noch später einigen“.

Ein Beispiel, warum genaues Nachdenken über Namen wichtig ist:
Für eine Konsumentenbefragung wird ein Fragebogen modelliert, der mehrere Fragen mit Multiple-Choice Antworten enthält.

Homonym im Modell

Homonym im Modell

Soll neben dem Fragebogen auch das Befragungsergebnis des Konsumenten gespeichert werden, so besteht der ausgefüllte Fragebogen aus den gegebenen Antworten. Die hier zu modellierende Antwortklasse ist allerdings etwas anderes als die in dem Beispieldiagramm:
Ein Fragebogen enthält Fragen, die mehrere Antwortmöglichkeiten haben. Ein ausgefüllter Fragebogen besteht aus gegebenen Antworten.

Wörter, die mehrere Bedeutungen haben („Antwort“ im Beispiel), heißen Homonyme. Beim Modellieren ist peinlichst genau darauf zu achten, dass die einzelnen Bedeutungen durch sinnvolle Namensgebung deutlich gemacht werden.

Vererbung von Komponenten am Beispiel von EJBs

Im Laufe der Zeit wurde der Begriff einer Komponente in UML immer weiter geschärft. Die aktuelle Spezifikation definiert eine Komponente folgendermaßen:
„A component represents a modular part of a system that encapsulates its contents and whose manifestation is replaceable within its environment. A component defines its behavior in terms of provided and required interfaces.“
Mit eigenen Worten: Eine Komponente wird über ihre Interfaces verwendet und ist dadurch austauschbar. Das Metamodell sieht folgendermaßen aus:

vererbung_Komponenten

In der EJB-Welt lassen sich Komponenten mit Session Beans abbilden. Diese können mehrere Interfaces exportieren und die Implementierung dahinter kann ausgetauscht werden.
In der EJB-3.1 Spezifikation steht folgendes über Superklassen von Session Beans:
„A session bean class is permitted to have superclasses that are themselves session bean classes. …the use of session bean classes as superclasses merely represents a convenient use of implementation inheritance, but does not have component inheritance semantics“.
Das bedeutet, dass es keine Komponenten-Vererbung bei Session Beans gibt.
Deutlich wird das z.B. bei den exportierten Interfaces: Die Superklasse S implementiert das Interface A, deren Subklasse K implementiert das Interface B. Bei echter Komponentenvererbung ist die Erwartung, dass die Subklasse (Subkomponente) K beide Interfaces (A und B) exportiert. Da es an dieser Stelle aber keine Komponentenvererbung gibt, exportiert K lediglich das Interface B.

UML ist nicht auf Java/JEE zugeschnitten. Dadurch, dass UML bei der Vererbung von Komponenten mächtiger ist als Session Beans, erfüllt UML ihren Anspruch, eine allgemeingültige Modellierungssprache zu sein. Das bedeutet andererseits aber auch, dass UML-Modelle nicht immer eins zu eins in einer anderen Sprache umgesetzt werden können.

What is a classifier?

„A classifier is a namespace and a type, and it can be generalized“ [UML spec].
Many different classes of the UML metamodel are subclasses of „Classifier“. It is important to know what a classifier is and thus to get a feeling of why some Metaclass is a „Classifier“.

Hierarchy of Classifier
Classes that are classifiers (the annex of the UML Superstructure contains a full taxonomy):

  • Class
  • Interface
  • Association
  • Component
  • DataType
  • Collaboration
  • UseCase

Classes that are not a classifier:

  • Comment
  • Parameter
  • Dependency
  • Generalization
  • Package

While „Package“ itself is a Namespace, it is not a Type, and thus is not a Classifier. Association was a surprise for me, because it feels like it shouldn’t be a Classifier. But thinking about it, an association can be generalized, and there is the concept of the „association class“. An association class „will be both an association, connecting a set of classifiers and a class, and as such have features and be included in other associations“ [UML Superstructure].

So all in all, the three criteria given (be a namespace, be a type, be generalizable) combined with some gut feeling allow us to guess what is a classifier and what is not.

All sciences are based on the concept of classification, for example taxonomy in biology. Object are assigned to different classes, which in turn often form a hierarchy (although there are classifications that are not based on hierarchies).
UML is based on a hierarchic classification. Or, to put it in the words of the spec: „A classifier is a classification of instances, it describes a set of instances that have features in common“.

Unternehmensformen / Organisation

Hierarchiegeführte Unternehmen haben es schwer, Komplexität zu bewältigen. Dazu gibt es interessante Bücher und Vorträge, z.B. von Niels Pfläging.

Leider haben die wenigsten Gelegenheit, moderne „Beta-Organisationen“ (Begriff von Niels) kennenzulernen, da viele Unternehmen noch hierarchiebehaftet oder eine gemischte Form sind. Hier eine Skizze eines hierarchiegeführten Unternehmens:

Hierarchie

Die Software-Entwicklung oder zumindest Teile dieser Abteilung setzt sich heutzutage oft aus Scrum-Teams zusammen, die allerdings durch die übrigen Hierarchien keinen direkten Kundenkontakt haben. An die übrige Organisation sind diese Teams meist nur über die Person angebunden.

gemischte Unternehmen

Schließlich gibt es Organisationen, die ausschließlich in Teams organisiert sind:

Teams

Und hier ein agiles Unternehmen mit seinen Kunden. Teams, die Kundenkontakt haben, wirken direkt an der Wertschöpfung mit. Teams ohne Kundenkontakt liegen im Inneren der Organisation und werden bei Bedarf von den äußeren Teams in Anspruch genommen.

Kundenkontakt

EJB: How to start a new transaction for a call on this()

Sometimes it is necessary to start a new transaction in a stateless sessionbean with container managed transactions (CMT). For that, usually a new SLSB is created and given the transactionattribute REQUIRES_NEW. Unknown to many is the fact that from a SLSB, methods on this() can be called that also start a new transaction.
The reason why this doesn’t work out-of-the-box is that a call on this() is a POJO-call and thus the container is unaware of the call and has no chance to handle transactions. So the solution is to make the container aware of the call by obtaining a reference to this() through the SessionContext.
Here is an example for it:

@javax.ejb.Stateless
@javax.ejb.Local(SomeInterface.class)
public class SomeInterfaceImpl implements SomeInterface {
    @javax.annotation.Resource
    private SessionContext sessionContext;

    @Override //has the TX-Attribute REQUIRED
    public List<String> doSomething(){
        sessionContext.getBusinessObject(SomeInterface.class).doInNewTx();
        throw new RuntimeException(); //Abort the Transaction
    }

    @Override
    @javax.ejb.TransactionAttribute(REQUIRES_NEW)
    public void doInNewTx(){
        /* persist something with the EntityManager, it will be persisted
           although the caller rolls back its Tx, cause this method runs
           in its own transaction */
    }
}

To try this out, create SomeInterfaceImpl and SomeInterface, and call doSomething() via an EJB-call. It will internally call doInNewTx() in a new transaction and then abort the current transaction by throwing a RuntimeException. Everything persisted in doInNewTx() will be written to the database, as it uses a new transaction that is committed independently.

OCUP part 6: protocol state machines

In addition to the behavioral state machines described in the previous article (that model the behavior of individual entities), there are also „protocol state machines“, which express the valid transitions that can be triggered on a classifier instance.
This type of state machine is widely used in framework documentation to describe the permitted order in which operations of a class can be invoked. A good example for that is the hibernate persistence lifecycle.

A protocol state machine has the keyword „{protocol}“ in its diagram header to be distinguished from behavioral state machines.