<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
  <title>Blog</title>
  <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/rss" />
  <subtitle>Blog</subtitle>
  <entry>
    <title>Inversion of Control</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/inversion-of-control-1" />
    <author>
      <name>Mihail Tsvyatkov</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/inversion-of-control-1</id>
    <updated>2012-04-17T11:42:00Z</updated>
    <published>2012-04-17T11:42:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	Vergleichbar mit der Konstruktion eines Wolkenkratzers, müssen bei der Erstellung einer Software Architektur-Richtlinien definiert und berücksichtigt werden. Wird dies nicht befolgt, stürzt die Konstruktion über kurz oder lang ein.&lt;br /&gt;
	Inversion of Control gibt dem Entwickler ein effektives Tool an die Hand, um Software auf Klassenebene so solide zu bauen, dass auch bei größeren Umbaumaßnahmen oder langjähriger Weiterentwicklung die Architekturaspekte Erweiterbarkeit, Wiederverwendbarkeit, Testbarkeit nicht in Mitleidenschaft geraten.&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=61f5c0d9-fc45-4c62-95c9-4371170ba3b2&amp;amp;groupId=10458&amp;amp;t=1334695861345" style="width: 300px; height: 201px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Große Softwaresysteme bestehen üblicherweise aus mehreren Modulen mit unterschiedlichen Aufgaben. Typischerweise sind solche Module ineinander verschachtelt und hängen voneinander ab. Auch die Klassen in einem Modul sind von anderen Klassen unterschiedlich stark abhängig. Aus der dadurch entstehenden starken Verwobenheit von Klassen resultiert oft die Notwendigkeit bei&amp;nbsp; Änderungen in einer Klasse, deren abhängige Klassen auch anpassen zu müssen. Das macht ein großes System schwierig erweiter- und wartbar - und verursacht letztendlich höhere Kosten.&lt;br /&gt;
	&lt;br /&gt;
	Um dieses Problem zu vermeiden und eine höhere Software-Qualität zu erreichen, werden Klassen und Module so gebaut, dass eine möglichst lose Kopplung zwischen den unterschiedlichen Komponenten vorherrscht. Dadurch wird vermieden, Klassen anpassen zu müssen, die nicht angefasst werden wollten.&lt;br /&gt;
	&lt;br /&gt;
	Wie kann man also eine losere Kopplung erreichen? Genau hier kommt das Prinzip „Inversion of Control“ zu Hilfe.&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Beispiel-Szenario&lt;/h3&gt;
&lt;p&gt;
	Um das Problem genauer zu betrachten, wird im Folgenden ein einfaches Beispiel-Szenario vorgestellt, für das zwei Implementierungsansätze in Java vorgestellt werden.&lt;/p&gt;
&lt;h4&gt;
	Anforderungen&lt;/h4&gt;
&lt;ul&gt;
	&lt;li&gt;
		Dokumente sollen durchsuchbar sein&lt;/li&gt;
	&lt;li&gt;
		Die FAST-Suchmaschine soll verwendet werden&lt;/li&gt;
	&lt;li&gt;
		evtl. soll dieses Jahr auf eine andere Suchmaschine geschwenkt werden&lt;/li&gt;
	&lt;li&gt;
		Zur Qualitätssicherung sollen Unit-Tests geschrieben werden&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Man könnte die Umsetzung der Anforderungen in zwei Module aufgeteilt umsetzen. Ein Modul, das die Implementierungen der verschiedenen Suchanbieter zur Verfügung stellt (SearchProvider) und ein zweites Modul (SearchService), das den Suchservice implementiert und das einen der implementierten Suchanbietern benutzt und damit von dem SearchProvider abhängig ist.&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=bfbed764-6924-4e0d-ad93-8ea752295727&amp;amp;groupId=10458&amp;amp;t=1334695903924" style="width: 500px; height: 134px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Implementierungsansatz 1 (enge Kopplung - so besser nicht)&lt;/h3&gt;
&lt;p&gt;
	Beim ersten Ansatz werden die Anforderungen mit enger Kopplung zwischen den beiden Modulen umgesetzt. Die folgenden Code-Ausschnitte skizzieren die&amp;nbsp; Implementierungen in den beiden Modulen:&lt;/p&gt;
&lt;h4&gt;
	SearchProvider&lt;/h4&gt;
&lt;h4&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=80487bc1-2c26-4783-a896-916361531281&amp;amp;groupId=10458&amp;amp;t=1334695861315" style="width: 350px; height: 112px;" /&gt;&lt;/h4&gt;
&lt;h4&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=20689917-4e7e-4090-889e-9a6cb9b121ac&amp;amp;groupId=10458&amp;amp;t=1334695861326" style="width: 450px; height: 201px;" /&gt;&lt;/h4&gt;
&lt;h4&gt;
	SearchService&lt;/h4&gt;
&lt;p&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=159dc500-3014-4e6d-a611-9a7cde9b0463&amp;amp;groupId=10458&amp;amp;t=1334695861338" style="width: 450px; height: 228px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Der SuchService hängt&amp;nbsp; direkt von dem FAST-SearchProvider ab,&amp;nbsp; die Erstellung des SearchProviders wird also direkt im SearchService durchgeführt. Genau dadurch entsteht eine enge Kopplung zwischen diesen Modulen.&lt;br /&gt;
	&lt;br /&gt;
	Die direkte Abhängigkeit führt dazu, dass bei einem späteren Austausch des SearchProviders auch des SearchService-Modul angepasst werden muss. An diesem Beispiel sieht die Anpassung in den beiden Modulen ziemlich einfach aus, aber bei einem komplexeren System könnte dies zu zusätzlichen Aufwänden führen wie z.B. Deployment von mehreren Komponenten oder Durchführung von mehreren Tests, was weitere Risiken und Aufwände mitbringen könnte.&lt;br /&gt;
	&lt;br /&gt;
	Unit-Tests zum Suchservice:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=4550a5f7-7dc7-4987-b1de-dc6ab8ffa123&amp;amp;groupId=10458&amp;amp;t=1334695861349" style="width: 406px; height: 171px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Ein anderes Problem taucht auf, wenn man die implementierte Funktionalität testen möchte. Bei einem Unittest ist das Ziel nur eine Unit automatisiert zu testen. An dem Code-Beispiel ist die Unit der SearchService. Um den SearcService als Unit zu testen, sollte der SearchProvider durch einen MockSearchProvider ersetzt werden. Dies ist über Anpassungen der SearchProviders möglich. Wird das nicht gemacht, schlägt der Unit-Test auf die Suchmaschine durch und wird zu einem Integrationstest bei dem der Suchserver erreichbar sein muss.&lt;br /&gt;
	&lt;br /&gt;
	Was ist aber die wirkliche Ursache für die angedeuteten Probleme?&lt;br /&gt;
	&lt;br /&gt;
	Die Ursache ist eigentlich die direkte Abhängigkeit des SearchService von dem FAST-SearchProvider.&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=f327900d-da4b-4878-b0a9-737a769c48f7&amp;amp;groupId=10458&amp;amp;t=1334695861322" style="width: 400px; height: 119px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Wer den Code genauer anschaut, erkennt, dass diese direkte Abhängigkeit nicht zwingend notwendig ist. Die Variable, die auf die SearchProvider-Implementierung referenziert, wird eigentlich als eine Instanz von dem SearchProvider-Interface deklariert, d.h. als eine Abstraktion von dem SearchProvider. In dem restlichen Codeabschnitt, wo diese Variable verwendet wird, werden Funktionalitäten genau aus der Definition der Abstraktion aufgerufen. Das heißt, dass der FAST-SearchProvider dort überhaupt nicht bekannt ist oder sein sollte und eigentlich nur bei der Initialisierung der Variable referenziert wird.&lt;br /&gt;
	&lt;br /&gt;
	Wenn die Initialisierung der Variable außerhalb des SearchServices stattfinden könnte, würde er nicht mehr von der konkreten Implementierung - dem FAST-SearchProvider -&amp;nbsp; abhängen, sondern nur von der definierten Abstraktion.&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=b3208fd7-0984-47eb-b520-9067689e2371&amp;amp;groupId=10458&amp;amp;t=1334695861334" style="width: 400px; height: 85px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Eine solche Lösung würde den Austausch von dem SearchProvider vereinfachen, da in diesem Fall der SearchService nicht angepasst werden muss. Die Einbindung des MockServices im Unittest wäre dann einfach.&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Implementierung 2 (losere Kopplung - so ist besser)&lt;/h3&gt;
&lt;p&gt;
	Der folgende Implementierungsansatz zeigt, wie man die Anbindung von dem SearchService zu einem konkreten SearchProvider außerhalb von dem SearchService auslagern könnte. &amp;nbsp;Dabei kommt das Inversion of Control Framework &lt;em&gt;Google Guice&lt;/em&gt; zur Hilfe.&lt;/p&gt;
&lt;p&gt;
	Mit &lt;em&gt;Guice&lt;/em&gt; sieht die Implementierung des SearchServices so aus:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=92d5e1c1-4ef1-44f6-aaaf-115d9a409213&amp;amp;groupId=10458&amp;amp;t=1334695861319" style="height: 286px; width: 400px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Die Annotation @Inject gibt dem Framework den Hinweis, dass hier ein SearchProvider angebunden (injected) werden sollte. Die Anbindungsdefinition geschieht dann außerhalb von dem SearchService in einer separaten Klasse, z.B. für den MockSearchProvider wie folgt:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=8e69462c-4403-40c7-9ebd-63efb2f9a0bb&amp;amp;groupId=10458&amp;amp;t=1334695861330" style="width: 450px; height: 121px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Man kann im Code die Anbindungskonfiguration verwenden, um den entsprechenden Service zu benutzen, z.B. um in den Unittests für den SearchService den MockSearchProvider statt den echten SearchProvider anzuwenden:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="../../../image/image_gallery?uuid=8446f1e3-8544-4473-8f13-7695afe4b144&amp;amp;groupId=10458&amp;amp;t=1334695861342" style="width: 500px; height: 172px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Bei diesem Ansatz wurde die Kontrolle der Erzeugung von dem konkreten SearchProvider von dem SearchService an das Framework übergeben („Inversion of Control“). Damit könnte man dann Anbindungen umdefinieren oder austauschen und dies, ohne den SearchService anpassen zu müssen. Dadurch wird die lose Kopplung zwischen dem SearchService-Modul und dem SearchProvider-Modul erreicht.&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Fazit - was bringt Inversion of Control?&lt;/h3&gt;
&lt;p&gt;
	Trennung zwischen Nutzung und Erzeugung von Objekten&lt;br /&gt;
	&lt;br /&gt;
	&lt;strong&gt;- &amp;gt; losere Kopplung&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Einfache Austauschbarkeit&lt;/li&gt;
	&lt;li&gt;
		Fokus auf das Design&lt;/li&gt;
	&lt;li&gt;
		Sicht nur auf gebrauchte Funktionalität&lt;/li&gt;
	&lt;li&gt;
		Schneller und leichter Austausch von Komponenten&lt;/li&gt;
	&lt;li&gt;
		Weniger Nebeneffekte&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	&lt;strong&gt;-&amp;gt; bessere Testbarkeit&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Verwendung von Mocks&lt;/li&gt;
	&lt;li&gt;
		Schwerpunkt auf das Testen von dem Klassenverhalten&lt;/li&gt;
	&lt;li&gt;
		Keine Tests von Abhängigkeiten&lt;/li&gt;
	&lt;li&gt;
		Keine Nebeneffekte&lt;br /&gt;
		 &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
	Herausforderungen&lt;/h3&gt;
&lt;p&gt;
	Bei der Betrachtung von Klassen die Guice nutzen, wird die Zuordnung zu den verwendeten Implementierungen undurchsichtiger. Hier muss dann in das entsprechende Modul geschaut werden, in dem den Interfaces die konkrete Implementierung zugeordnet ist. Dies erschwert z.B. die Fehleranalyse, wenn Konzept und Framework nicht verstanden wurden.&lt;/p&gt;
&lt;h3&gt;
	Hmm..why should I care?&lt;/h3&gt;
&lt;p&gt;
	Bei der Konstruktion von Gebäuden ist die Einhaltung von Architekturvorgaben unverzichtbar. Genauso selbstverständlich sollten sich Softwareentwickler Prinzipien wie „Inversion of Control“ aneignen, um die Qualität der Software signifikant zu steigern. Eine losere Kopplung und eine bessere Testbarkeit dient nicht dem Selbstzweck, sondern führt zu einer verständlicheren, leichter erweiterbar und automatisiert testbarenr Software. Refactorings lassen sich dadurch kontrollierter durchführen. Dies resultiert in Systemen an denen länger Entwickelt nicht nur in einer Kostenersparnis, sondern erhöht die Kundenzufriedenheit signifikant.&lt;br /&gt;
	 &lt;/p&gt;
&lt;p&gt;
	Autoren: Robert Süggel u. Mihail Tsvyatkov&lt;/p&gt;</summary>
    <dc:creator>Mihail Tsvyatkov</dc:creator>
    <dc:date>2012-04-17T11:42:00Z</dc:date>
  </entry>
  <entry>
    <title>Automatisierte Tests über Weboberflächen</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/automatisierte-tests-uber-weboberflachen" />
    <author>
      <name>Wieslaw Nawrocki</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/automatisierte-tests-uber-weboberflachen</id>
    <updated>2012-03-19T09:21:00Z</updated>
    <published>2012-03-19T09:21:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	Fast jeder kennt das Problem. Man implementiert neue Funktionalität, führt eventuell noch paar Code-Optimierungen durch und lässt anschließend Unit-Tests laufen. Obwohl alle Tests erfolgreich sind, ist man trotzdem nicht immer sicher, ob eigene Änderungen keine Seiteneffekte verursacht haben, die erst beim manuellen Testen der Applikation über die Oberfläche ersichtlich werden. Ganz schlimm wird es, wenn diese Fehler ganz übersehen werden. Meistens ist es nicht der Fall. Doch wer sicher sein will, sollte sich über Testautomatisierung der Benutzeroberflächen (GUI-Testing) Gedanken machen.&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Wozu GUI-Tests?&lt;/h3&gt;
&lt;p&gt;
	Unit-Tests alleine sind im Bereich der Softwarequalität nicht ausreichend, da bei dieser Art des Tests die Software nur aus der Codeperspektive betrachtet und getestet wird (s.g. White-Box Tests). Dabei wird eine zentrale Sicht auf das Produkt nicht ausreichend berücksichtigt – die Anwendersicht. Der Anwender verwendet die Applikation grundsätzlich anders als Unit-Test. Für diesen ist die Anwendung eine Black Box, die über die Oberfläche bedient wird. In Folge dessen, wird er mit anderen Problemen und Fehlern konfrontiert. Besonders bei Webapplikationen entstehen zusätzlich Probleme durch unterschiedliche Browsertypen und Betriebssystemen.&lt;br /&gt;
	&lt;br /&gt;
	Aus diesem Grund werden GUI-Tests in Softwareprojekten durchgeführt. Manuelle Testdurchführung über Oberflächen ist meist sehr aufwändig, zeitintensiv und teuer. Besonders bei Regressionstests, bei denen immer wieder die gleichen Testszenarien durchgeführt werden, um die Grundfunktionalität der Software zu gewährleisten.&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Automatisierte&amp;nbsp; GUI-Tests?&lt;/h3&gt;
&lt;p&gt;
	Die Notwendigkeit der Automatisierung von Testabläufen steht in den meisten Softwareprojekten außer Frage. Nicht nur der Buildprozess und die Unit-Tests Läufe, sondern auch GUI-Tests lassen sich inzwischen sehr zuverlässig und stabil automatisieren.&lt;br /&gt;
	&lt;br /&gt;
	Testautomatisierung über die Benutzeroberflächen kann weitgehend die Unit-Test ergänzen und auch dazu beitragen, dass die Qualitätsprobleme und Seiteneffekte so früh wie möglich erkannt werden. Dadurch können eine bessere Produktqualität erreicht, die Entwicklungs-, Fehlerlokalisierungszeiten verkürzt und somit die Kosten reduziert werden. Insbesondere bei Regressionstests.&lt;br /&gt;
	&lt;br /&gt;
	Die Erstellung und Wartung von automatisierten GUI-Tests ist natürlich auch mit Aufwand verbunden und steht somit nicht immer im Verhältnis zwischen Kosten und Nutzen. Wenn man sich für die Testautomatisierung entscheidet, sollte folgendes beachtet werden:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Man sollte nicht versuchen, alles zu automatisieren. Testerstellung, Wartung und Durchführung müssen im Verhältnis zu den manuellen Tests stehen.&lt;/li&gt;
	&lt;li&gt;
		Wenn eine Funktion mit Unit-Test getestet werden kann, dann wird mit Unit-Test getestet und nicht über die Oberfläche. „Don’t write Front-End Tests“ [2].&lt;/li&gt;
	&lt;li&gt;
		Bei der Testerstellung muss auf Wartbarkeit und Wiederverwendbarkeit geachtet werden.&lt;br /&gt;
		 &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
	Automatisierte&amp;nbsp; GUI-Tests bei der it-economics GmbH&lt;/h3&gt;
&lt;p&gt;
	Eines der wichtigsten Themen in unserer Firma ist die Qualität der Software. Da die automatisierten GUI-Tests die Unit-Test hervorragend ergänzen und somit zur Erreichung besserer Softwarequalität führen, wollen wir auch auf diesem Themengebiet unser Wissen ausbauen.&lt;br /&gt;
	&lt;br /&gt;
	Bei uns werden Web-Anwendungen entwickelt und erweitert, die sehr sensible Daten verarbeiten. Deswegen ist es für uns besonders wichtig, dass die Qualität in diesem Bereich bestens gesichert ist. Zu diesem Zweck haben wir letztes Jahr eine konkrete Aufgabe im Rahmen einer Bachelorarbeit definiert: Ziel war geeignete Werkzeuge für diesen Zweck systematisch zu ermitteln und nach unseren Kriterien zu evaluieren. Das „Sieger-Werkzeug“ soll zukünftig in unserem Unternehmen für die Automatisierung von Oberflächentests von Web-Anwendungen eingesetzt werden.&lt;br /&gt;
	&lt;br /&gt;
	Mittels einer Marktanalyse wurden über 90 Produkte ermittelt. Nach der Erstfilterung anhand von „Muss“-Kriterien, blieben nur noch 12 Tools übrig, die daraufhin anhand von „Wunsch“-Kriterien genauer evaluiert und einzeln bewertet wurden. Die höchste Bewertung erhielt Selenium WebDriver (Selenium 2) und stellte sich als insgesamt sehr überzeugendes Werkzeug heraus, natürlich auch weil das Java basierende Open Source Tool perfekt in unseren Unternehmenskontext passt."&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Selenium WebDriver&lt;/h3&gt;
&lt;p&gt;
	Selenium ist schon lange eine gute Alternative zu schwergewichtigen, proprietären und v.a. teuren Lösungen. Heute wird es von Firmen wie Ford Motors, Deutsche Bank, Adobe und Google eingesetzt [1]. Neben wenigen Schwächen in der Dokumentation und im Reporting, hat dieses Produkt viele Vorteile, die für it-economics GmbH eine wichtige Rolle spielen, u.a.:&lt;br /&gt;
	ausgezeichnete Integrität in den Unternehmenskontext&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		hohe Zukunftssicherheit&lt;/li&gt;
	&lt;li&gt;
		große Community&lt;/li&gt;
	&lt;li&gt;
		Erweiterbarkeit&lt;/li&gt;
	&lt;li&gt;
		Übersichtlichkeit, Wiederverwendbarkeit und Wartbarkeit von Tests&lt;/li&gt;
	&lt;li&gt;
		GUI-Test in Form von JUnit-Test und dadurch die Möglichkeit der Anbindung der Testausführung an Continuous-Integration-Systeme (CI-Systeme) wie beispielweise Jenkins[3].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	&lt;br /&gt;
	Mit Selenium WebDriver wurden im Rahmen der Bachelorarbeit vereinbarte Testszenarien exemplarisch umgesetzt, die Testausführung in ein CI-System integriert und somit der gesamte Testablauf beispielhaft automatisiert.&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Ausblick&lt;/h3&gt;
&lt;p&gt;
	Im nächsten Schritt werden wir die gewonnenen Erkenntnisse auf unsere Infrastruktur anwenden, unser Know-How im diesem Bereich weiter ausbauen und letztendlich dieses Wissen unseren Kunden zur Verfügung stellen.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	Quellen:&lt;br /&gt;
	[1] Java Magazin 9/2011, Seite 100.&lt;br /&gt;
	[2] http://wn.com/GTAC_2010_The_Future__of_Front-End_Testing (Minute 3)&lt;br /&gt;
	[3] http://www.jenkins-ci.org&lt;br /&gt;
	 &lt;/p&gt;</summary>
    <dc:creator>Wieslaw Nawrocki</dc:creator>
    <dc:date>2012-03-19T09:21:00Z</dc:date>
  </entry>
  <entry>
    <title>PMP/PMI für Projektleiter</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/pmp-pmi-fur-projektleiter" />
    <author>
      <name>Markus Huber</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/pmp-pmi-fur-projektleiter</id>
    <updated>2012-03-07T00:56:00Z</updated>
    <published>2012-03-07T00:56:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	Fast jeder Projektleiter wurde in seinem Berufsleben des Öfteren befragt, über welche Fähigkeiten er verfügen muss, um seine Arbeit erfolgreich auszuführen. Neben sehr guten kommunikativen und menschlichen Fähigkeiten, den sog. Social Skills muss er über hervorragende Methodenkenntnisse des Projektmanagements verfügen. Diese hat er normalerweise über die praktische Ausübung seiner Tätigkeit erlernt und wendet sie alltäglich bewusst oder auch unbewusst erfolgreich an. Diese Methodik wird in der Regel durch die Unternehmen, in denen die Projekte durchgeführt werden vorgegeben. Eine übergreifende Projektmethodik, die internationale Anerkennung genießt, ist der PMI (Project Management Institute) Standard, der durch das PMP (Project Management Professional) zertifiziert wird. Die in dieser Zertifizierung abgefragte Projektmethodik beschreibt die Prozess- und Werkzeugkenntnisse eines Projektleiters, die zur erfolgreichen Ausübung der Projektmanagementtätigkeit notwendig sind. Hierbei beschränkt sich das PMP für PMI nicht nur auf die Softwareindustrie, sondern erfreut sich z. B. auch in den Bereichen der klassischen Ingenieurwissenschaften hoher Anerkennung. Dieser Blog enthält zum Thema PMP/PMI für Projektleiter folgende Inhalte:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		&lt;p class="big"&gt;
			PMP Zertifizierung/ Prüfung nach PMI– Was ist das?&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p class="big"&gt;
			Welche Zertifizierungsvoraussetzungen gibt es und wo melde ich mich an?&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p class="big"&gt;
			Was muss ich wissen bzw. wie bereite ich mich vor?&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p class="big"&gt;
			Was folgt nach der Zertifizierung?&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p class="big"&gt;
			Fazit zur PMP Zertifizierung nach PMI&lt;/p&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
	PMP Zertifizierung/ Prüfung nach PMI– Was ist das?&lt;/h3&gt;
&lt;p&gt;
	Das Project Management Institute (PMI) ist ein weltweit tätiger US-amerikanischer Projektmanagementverband. Das PMI bietet mehrere Zertifizierungen an. Hierbei ist das PMP das Bekannteste. Das PMP steht für Project Management Professional und bezeichnet die Prüfung bzw. Zertifizierung, die die Projektmanagementkenntnisse nach PMI-Standard überprüft. Es wird von fast allen Industrien anerkannt als Zertifizierung für Projektleiter. In den Vereinigten Staaten ist das PMP beispielsweise ein notwendiges Kriterium, um eine Funktion als Projektleiter im öffentlichen Bereich auszuüben. Im Januar 2011 gab es über 500.000 Project Management Professionals (PMPs) in über 185 Ländern.&lt;/p&gt;
&lt;p&gt;
	Die Prüfung zur PMP Zertifizierung hat folgendes Format:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Die Prüfung dauert 4 Stunden (inklusive optionaler Pausen).&lt;/li&gt;
	&lt;li&gt;
		Sie besteht aus 200 Multiple Choice Fragen. Jede Frage besteht aus 4 Auswahlmöglichkeiten, wobei nur jeweils eine davon richtig ist.&lt;/li&gt;
	&lt;li&gt;
		Von den 200 Fragen werden 175 für die finale Bewertung herangezogen (25 davon – die nicht gesondert gekennzeichnet sind – werden nicht&amp;nbsp; für die finale Bewertung herangezogen, sondern sind in der Regel potentielle zukünftige Fragen, die von PMI evaluiert werden)&lt;/li&gt;
	&lt;li&gt;
		Die Prüfung gilt als bestanden, sobald 61% der Fragen richtig beantwortet wurden (d.h. also mindestens 106 von 175)&lt;/li&gt;
	&lt;li&gt;
		Die Prüfung wird in autorisierten und video-überwachten Prometric Testcentern durchgeführt.&lt;/li&gt;
	&lt;li&gt;
		In die Prüfungszimmer dürfen weder Unterlagen noch Verpflegung mitgenommen werden.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
	Welche Zertifizierungsvoraussetzungen gibt es und wo melde ich mich an?&lt;/h3&gt;
&lt;p&gt;
	Die PMP Zertifizierung ist ausgerichtet auf berufstätige Projektleiter, die eine zusätzliche Qualifikation erhalten wollen, in dem sie ihre Methodenkenntnisse nach dem PMI Standard innerhalb der PMP Prüfung zertifizieren lassen. Die PMP Zertifizierung ist daher strengen Zugangsvoraussetzungen unterworfen:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Ein Bewerber muss&amp;nbsp; über eine spezifische Ausbildung verfügen (i. d. Regel – aber nicht ausschließlich - ist dies ein abgeschlossenes Studium)&lt;/li&gt;
	&lt;li&gt;
		Zudem muss der Bewerber - je nach Ausbildung – über einschlägige Erfahrungen über mindestens 3 Jahre/4500h bzw. 5 Jahre/7500h (innerhalb der letzten 8 Jahre) im Bereich Projektmanagement vorweisen. Aus eigener Erfahrung ist diese Zugangsvoraussetzung sehr sinnvoll, da eine Abbildung der in der Vergangenheit erworbenen Projektmanagementkenntnisse das Erlernen der PMI-Methodik stark vereinfacht.&lt;/li&gt;
	&lt;li&gt;
		Des Weiteren muss der Bewerber vorweisen, dass er Projektmanagement Schulungen in einem Umfang von 35 Stunden besucht hat&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Die Anmeldung erfolgt über die offizielle PMI Website &lt;a href="https://www.pmi.org/default.aspx" target="_blank"&gt;https://www.pmi.org/default.aspx&lt;/a&gt;. Dort ist ebenfalls der Anmeldeprozess detailliert beschrieben.&lt;/p&gt;
&lt;h3&gt;
	&lt;br /&gt;
	Was muss ich wissen bzw. wie bereite ich mich vor?&lt;/h3&gt;
&lt;p&gt;
	Die PMP Zertifizierung überprüft die Projektmanagementkenntnisse nach PMI-Standard. Um die Prüfung bestehen zu können, müssen diese Werkzeuge, Nomenklaturen und Vorgehensweisen verinnerlicht werden.&amp;nbsp; Die PMI-Standards sind detailliert beschrieben in „A GUIDE TO THE PROJECT MANAGEMENT BODY OF KNOWLEDGE (PMBOK® GUIDE)“ &lt;a href="http://www.pmi.org/Certification/~/media/PDF/Certifications/pdc_pmphandbook.ashx" target="_blank"&gt;PMBOK&lt;/a&gt;.&lt;br /&gt;
	&lt;br /&gt;
	Die Projektmanagementmethodik wird unterteilt in sog. „Prozessgruppen“ und „Knowledge Areas“ eines Projektablaufs.&lt;/p&gt;
&lt;p&gt;
	1)&amp;nbsp; PMI unterscheidet hierbei in folgende „Prozessgruppen“ als Teilbereiche eines Projektes:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Initiating&lt;/li&gt;
	&lt;li&gt;
		Planning&lt;/li&gt;
	&lt;li&gt;
		Executing&lt;/li&gt;
	&lt;li&gt;
		Monitoring &amp;amp; Controlling&lt;/li&gt;
	&lt;li&gt;
		Closing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	2)&amp;nbsp;&amp;nbsp; &amp;nbsp;Des Weiteren unterscheidet PMI in folgende „Knowledge Areas“ eines Projektablaufs:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Integration&lt;/li&gt;
	&lt;li&gt;
		Scope&lt;/li&gt;
	&lt;li&gt;
		Time&lt;/li&gt;
	&lt;li&gt;
		Cost&lt;/li&gt;
	&lt;li&gt;
		Quality&lt;/li&gt;
	&lt;li&gt;
		Human Resource&lt;/li&gt;
	&lt;li&gt;
		Communications&lt;/li&gt;
	&lt;li&gt;
		Risk&lt;/li&gt;
	&lt;li&gt;
		Procurment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	&lt;br /&gt;
	Beide Bereiche kreieren in der PMI-Methodik eine Matrix, in der die unterschiedlichen Projektprozesse definiert sind, die innerhalb eines Projektablaufs (Initiating -&amp;gt; Closing) für die unterschiedlichen „Knowledge Areas“&amp;nbsp; (Integration -&amp;gt; Procurement) durchzuführen sind.&lt;br /&gt;
	&lt;br /&gt;
	Folgende Abbildung beschreibt alle PMI Projekt Prozesse innerhalb einer „Prozessgruppen – Knowledge Area“ Matrix:&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://www.it-economics.de/image/image_gallery?uuid=2907a72f-a512-4b8c-8807-a3f55f6dceaa&amp;amp;groupId=10458&amp;amp;t=1331125880701" target="_blank"&gt;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=2907a72f-a512-4b8c-8807-a3f55f6dceaa&amp;amp;groupId=10458&amp;amp;t=1331125880701" style="width: 500px; height: 724px; margin-left: 5px; margin-right: 5px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="big"&gt;
	Abbildung 1 Projektmanagement Prozesse - Mapping der Prozessgruppen und Knowledge Areas (Quelle: PMBOK)&lt;/p&gt;
&lt;p&gt;
	Der Prozess „Develop Project Charter“ ist somit Teil der Prozessgruppe „Initiating“ und Teil des Knowledge Areas „Integration“ Die Bestandteile der so aufgebauten Matrix sind Prozesse, die im Laufe eines Projektes durchschritten werden. Jeder Prozess basiert hierbei auf Eingaben (Inputs), die Ergebnisse (Outputs) anderer Prozesse sein können. Des Weiteren benützt jeder Prozess Werkzeuge (die sog. Tools &amp;amp; Techniques), die ihn dabei unterstützen, die Ergebnisse zu erstellen.&lt;br /&gt;
	&lt;br /&gt;
	Eine Anmeldung zur Prüfung ist dann sinnvoll,&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		wenn dem Prüfungsteilnehmer sowohl die Position des Prozesses innerhalb der „PMI-Matrix“ vertraut ist, als auch der eigentliche Inhalt bzw. die notwendigen Aktivitäten.&lt;/li&gt;
	&lt;li&gt;
		Zudem müssen die Inputs und Outputs bzw. auch die Tools &amp;amp; Techniques zu allen Prozessen bekannt sein.&lt;/li&gt;
	&lt;li&gt;
		Schließlich muss das Wissen durch zahlreiche Multiple Choice Tests gefestigt werden. Hierbei ist es vor allem wichtig, dass der Prüfungsteilnehmer mit den PMI Fragetechniken vertraut wird. Testfragen mit Beispieltests lassen sich im Internet finden.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Aus eigener Erfahrung empfehle ich, einen professionellen Vorbereitungskurs zu belegen. Dies hat vor allem den Vorteil, dass man sich Full-Time auf den Prüfungsstoff vorbereiten kann. Des Weiteren empfehle ich, nicht allzu viel Zeit zwischen Vorbereitungskurs und Prüfungstermin vergehen zu lassen. Idealerweise sollte ein Wochenende dazwischenliegen, die Dauer zwischen Ende des Vorbereitungskurses und Prüfungstermin sollte allerdings nicht länger als eine Woche betragen.&lt;/p&gt;
&lt;h3&gt;
	Was folgt nach der Zertifizierung?&lt;/h3&gt;
&lt;p&gt;
	Sobald die PMP Zertifizierung bestanden ist, darf man den Titel PMP nach PMI 3 Jahre lang führen. Darüber hinaus muss ein PMP ständigen Zertifizierungsanforderungen genügen, um seine Zertifizierung aufrechtzuerhalten. Diese Rezertifizierungen stehen alle drei Jahre an.&lt;br /&gt;
	Um die Zertifizierung nach 3 Jahren erneuern zu lassen, benötigt man 60 Professional Development Units (sog. PDUs). Diese PDUs erhält man beispielsweise durch folgende Aktivitäten:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Schulungen:&lt;br /&gt;
		a.&amp;nbsp;&amp;nbsp; &amp;nbsp;Teilnahme an Projektmanagement Schulungen, die durch PMI angeboten werden&lt;br /&gt;
		b.&amp;nbsp;&amp;nbsp; &amp;nbsp;Teilnahme an Projektmanagement Schulungen, die durch Universitäten bzw. Trainingsorganisationen angeboten werden&lt;br /&gt;
		c.&amp;nbsp;&amp;nbsp; &amp;nbsp;Selbstständige Weiterbildung&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;
		Aktives Lehren/ Anweisen:&lt;br /&gt;
		d.&amp;nbsp;&amp;nbsp; &amp;nbsp;Durch Erstellung von Projekt Management Knowhow&lt;br /&gt;
		e.&amp;nbsp;&amp;nbsp; &amp;nbsp;Freiwillige (unentgeltliche) Erbringung von Projektmanagement Diensten&lt;br /&gt;
		f.&amp;nbsp;&amp;nbsp; &amp;nbsp;Arbeit als Projektleiter&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Hierbei wird jeder Dauer einer Aktivität ein PDU Wert zugeschlüsselt. Hierbei gilt als Faustformel, dass ein PDU einer Arbeitsstunde/ Schulungsstunde/ Lehrstunde etc. entspricht (a) – e)). Für den Bereich f) erhält ein Projektleiter 5 PDUs, wenn er 12 Monate als Projektleiter tätig ist, sodass also max. 15 PDU für die Tätigkeit als Projektleiter innerhalb der 3 Jahre geltend gemacht werden dürfen.&lt;br /&gt;
	Genauere Details zu den PDUs und dem Rezertifizierungsverfahren kann ebenfalls dem PMBOK entnommen werden.&lt;/p&gt;
&lt;h3&gt;
	Fazit zur PMP Zertifizierung nach PMI&lt;/h3&gt;
&lt;p&gt;
	Die Vorbereitung zur Prüfung stellt zwar einen sehr hohen Aufwand dar. Zudem dauert die Prüfung selbst mit 4 Stunden relativ lange. Trotzdem überwiegen meiner Meinung nach die positiven Aspekte und ich kann die PMP Zertifizierung nach PMI auf jeden Fall empfehlen.&lt;br /&gt;
	Ich empfand es als sehr interessant, die Methoden und Prozesse des Projektmanagements im Rahmen des PMI Standards kennenzulernen und diese mit den Projektvorgehensweisen mit den mir bekannten Modellen bzw. Methoden zu vergleichen. Die PMI Projektmethodik gibt hier einen guten Überblick über das Projektmanagement und so manche Aufgabe, die man im Berufsleben eher unbewusst anwendet, findet hier sehr oft ein entsprechendes Mapping in einen der PMI Projekt Prozesse bzw. Aktivitäten. Zudem ist es von Vorteil mit einer Methodik vertraut zu sein, die nicht nur in der Softwareentwicklung anerkannt ist, sondern auch von anderen Disziplinen wie z.B. den klassischen Ingenieurwissenschaften geschätzt wird. Die Zertifizierung macht m. E. nur dann Sinn, wenn bereits mehrere Jahre Projektexpertise gesammelt wurden. Deshalb ist eine der Zugangsvoraussetzungen der Nachweis des Zeitraums der bereits als Projektleiter erbrachten Tätigkeiten. Der größte Vorteil der PMP Zertifizierung nach PMI ist jedoch die Steigerung des Marktwerts. Einerseits erhöht sich natürlich der Marktwert des Projektleiters, der über diese Zertifizierung verfügt. Andererseits verbessert sich ebenfalls der Marktwert der Beratungsfirma, indem das Unternehmen über zertifizierte Projektleiter verfügt, die auch aktiv von Kunden nachgefragt werden.&lt;br /&gt;
	 &lt;/p&gt;</summary>
    <dc:creator>Markus Huber</dc:creator>
    <dc:date>2012-03-07T00:56:00Z</dc:date>
  </entry>
  <entry>
    <title>IT Projekt und Portfolio-Management, Folge 1 Einführung und praktische Erfahrungen</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/it-projekt-und-portfolio-management-folge-1-einfuhrung-und-praktische-erfahrungen" />
    <author>
      <name>Tobias Pregler</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/it-projekt-und-portfolio-management-folge-1-einfuhrung-und-praktische-erfahrungen</id>
    <updated>2012-02-01T16:07:00Z</updated>
    <published>2012-02-01T16:07:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	Da gerade in den letzten Jahren das „IT Projekt &amp;amp; Portfolio-Management“ (kurz IT-PPM) durch die stetige Steigerung der Flexibilität in den einzelnen Organisationseinheiten&amp;nbsp; enorm an Bedeutung gewonnen und mittlerweile ein festes Kerngebiet bei der Steuerung einer Multi-Projektorganisation bildet, wollen wir Ihnen mit unserer Blog-Reihe die theoretischen Ansätze des IT-PPMs näher bringen und Ihnen einen Einblick in unsere praktischen Erfahrungen in diesem Themenumfeld aufzeigen. Die Reihe wird aus mehreren Folgen bestehen und in unserem Blog bereitgestellt. Unter anderem sind bis dato folgende Themen geplant:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		&lt;p class="big"&gt;
			Folge 1: Einführung und praktische Erfahrungen&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p class="big"&gt;
			Folge 2: Einblicke in die breite Softwarelandschaft&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p class="big"&gt;
			Folge 3: Vertiefung mit Hilfe eines ausgewählten Softwareprodukts&lt;/p&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
	Was versteht man unter&amp;nbsp; „IT Projekt &amp;amp; Portfolio-Management“?&lt;/h3&gt;
&lt;p&gt;
	Ein Projektportfolio wird durch die Gesamtheit aller alleinstehenden und zu Programmen zusammengefasster Projekte einer strategischen Geschäftseinheit gebildet. Durch die ständige Neupriorisierung, den Abschluss bzw. das Verwerfen von Projekten und Programmen und den strategischen Änderungen eines Unternehmens unterliegen die Projektportfolios einer ständigen Veränderung. Dabei steuert und kontrolliert das IT Projekt &amp;amp; Portfolio-Management innerhalb eines projektorientierten Unternehmens alle Projekte und Programme und stellt sicher, dass Unternehmen zum richtigen Zeitpunkt mit den geeignetsten Ressourcen und finanziellen Mitteln die relevanten Programme und Projekte durchführt.&lt;/p&gt;
&lt;p&gt;
	Aus langjähriger Erfahrung bei diversen Kunden kristallisierten sich bestimmte Kernaufgaben heraus, die das IT-PPM charakterisieren und vom Projekt- bzw. Programmmanagement abgrenzen:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=47d71010-d925-4e06-af65-cfbaf12d9757&amp;amp;groupId=10458&amp;amp;t=1328111006412" style="width: 608px; height: 344px; " /&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;cite&gt;Abb.1: Charakteristische Kernaufgaben des IT-PPM - Quelle: © it-economics GmbH&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;
	Im Gegensatz zum Programmmanagement fokussiert sich das IT-PPM auf die Prioritäten und Ziele des Unternehmens die vorhandenen Ressourcen sinnvoll und gezielt einsetzen zu können. Die Umsetzung und operative Kontrolle der jeweiligen Projekte erfolgt im Programm- bzw. Projektmanagement.&lt;/p&gt;
&lt;h3&gt;
	Wie funktioniert „IT Projekt &amp;amp; Portfolio-Management“?&lt;/h3&gt;
&lt;p&gt;
	Der Prozess des IT Projekt &amp;amp; Portfolio-Managements setzt sich aus drei Phasen zusammen:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=e0d6cab5-f9d8-479d-82c6-27f21141a53e&amp;amp;groupId=10458&amp;amp;t=1328111021058" style="width: 582px; height: 344px; " /&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;cite&gt;Abb.2: Die drei Phasen des IT-PPM - Quelle: © it-economics GmbH&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;1. Initiierungsphase&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
	In der Initiierungsphase werden geeignete Projektvorhaben erstmalig fachlich genauer beleuchtet und mit einer ersten groben Aufwandsschätzung versehen. Thematisch zusammenhängende Projektvorhaben werden zu geeigneten Projekten zusammengefasst um beurteilungsfähige Projektanträge erstellen zu können.&lt;/p&gt;
&lt;p&gt;
	Gerade in dieser Phase werden die Weichen für den Erfolg des geplanten Portfolios gestellt. Aus eigenen Erfahrungen lassen sich in dieser Phase oftmals bereits Über- bzw. Unterplanungen gezielt aufdecken und können auf Grund des frühen Zeitpunkts noch relativ leicht ausgeglichen werden. Es ist wichtig in dieser Phase bereits das Angebot (Unternehmensressourcen) und die Nachfrage (Anforderungen) im Auge zu behalten um im späteren Verlauf auf keine unerwarteten Situationen ad hoc reagieren zu müssen. Umso feiner die Granularität bereits ist, desto leichter lassen sich die gewünschten Unternehmensziele verfolgen und die verfügbaren Ressourcen beplanen und später auf die einzelnen Projekte aufteilen. Oftmals wird in dieser Phase jedoch nicht dediziert genug auf die verfügbaren Ressourcen geachtet wodurch im weiteren Verlauf Planungsenpässe auftreten und das Portfolio in Schieflage geraten kann.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;2. Planungsphase&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
	Während der Planungsphase werden anhand von vorgegebenen Priorisierungen und Auswahlkriterien des Unternehmens die gestellten Projektanträge genauer bewertet und mit dem notwendigen Budget und den damit verbundenen Ressourcen versorgt. Im Anschluss werden die selektierten Projektvorhaben in eine ganzheitliche Projektportfolioplanung mit den bereits laufenden Projekten zusammengefasst. Dieser Auswahlprozess ist ein ständig wiederkehrender Prozess. Abschließend wird das zusammengestellte Projektportfolio freigegeben.&lt;/p&gt;
&lt;p&gt;
	Dabei ist in dieser Phase wichtig, den Blick nicht nur auf die geplanten Projektvorhaben zu richten sondern die bereits laufenden Projekte im Auge zu behalten. Denn Ressourcen, die bereits in den laufenden Projekten verplant sind, können für die folgenden Projektvorhaben ggf. nicht wie gewünscht eingesetzt werden. Gerade in Shared Service Unternehmen, in denen die Planungs- und Steuerungseinheiten sowie die liefernden Einheiten getrennt und eigenständig agieren, wird oft der Fehler gemacht, nur in einzelnen Bereichen statt ganzheitlich übergreifend die Umsetzungsmöglichkeiten zu beachten. Dadurch kann oftmals das Projektportfolio nur in einzelnen Shared Service Einheiten umgesetzt werden, in anderen aber nicht mit den benötigten Mitarbeitern besetzt werden. Die Folge sind immer wieder kehrende Repriorisierungsrunden. Es ist aus diesem Grund essentiell wichtig, dass die planungsverantwortliche Einheit entweder vollständige Transparenz über alle Ressourcen hat. Alternativ kann auch dezentraler Prozess aufgesetzt werden, bei dem die Shared Service Einheiten Umsetzungszusagen machen. So oder so - eine enge Verzahnung der Bereiche ist in der Planungsphase wie auch in der darauf folgenden Umsetzungsphase der Grundstein für ein erfolgreiches Portfolio.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;3. Controllingphase&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
	Im Gegensatz zu der Initiierungs- und Planungsphase, die sequenziell ablaufen, wird in der Controllingphase permanent das aktuell freigegebene Projektportfolio überwacht und darauf geachtet, dass die Unternehmensziele in den Bereichen Leistungsumfang, Qualität, Kosten, Ressourcen und Zeit (SQERT) eingehalten werden. Im Falle von Auffälligkeiten werden die Risiken bewertet und entschieden wie diese Problemfälle am besten gelöst werden können.&lt;/p&gt;
&lt;p&gt;
	In den meisten Unternehmen wird schon zur Jahresmitte damit begonnen, für das Folgejahr eine Jahresplanung aufzusetzen, in der das geplante Projektportfolio erstellt wird. Da aber während eines Geschäftsjahres, zum Beispiel auf Grund von gesetzlichen Anpassungen, immer wieder ad hoc &amp;nbsp;in das definierte Projektportfolio eingegriffen werden muss, ist ein genaues Controlling der aktuell abzuwickelnden Projekte zwingend erforderlich, da nur so Budget-, Ressourcen- oder Terminkonflikte schnell und effizient entdeckt und eskaliert werden können. Gerade durch ein ständiges und effizientes Reporting der aktuellen Begebenheiten können die diversen Organisationseinheiten sich einen übergreifenden Blick über den aktuellen Fortschritt des Portfolios und der darin enthaltenen Projekte machen und schnell und effizient auf ggf. auftretende Abweichungen aus dem strategischen Unternehmenszielen eingreifen. Auch hier ist, wie in der Planungsphase, eine Verzahnung der einzelnen Bereiche notwendig um ein aussagekräftiges und ganzheitliches Bild zu erhalten. Insbesondere dann, wenn keine Shared Service übergreifende Projektleitung installiert ist.&lt;/p&gt;
&lt;h3&gt;
	Welches Ziel verfolgt „IT Projekt &amp;amp; Portfolio-Management“?&lt;/h3&gt;
&lt;p&gt;
	Ziel des IT Projekt &amp;amp; Portfolio-Managements ist durch eine dauerhafte Planung, Beurteilung, Priorisierung, Steuerung und Überwachung die Unternehmensinvestitionen in den Projekten gezielt zu optimieren. Dabei ist darauf zu achten, dass die Prozesse ständig gelebt werden um eine ganzheitliche, aussagekräftige und valide Planungsgrundlage zu erhalten. Um dies zu erreichen, sollte sich das Unternehmen immer wieder folgende Kernfragen vor Augen halten:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Verfolgen wir mit unserem Portfolio die angestrebte Unternehmensstrategie?&lt;/li&gt;
	&lt;li&gt;
		Besteht unser Portfolio aus der richtigen Zusammensetzung zwischen kurz-, mittel- und langfristigen Erfolgsmöglichkeiten?&lt;/li&gt;
	&lt;li&gt;
		Sind die eingegangenen Risiken bekannt und welche Auswirkungen haben diese?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Neben den unternehmensweiten Fragen sollte auch auf Ebene des Projektportfolios genau analysiert werden, ob der richtige Weg eingeschlagen wurde. Dabei helfen folgende Fragen:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Wie stabil ist unser Portfolio in Anbetracht auf den Fortschritt der darin enthaltenen Projekte?&lt;/li&gt;
	&lt;li&gt;
		Wurde das Portfolio richtig geschnitten und liefert es den erwarteten Nutzen?&lt;/li&gt;
	&lt;li&gt;
		Können noch weitere Projekte umgesetzt werden ohne das gesamte Portfolio zu gefährden?&lt;/li&gt;
	&lt;li&gt;
		Wie entwickeln sich die Aufwände und Kosten der einzelnen Projekte innerhalb unseres Portfolios?&lt;/li&gt;
	&lt;li&gt;
		Sollten Konflikte auftreten, welche Projekte innerhalb des Portfolios sollen priorisiert werden?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Fragen zum Unternehmen und unserem Portfolio sind nun gestellt, aber was ist mit unseren Mitarbeitern? Auf folgende Fragen sollte man hier jedenfalls Antworten haben:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Sind unsere Mitarbeiter richtig für die angestrebten Projekte qualifiziert?&lt;/li&gt;
	&lt;li&gt;
		Können wir mit unserer Belegschaft das definierte Portfolio stemmen, decken sich Angebot und Nachfrage?&lt;/li&gt;
	&lt;li&gt;
		Wie werden die einzelnen Mitarbeiter auf die jeweiligen Projekte verteilt?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Hat man all diese Themengebiete und Fragen im Blick, sollte man abschließend die Aussagekräftigkeit und Ergebnisse genausten analysieren, um den erhofften Nutzen aus den Antworten ziehen zu können.&lt;/p&gt;
&lt;p class="big"&gt;
	Im zweiten Teil dieser Blogserie werden wir Ihnen im März anhand von renommierten Marktforschungsunternehmen einen Einblick in den weitläufigen Markt kleiner wie auch namhafter Softwarehersteller bieten und Ihnen aufzeigen, wie das Zusammenspiel zwischen der reinen Theorie und den Tools gemeistert werden kann und welche Herausforderungen es dabei zu bewältigen gilt.&lt;/p&gt;</summary>
    <dc:creator>Tobias Pregler</dc:creator>
    <dc:date>2012-02-01T16:07:00Z</dc:date>
  </entry>
  <entry>
    <title>Anbindung von Bankenperipheriegeräten in virtuellen Umgebungen</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/anbindung-von-bankenperipheriegeraten-in-virtuellen-umgebungen" />
    <author>
      <name>Daniel Reis</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/anbindung-von-bankenperipheriegeraten-in-virtuellen-umgebungen</id>
    <updated>2012-01-20T19:41:00Z</updated>
    <published>2012-01-20T19:41:00Z</published>
    <summary type="html">&lt;h3&gt;
	Mehrwert einer Virtualisierung&lt;/h3&gt;
&lt;p class="big"&gt;
	Die Schlagworte „Virtualisierung“ und „Cloud“ sind derzeit im Bereich IT-Architektur oft zu hören und „ohne“ scheint es keinen Weg in die Zukunft zu geben.&lt;br /&gt;
	Inhaltlich verbirgt sich dahinter die Verlagerung des Betriebs von Software und Rechenleistung in entfernte Systeme. Eine Konzentration von Leistungen im Rechenzentrum (RZ) bietet eine ganze Reihe von Vorteilen, denen wir uns nicht entziehen können. Allem voran sind hier die Einsparpotentiale durch Vereinheitlichung der Prozesse sowie die Zusammenlegung und bessere Ausnutzung von Rechenleistung zu nennen. Die Anwendungen werden zentral verwaltet und die Komplexität sowie Kosten der IT reduziert. Der Auslastungsgrad der Hardware kann zudem gezielt erhöht werden.&lt;/p&gt;
&lt;h3&gt;
	Virtualisierung von Bankenperipheriegeräten&lt;/h3&gt;
&lt;p&gt;
	Aber was verbirgt sich genau hinter der Virtualisierung und was bedeutet dies für ein so komplexes Umfeld wie das einer Bankfiliale? Hier steht nicht nur die Arbeit mit einer Anwendung im Mittelpunkt, sondern das Tagesgeschäft eines Bankmitarbeiters mit Ein- und Auszahlungen über Kassentresore.&lt;br /&gt;
	Aber fangen wir vorne am Arbeitsplatz an und schauen uns zunächst nur die Virtualisierung des Clients an:&lt;br /&gt;
	Grundsätzlich ist Client-Virtualisierung ein Verfahren, um Benutzern gleichzeitig und unabhängig voneinander die Ausführung von Anwendungsprogrammen auf einem entfernten Server zu ermöglichen.&lt;br /&gt;
	Bei der Betrachtung der Bank verschieben wir also den Betrieb unserer Bankanwendung vom Filial-Client ins Rechenzentrum. Der Client verliert damit seine eigentliche Aufgabe und muss zukünftig nur noch das Bild der Anwendung aus dem Rechenzentrum anzeigen – im Grunde die Funktionalität eines Fernsehers. Wir brauchen somit keinen Fat-Client mit eigener Anwendungssoftware, sondern nur noch einen Thin-Client mit geringer Softwareausstattung.&lt;br /&gt;
	Das Rechenzentrum bietet uns die Software als Service. Dies kennen wir in ähnlicher Form vom „Office 365“ von Microsoft, das uns z.B. Word und Excel in der „Cloud“ anbietet. Auch hier wird uns die Anwendung auf einem (bzw. mehreren) entfernten Servern angeboten.&lt;br /&gt;
	Die Virtualisierung von Anwendungen gehört in den IT-Projekten inzwischen zu den gängigen Aufgaben und es gibt auch schon viele Erfahrungen in dem Bereich. Bei einem kompletten Schalter-Kasse-Betrieb in der Bank, müssen wir aber unsere Peripheriegeräte in der Filiale aus dem Rechenzentrum heraus ansteuern, da dort unsere Anwendungen laufen.&lt;br /&gt;
	&lt;br /&gt;
	Die folgende Skizze soll dies veranschaulichen:&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://www.it-economics.de/image/image_gallery?uuid=2d1b40c1-7833-4c6e-b073-a3ecb83a248f&amp;amp;groupId=10458&amp;amp;t=1327088787405" target="_blank"&gt;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=2d1b40c1-7833-4c6e-b073-a3ecb83a248f&amp;amp;groupId=10458&amp;amp;t=1327088787405" style="width: 550px; height: 267px; margin: 5px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
	Problemfelder bei der Bankenperipherie&lt;/h3&gt;
&lt;p&gt;
	Hier stehen wir nun vor einigen Problemen:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Aus dem Rechenzentrum heraus kommunizieren wir via TCP/IP, die Kassentresore z.B. werden aber – von den neuesten Modellen abgesehen – über eine serielle Schnittstelle angesprochen.&lt;/li&gt;
	&lt;li&gt;
		Es muss sichergestellt werden, dass wir mit dem richtigen Kassentresor in der Bankfiliale kommunizieren. Sowohl Rechenzentrum als auch Peripheriegerät in der Bank müssen sich authentifizieren.&lt;/li&gt;
	&lt;li&gt;
		Die Kommunikation zwischen Rechenzentrum (RZ) und Bank muss verschlüsselt sein.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Da die Verbindung zwischen RZ und Peripheriegerät in der Filiale das grundlegendste Problem darstellt, fokussieren wir uns zunächst auf den ersten Punkt.&lt;/p&gt;
&lt;h3&gt;
	Lösungsansätze&lt;/h3&gt;
&lt;p&gt;
	Betrachten wir die Kommunikation in Rechnernetzen vom ISO-OSI-Modell ausgehend, bieten uns die unterschiedlichen Schichten verschiedene Ansatzpunkte, um eine Kommunikation zwischen RZ-Server und Bankperipherie zu etablieren. Von der Bitübertragungs- bis zur Anwendungsschicht können wir theoretisch auf jeder Schicht aufsetzen. Die Lösungsmöglichkeiten sind vielfältig, da es für jede Schicht auch wiederum verschiedene Protokolle gibt. Des Weiteren können wir uns für ein Kaufprodukt oder eine Eigenbaulösung entscheiden. Eine Liste aller Lösungsansätze würde recht lang werden und jeden Ansatz zu verproben, wäre sicher zu aufwendig.&lt;br /&gt;
	Es sollten daher zunächst grundsätzliche Entscheidungen getroffen werden, z.B. Aufsetzen auf der Applikationsschicht oder eher Bitübertragungsschicht oder ob wir ein Kaufprodukt oder eher eine Eigenbaulösung einsetzen wollen.&lt;br /&gt;
	&lt;br /&gt;
	Beim Eigenbau einer solchen Lösung hätten wir auf der einen Seite eine sehr hohe Flexibilität und könnten das Produkt exakt auf unsere Wünsche zuschneiden, aber auf der anderen Seite müssten wir alle Anforderungen aus bankfachlicher als auch betriebs- und sicherheits-technischer Sicht selber definieren und implementieren. Neben unseren fachlichen Anforderungen, müssen wir auch Umsetzung, Betrieb, Sicherheit, Support und Weiterentwicklung im Auge behalten. Insbesondere im Betrieb tun sich weit mehr Fragen und Anforderungen auf, als man zunächst vermutet, z.B. Monitoring, Remote Operations, zentrale Logs, Software-Versorgung, Zertifikatsmanagement, Zukunftssicherheit usw. Diese Aufgaben werden zu Beginn eines Projektes gern unterschätzt, da häufig die Fachlichkeit im Fokus steht und weniger der technische Betrieb.&lt;br /&gt;
	Der Aufwand bei solch umfangreichen Projekten erreicht schnell eine beachtliche Größe und benötigt zusätzlich noch einen verhältnismäßig großen Risikopuffer. Denn in der Regel betritt das Unternehmen bei der Eigenentwicklung Neuland und muss die Erfahrungen, z.B. eines bereits am Markt bestehenden Produktanbieters, erst noch sammeln. Zudem besteht die Gefahr die Architektur nicht variabel genug zu konzipieren, so dass bei einer späteren Integration eines weiteren Softwareprodukts oder einer Hardware-Komponente die gesamte Architektur geändert werden muss.&lt;br /&gt;
	Der langfristige Support und Betrieb eines solchen Systems wiegt aber ebenfalls schwer. Beim Eigenbau einer Lösung müssten wir im Fehlerfall bis auf die Bit-Schicht herunter um den Fehler zu analysieren, die Zuständigkeit in unserer verteilten Architektur festzustellen und zu beheben.&lt;br /&gt;
	&lt;br /&gt;
	Im Gegensatz zur Eigenbaulösung steht die Integration eines Kaufproduktes. In unserem Fall der Bankenperipherieanbindung würde diese Software / Appliance in der Bank die TCP/IP-Befehle empfangen und als serielles Signal an die Peripheriegeräte weiterleiten. Bei der Lösung der Betriebsthemen würden die eigenen Anforderungen nur gegen die Möglichkeiten des Produkts gehalten und die Differenzen wären vom Anbieter aufzuarbeiten. Es wäre sicherlich sinnvoll sich von dem Kaufprodukt klar abzugrenzen und es nur als „Blackbox“ zu sehen. Es soll auf der einen Seite unsere fachlichen Vorgaben umsetzen und sich betriebstechnisch integrieren können, aber auf der anderen Seite die Verantwortlichkeit beim Hersteller belassen – „das Produkt muss einfach funktionieren“.&lt;br /&gt;
	Die Kosten beim Kauf eines Kaufproduktes sind sicher nicht unwesentlich, bieten uns aber ein höheres Maß an Kostensicherheit als der komplette Eigenbau. Auch würde sich der Betrieb und Support deutlich vereinfachen, da uns die verschlüsselte TCP/IP-Kommunikation nicht vor große Anforderungen stellt und die technische Ansteuerung der Peripheriegeräte dann beim Produkt liegt. Es böte sich sogar die Möglichkeit dem Kaufprodukt die fachlichen Funktionen vollständig zu überlassen. Am Beispiel einer Auszahlung könnte dies bedeuten, dass wir nur den Befehl „Auszahlung 100€ / Stückelungskennzeichen 1“ senden und alle weiteren technischen Aufgaben der Kaufsoftware im Sinne einer „Blackbox“ überlassen. Bei einem automatischen Kassentresor (AKT) wären dies unter anderem das&amp;nbsp; Sperren des AKTs für die Transaktion, die Auswahl der Geldrollen (Kassetten) zur Auszahlung, die Auszahlung selbst und die abschließende Freigabe des AKTs.&lt;br /&gt;
	&lt;br /&gt;
	Alles komplett selber zu steuern und zu entwickeln, gibt einem (fast) immer ein gutes Gefühl, man sollte aber die Risiken bei einem Eigenbau im Auge behalten. Wir haben im Falle der Anbindung der Bankenperipherie den Kauf eines Produktes empfohlen und in die Systemarchitektur des Kunden integriert. Damit haben wir die Kontrolle über die grundsätzliche Architektur und die Schnittstellen behalten und den Hersteller der Blackbox in einer zentralen Komponente unserer Architektur in die Verantwortung genommen.&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Unsere Lösung&lt;/h3&gt;
&lt;p&gt;
	So könnte vereinfacht eine Lösung zur Virtualisierung von Bankenperipheriegeräten aussehen:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=f605ba50-8386-4d8c-a161-bd3f57abc991&amp;amp;groupId=10458&amp;amp;t=1327088787408" style="width: 550px; height: 348px; margin: 5px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Virtualisierung von Bankenarbeitsplätzen wird spätestens mit der Anbindung der Peripheriegräte zu einer echten Herausforderung. Die Kommunikation aus dem Rechenzentrum in die Filiale hinein kann auf unterschiedlichste Weisen gelöst werden.&lt;br /&gt;
	Wir haben auf den Bau einer kompletten Eigenlösung verzichtet und stattdessen ein Kaufprodukt empfohlen mit entsprechender Aufgaben- und Verantwortungsverteilung. Wir profitieren dabei nicht nur durch das Produkt des Herstellers, sondern partizipieren auch von dessen Erfahrung bei anderen Geldhäusern. Zudem werden Aufwand und Risiko deutlich minimiert.&lt;br /&gt;
	 &lt;/p&gt;</summary>
    <dc:creator>Daniel Reis</dc:creator>
    <dc:date>2012-01-20T19:41:00Z</dc:date>
  </entry>
  <entry>
    <title>Workflow Engines – Das Mittel gegen unflexible und teure Geschäftsprozesse</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/workflow-engines-–-das-mittel-gegen-unflexible-und-teure-geschaftsprozesse" />
    <author>
      <name>Alexander Lechner</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/workflow-engines-–-das-mittel-gegen-unflexible-und-teure-geschaftsprozesse</id>
    <updated>2012-01-16T20:10:00Z</updated>
    <published>2012-01-16T20:10:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	Vor Ferien oder Brückentagen muss der Urlaub noch beantragt werden. Denn bevor man seine freien Tage genießen kann, sind viele organisatorische Schritte notwendig: Der Vorgesetzte muss dem Antrag zustimmen, die Personalabteilung muss informiert werden, ein Stellvertreter muss gefunden und in die Abwesenheitsnotiz im Outlook eingetragen werden. Ziemlich viele Aufgaben. Da kann es schon mal passieren, dass man etwas vergisst. Aber es wäre ärgerlich, wenn wegen einer Unachtsamkeit der Urlaub ins Wasser fiele.&lt;br /&gt;
	&lt;br /&gt;
	Um dem entgegenzuwirken setzen viele Unternehmen IT-Systeme ein, die den Arbeitnehmern bei der Ausführung des „Urlaubsprozesses“ helfen sollen. Diese Software ist allerdings oft unflexibel und muss bei Änderungen am Prozess mühsam angepasst werden.&lt;/p&gt;
&lt;h3&gt;
	Was können Workflow Management Systeme was andere nicht können?&lt;/h3&gt;
&lt;p&gt;
	Die kontinuierliche Verbesserung von Geschäftsprozessen ist nach Gartner eine der Top-4-Einsatzszenarien für Business Process Management Systeme (BPMS). Business Process Management Systeme oder Workflow Management Systeme (WFMS), wie der Oberbegriff lautet, dienen hierbei als gemeinsame Anlaufstelle für alle Geschäftsprozesse. Ziel dieser Software ist es, Änderungen an Prozessen nicht zu implementieren, sondern zu modellieren. WFMS bilden dabei das Bindeglied zwischen dem Management und der IT-Abteilung einer Firma. Der Workflow, der letztendlich zur erfolgreichen Beantragung eines Urlaubs führt, wird dabei nach dem Baukastenprinzip in einzelne Aufgaben unterteilt. Die Aufgaben stellen vorgefertigte Bausteine dar, die von der IT-Abteilung bereitgestellt und vom Management zu einem Geschäftsprozess zusammengefügt werden. Wenn man unser Beispiel in eine Prozesssprache übersetzt und in einzelne Aufgaben aufteilt, könnte das wie folgt aussehen:&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://www.it-economics.de/image/image_gallery?uuid=8d0f0af4-2949-4370-8bec-bc343784e112&amp;amp;groupId=10458&amp;amp;t=1326745559886" target="_blank"&gt;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=8d0f0af4-2949-4370-8bec-bc343784e112&amp;amp;groupId=10458&amp;amp;t=1326745559886" style="width: 550px; height: 300px; margin: 5px; float: left;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	Abbildung 1: Exemplarischer Workflow zur Beantragung von Urlaubstagen&lt;/p&gt;
&lt;p&gt;
	Wie mancher vielleicht bemerkt, ist dieser Prozess nicht perfekt und kann verbessert werden. Das WFMS bietet die nötige Flexibilität, um Änderungen am Prozess einfach zu modellieren und kann so auf fast alle erdenklichen Situationen reagieren. Da alle Schritte vom System überwacht werden, können auch keine Aufgaben vergessen werden. Das gewährleistet eine kurze Bearbeitungszeit. Workflow Engines helfen dadurch sogar die Kosten für einen Geschäftsprozess zu senken. WFMS eigenen sich nicht nur für die Verbesserung von Prozessen, sondern auch für firmenspezifische Prozesslösungen eines Problems oder für das service-orientierte Re-Design einer bestehenden Anwendung. Sie kommen besonders bei regelbasierten oder entscheidungsintensiven Prozessen zum Einsatz und eignen sich so z.B. für die Einführung neuer Produkte im Kreditgeschäft von Banken. Die Vorteile von WFMS liegen auf der Hand und auch Gartner hat im Jahr 2006 die Empfehlung zur Einführung solcher Systeme gegeben.&lt;/p&gt;
&lt;h3&gt;
	Wie finde ich die „richtige“ Workflow Engine?&lt;/h3&gt;
&lt;p&gt;
	Unternehmen, die sich jetzt für den Einsatz einer Workflow Engine entscheiden, stehen vor der schwierigen Aufgabe aus der Vielzahl von Anbietern das richtige Produkt zu finden. Es gibt weit mehr als 100 verschiedene Systeme mit unterschiedlichen Stärken und Schwächen. Nicht einmal Gartner lässt sich zu einer Aussage über die Anzahl aller Workflow Engines bewegen, sondern gibt nur einen kleinen Einblick über die Marktführer, solche die es werden wollen, und die Nischenprodukte.&lt;/p&gt;
&lt;p&gt;
	Abhandlungen, wie man die richtige Software für seine Zwecke findet, gibt es viele. Eine haben wir bereits in unserem Blog vorgestellt [&lt;a href="http://www.it-economics.de/blog/-/blogs/vendor-selection-process?_33_redirect=http%3A%2F%2Fwww.it-economics.de%2Fblog%2F-%2Fblogs%3F_33_advancedSearch%3Dfalse%26_33_keywords%3D%26_33_delta%3D5%26_33_cur%3D2%26_33_andOperator%3Dtrue"&gt;Vendor Selection Process&lt;/a&gt;].&lt;br /&gt;
	&lt;br /&gt;
	Bei WFMS sollte man vor allem darauf achten, welche Art von Workflow Engine benötigt wird. Man unterscheidet hierbei zwischen integration-centric, human-centric, document-centric und system-centric WFMS:&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://www.it-economics.de/image/image_gallery?uuid=a31d0b86-500b-42d1-9c1e-b3d9b7410344&amp;amp;groupId=10458&amp;amp;t=1327089796825" target="_blank"&gt;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=a31d0b86-500b-42d1-9c1e-b3d9b7410344&amp;amp;groupId=10458&amp;amp;t=1327089796825" style="height: 220px; margin: 5px; width: 600px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	Wenn man Probleme hat die Anforderungen des neuen Systems zu definieren, sollte man sich Gedanken über den Fokus der neuen Anwendung machen. Man sollte sich z.B. folgende Fragen stellen:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Welchen wirtschaftlichen Triebfaktoren unterliegt mein Unternehmen?&lt;/li&gt;
	&lt;li&gt;
		Welche Unternehmensstrategie habe ich?&lt;/li&gt;
	&lt;li&gt;
		Was sind die Ziele, Schwächen und Möglichkeiten meiner Firma?&lt;/li&gt;
	&lt;li&gt;
		Welche Risiken gibt es?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Für den erfolgreichen Einsatz und eine große Akzeptanz der Workflow Engine ist es außerdem wichtig zu wissen, wer die Stakeholder der neuen Technologie sind und wer in deren Konkurrenz tritt. Meist wird man in den betroffenen Organisationseinheiten des Unternehmens sehr schnell fündig. Um nach der Einführung eines WFMS&amp;nbsp; das neue System zu rechtfertigen und seinen positiven Nutzen herauszustellen, sollte man die Key Performance Indicators auf die neue eingesetzte Software anwenden.&lt;/p&gt;
&lt;h3&gt;
	Workflow Engines – Das Non plus Ultra der Prozessoptimierung?&lt;/h3&gt;
&lt;p&gt;
	Die Vorteile, die ein WFMS verspricht, sind viel versprechend. Alles soll besser, schneller, flexibler und günstiger werden. Die Möglichkeit eines up-to-the-minute Reportings ist für jeden Manager ein Traum. Workflow Engines bergen aber auch Gefahren, besonders wenn die Nutzer die neue Technologie nicht akzeptieren und eher als Überwachungsorgan des Managements empfinden. Die stetige Verbesserung und Neueinführung von Prozessen kann zu Overmanagement führen und das Unternehmen unflexibler machen. Es ist, wie so oft, nötig einen gesunden Mittelweg zu finden, um Workflow Engines erfolgreich einzusetzen.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	Quellen:&lt;a href="http://www.bpminstitute.org/articles/article/article/what-is-scope.html"&gt;&lt;br /&gt;
	&lt;br /&gt;
	http://www.bpminstitute.org/articles/article/article/what-is-scope.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://www.progress.com/docs/whitepapers/gated/savvion/understing_usage_patterns-wp.pdf"&gt;http://www.progress.com/docs/whitepapers/gated/savvion/understing_usage_patterns-wp.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://www.gartner.com/technology/media-products/reprints/oracle/article161/article161.html"&gt;http://www.gartner.com/technology/media-products/reprints/oracle/article161/article161.html&lt;/a&gt;&lt;/p&gt;</summary>
    <dc:creator>Alexander Lechner</dc:creator>
    <dc:date>2012-01-16T20:10:00Z</dc:date>
  </entry>
  <entry>
    <title>Effektives und effizientes Selbstmanagement, Teil 1 Grundlagen</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/effektives-und-effizientes-selbstmanagement-teil-1-grundlagen" />
    <author>
      <name>Torsten Klein</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/effektives-und-effizientes-selbstmanagement-teil-1-grundlagen</id>
    <updated>2012-01-02T20:51:00Z</updated>
    <published>2012-01-02T20:51:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	Wer kennt sie nicht diese Situation: Man sitzt in einem Restaurant, hat dem Kellner seine Bestellung klar und deutlich mitgeteilt – Ein Bier, einen gemischten Salat und danach eine Pizza Salami. Die Kollegen hatten ebenso bestellt. Der Kellner geht, und die Bestellung wird wie gewünscht ausgeliefert – oder?&amp;nbsp; Das wird nur klappen, wenn wir es mit einem robust organisierten Betrieb(sprozess) zu tun haben, in dem jeder Mitarbeiter in der Wertschöpfungskette seine Arbeitsaufgaben zuverlässig erledigt. Notiert z.B. der Kellner nicht alles präzise, wird die Küche etwas anderes ausliefern, als der Kunde gewünscht hat. Und wenn das häufiger passiert, verliert der Kellner seinen Job.&lt;/p&gt;
&lt;p&gt;
	Das ist ein Beispiel aus der Gastronomie. In Branchen wie der unsrigen, in denen Wissensarbeiter tätig sind, verhält es sich nicht anders. Zwar sind unsere Arbeitsschritte und Aufgabenbereiche komplexer und weniger klar umrissen&amp;nbsp; als im obigen Beispiel. Die Erwartungshaltung der bestellenden Kollegen / Kunden gegenüber dem Wissensarbeiter entspricht jedoch der oben genannten. Man erwartet, dass der Auftrag ausgeführt wird – in Time, in Scope, in Quality und in Budget – egal wie klein oder groß er ist.&lt;br /&gt;
	&lt;br /&gt;
	Nun ist das Problem, dass wir im täglichen Arbeits- und Privatleben nicht nur eine sondern sehr viele „Bestellungen“, d.h. Aufgaben haben. Sie prasseln täglich -gefühlt unendlich- häufig auf uns ein: E-Mails, SMS, Voicemails, Chats, Anrufe, Meetings, Statusprotokolle, usw., usw. Und so stehen wir – täglich – vor der Herausforderung, das alles zu verwalten und priorisiert abzuarbeiten. Doch vielen von uns – und das ist tatsächlich verblüffend – fehlt ein klares Konzept, wie damit umzugehen ist. &amp;nbsp;&lt;br /&gt;
	Die umfangreiche Literatur zum Thema Selbstmanagement bietet grundsätzlich zwei Ansätze, wie das Problem angegangen werden kann: „Top down“ oder „Bottom up“.&lt;br /&gt;
	&lt;br /&gt;
	Bekanntester Vertreter des erstgenannten Ansatzes ist Steven Covey. Er entwickelte das Konzept der Uhr und des Kompasses [Covey, S., First Things First, London 1994]. Der Kompass steht für die großen Ziele, die individuelle Himmelsrichtung nach der sich der einzelne ausrichten möchte. Ist diese bestimmt gilt es, alle (täglichen) Arbeiten daran auszurichten, durch entsprechend sinnvolle Planung und Priorisierung:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=367c417d-5dc2-4de8-a5f6-dc3fe8e29fdd&amp;amp;groupId=10458&amp;amp;t=1325674222856" style="width: 550px; height: 314px; float: left; margin: 5px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	Abb.1: Top Down Planung auf basierend auf Steven Covey - Quelle: © it-economics GmbH&lt;/p&gt;
&lt;p&gt;
	Auch &lt;a href="http://de.wikipedia.org/wiki/Lothar_J._Seiwert"&gt;Lothar Seiwert&lt;/a&gt; vertritt den Top Down Ansatz in ähnlicher Form. Er schlägt in seinem Buch „Wenn Du es eilig hast, gehe langsam“ auch konkrete Schritte zur Umsetzung vor:&lt;/p&gt;
&lt;p class="big"&gt;
	&lt;a href="http://www.it-economics.de/image/image_gallery?uuid=811a4ca2-5926-490f-9371-6c58590c2b8d&amp;amp;groupId=10458&amp;amp;t=1325674222856" target="_blank"&gt;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=811a4ca2-5926-490f-9371-6c58590c2b8d&amp;amp;groupId=10458&amp;amp;t=1325674222856" style="width: 600px; height: 168px; float: left; margin: 5px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="big"&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	Abb.2: Top Down Planung auf basierend auf Lothar Seiwert - Quelle: © it-economics GmbH&lt;/p&gt;
&lt;p&gt;
	So logisch und schlüssig diese Konzept erscheinen, so schwierig ist (zumindest für mich persönlich) die Operationalisierung. In einer Welt, in der kaum vorhersagbar ist, was die nächsten 3-5 Jahre passieren wird, konnte ich zwar mein persönliches Leitbild erarbeiten. Aber auf dieses hinzuarbeiten, indem ich Jahresziele und Wochenplanungen erstelle, erschien mir schwierig. Täglich änderten sich Aufgaben und Prioritäten und die wirkliche Herausforderung für mich war, diese sauber zu managen. Also schaute ich mich nach anderen Konzepten um.&lt;br /&gt;
	&lt;br /&gt;
	In David Allens „Getting Things Done (GTD)“ fand ich einen Ansatz, der sich (zunächst) um das Management der täglichen Herausforderung kümmert. All das Zeug, das einem im Kopf herumschwirrt, soll geordnet abgearbeitet werden können. Er entwirft ein robustes System, in dem nichts mehr verloren gehen kann. Denn: Wenn man nicht all des Zeugs Herr wird, braucht / kann man sich auch keine Gedanken über die großen Ziele machen. Man hat den Kopf einfach nicht frei dafür.&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=e92758f9-d0ab-44aa-a8a4-02fa07236b00&amp;amp;groupId=10458&amp;amp;t=1325674222855" style="width: 262px; height: 269px; margin: 5px; float: left;" /&gt;&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	&lt;cite&gt;Abb.3: Alles Zeug raus aus dem Kopf und rein in den Eingangskorb&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;
	Ist erst mal alles im Eingangskorb erfasst, geht es darum, diesen abzuarbeiten. Das Konzept ist aktionsorientiert. Das bedeutet, man soll sich fragen, was als nächstes genau zu tun ist. Kann man mit der E-Mail, dem Brief, Zettel, etc. nichts tun, dann wandert es entweder in den Müll oder in eine Wiedervorlage oder beim Referenzmaterial.&lt;br /&gt;
	Kann etwas getan werden und sind mehrere Schritte nötig, um das ToDo zu erledigen, wird ein Projekt dafür angelegt. Ist es nur ein Schritt, und dauert dieser weniger als 2 Minuten (nur dann!), wird das ToDo sofort erledigt. Ein Tipp: Man sollte die Zeit stoppen. Es ist überraschend, wie sehr man sich hier verschätzt! Dauert die Erledigung mehr als 2 Minuten, dann ist zu prüfen, ob man es delegieren kann. Nach dem Übertragen der Aufgabe, landet das ToDo in einem Ordner „Warten auf“.&lt;br /&gt;
	Muss man es selbst erledigen, so packt man das ToDo entweder in den Terminkalender (wenn es zu einem bestimmten Zeitpunkt erledigt sein muss) oder man legt es in einen Ordner „nächste Schritte (so bald als möglich).&lt;/p&gt;
&lt;p&gt;
	Und so arbeitet man sich für jedes ToDo durch den Eingangskorb:&lt;/p&gt;
&lt;p class="big"&gt;
	&lt;a href="http://www.it-economics.de/image/image_gallery?uuid=668e4947-8048-4434-b933-ac17db71c6ce&amp;amp;groupId=10458&amp;amp;t=1325674222856" target="_blank"&gt;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=668e4947-8048-4434-b933-ac17db71c6ce&amp;amp;groupId=10458&amp;amp;t=1325674222856" style="width: 600px; height: 450px; margin: 5px; float: left;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="big"&gt;
	Quelle: &lt;a href="http://de.wikipedia.org/w/index.php?title=Datei:GTD_Arbeitsablauf.png&amp;amp;filetimestamp=20061117211401"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	Im Ergebnis hat man nun alles kategorisiert und in Ordner verteilt. David Allen schlägt diverse Gruppierungsmöglichkeiten vor, aus denen man sich eine geeignete aussuchen kann.&lt;br /&gt;
	&lt;br /&gt;
	All diese Organisationsarbeit bringt allerdings nichts, wenn man das System nicht am Leben hält. Man muss sich also – wie beim Zähneputzen – dazu zwingen, das alles regelmäßig durchzusehen und aktuell zu halten. Und das war für mich die Achillesferse des Konzepts. Man hat es nämlich schnell mit mehr als 10-20 Listen zu tun (vgl. Punkt 3 „Organisieren“ – „Grundkategorien“):&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://www.it-economics.de/image/image_gallery?uuid=bd4f9165-3289-4003-809a-32488df7c3d2&amp;amp;groupId=10458&amp;amp;t=1325674222855" target="_blank"&gt;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=bd4f9165-3289-4003-809a-32488df7c3d2&amp;amp;groupId=10458&amp;amp;t=1325674222855" style="width: 600px; height: 415px; margin: 5px; float: left;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	Quelle: &lt;a href="http://de.wikipedia.org/w/index.php?title=Datei:GettingThingsDone.png&amp;amp;filetimestamp=20061117210804"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	„Zeug“ kann in elektronischer Form und in papierhafter Form vorliegen. Entsprechend sind die verschiedenen Listen und Kategorien auch nicht auf Papier bzw. E-Mails beschränkt. So multiplizieren sich die Aufwände zum Durchsehen entsprechend. Das System lähmt dann eher, und ich hatte das Gefühl, dass ich mehr Zeit mit Kategorisieren und Durchsehen verbrachte, als mit dem Abarbeiten der Aufgaben.&lt;br /&gt;
	&lt;strong&gt;Und so entwarf ich mein eigenes System, über das ich im nächsten Blog berichten werde…&lt;/strong&gt;&lt;/p&gt;</summary>
    <dc:creator>Torsten Klein</dc:creator>
    <dc:date>2012-01-02T20:51:00Z</dc:date>
  </entry>
  <entry>
    <title>Kanban in der Wartung</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/kanban-in-der-wartung" />
    <author>
      <name>Steffen Kleeberg</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/kanban-in-der-wartung</id>
    <updated>2011-12-16T09:09:00Z</updated>
    <published>2011-12-16T09:09:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	Das Jahr neigt sich dem Ende zu. Die Weihnachtsfesttage haben begonnen und viele freuen sich auf besinnliche Stunden mit der Familie. Insbesondere für Entwicklungsteams eine Zeit, in der die Möglichkeit besteht, zur Ruhe zu kommen und die vielen Aufgaben zu vergessen. Der tägliche Terminstress, kommt im nächsten Jahr bestimmt wieder.&lt;br /&gt;
	Doch das muss nicht sein und ich möchte diesen Blog nutzen, einen Entwicklungsansatz vorzustellen, der überlasteten Teams die Ruhe und damit auch eine erhöhte Teamleistungsfähigkeit zurückbringen kann.&lt;/p&gt;
&lt;h3&gt;
	Kanban – Warum noch ein Agiler Ansatz?&lt;/h3&gt;
&lt;p&gt;
	In einem Wartungs-/Entwicklungsprojekt kommt man oft an einen Punkt, an dem sich die ursprünglichen Aufgaben verändern und mehr Verantwortung auf das Team zukommt, als man zu Beginn erwarten konnte. Speziell in Wartungsteams, können neben dem Tagesgeschäft auch weitere Themengebiete dazukommen.&lt;br /&gt;
	&lt;br /&gt;
	In meinem aktuellen Projekt, stehen wir vor einer solchen Herausforderung:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Es gibt mehrere Produktbestandteile die in der Wartung betreut werden&lt;/li&gt;
	&lt;li&gt;
		Probleme im Systemumfeld führen zu Analyseaufwand, obwohl die Fehlerbehebung von einem anderen Team geleistet wird&lt;/li&gt;
	&lt;li&gt;
		Für alle Bestandteile gibt es in regelmäßigen Abständen Erweiterungswünsche&lt;/li&gt;
	&lt;li&gt;
		Es wurde eine komplette Neuentwicklung übernommen, die bis zur produktiven Einführung begleitet wurde, jetzt steht die Übernahme der Wartungsaufgabe an&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	&lt;br /&gt;
	All diese Aufgaben müssen durch das Team parallel bearbeitet werden und es muss immer die Möglichkeit bestehen, besonders kritische Probleme sofort bearbeiten zu können. Jedes Teammitglied arbeitet also an vielen Dingen gleichzeitig, ohne dass nach außen eine Transparenz bestand, welche Themen da sind.&lt;br /&gt;
	&lt;br /&gt;
	Um dies transparenter, sowohl für das Team als auch für Außenstehende zu gestalten, überdachten wir unser Vorgehensmodell und stießen mit Kanban auf eine Methodik, die uns am Besten für das breit gefächerte Aufgabengebiet geeignet erschien.&lt;br /&gt;
	Methoden, die spontane Änderungen ausschließen und eine komplette Umstellung der etablierten Vorgehensweisen erfordern, kamen für uns nicht in Frage. Insbesondere, da in einem Kundenprojekt der Kunde den Takt und die Randparameter vorgibt. In einem solchen Umfeld muss man sich in einen großen Prozess einfügen und gleichzeitig für das eigene Team den effektivsten Weg wählen.&lt;/p&gt;
&lt;h3&gt;
	Kanban – Ein paar Hintergrundinformationen&lt;/h3&gt;
&lt;p&gt;
	Der Begriff Kanban (Kan ban = japanisch für Signalkarte) wird oft zusammen mit dem Kaizen Prozess (Prozess der kontinuierlichen Verbesserung) und der Lean Production bzw. Development („Verschlankungsprozess“) betrachtet, da Kanban insbesondere den Kaizen Prozess in einem Unternehmen fördern kann. Das Ziel ist, den Mitarbeitern die Möglichkeit zu geben, sich selber zu verbessern und gleichzeitig die Zeit, die eine Aufgabe zur Bearbeitung benötigt, zu verringern.&lt;br /&gt;
	&lt;br /&gt;
	Dabei setzt Kanban auf die etablierten Prozesse in einem Team auf, ohne Änderungen an diesen zu erzwingen. Zentrales Mittel ist die Visualisierung der Arbeitsabläufe, das es ermöglicht, Engpässe zu erkennen, damit diese genauer analysiert werden können. Diese Visualisierung kann elektronisch geschehen, verbreiteter ist jedoch die Verwendung eines sogenannten „Kanban Boards“, auf dem der Durchlauf einer Aufgabe durch das System vom einem Startpunkt bis zu einem definierten Endpunkt erfolgt.&lt;br /&gt;
	In unserem Fall, nimmt dieses Board zwei große Whitebordwände ein und visualisiert unsere einzelnen Arbeitsschritte:&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=facfd66d-c7f3-4f9f-8b7d-f3b97d25a0a1&amp;amp;groupId=10458&amp;amp;t=1324027121490" style="width: 600px; height: 247px; float: left; margin: 5px;" /&gt;&lt;/p&gt;
&lt;p class="big"&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	 &lt;/p&gt;
&lt;p class="big"&gt;
	Abbildung 1: Kanban Board&lt;/p&gt;
&lt;p&gt;
	Die Einführung des Boards war für uns der erste Schritt und für uns auch die größte sicht- und spürbare Änderung. Gerade da Kanban keine Änderungen erzwingt, war die Akzeptanz im Team von Beginn an sehr hoch. Schnell bestätigte sich das, was wir bislang nur vermutet haben: Ein Engpass in der Analyse- und der Testphase.&lt;br /&gt;
	&lt;br /&gt;
	Wir entschieden uns dafür, Kanban sanft einzuführen, d.h. wir nutzen nicht alle Methoden und Maßnahmen die Kanban für den Kaizenprozess zur Verfügung stellt. Da wir zuerst ein besseres Verständnis für die Auslastung eines jeden Teammitglieds erhalten wollten, verzichteten wir z.B. auf die Limitierung der Aufgabenkarten pro Arbeitsschritt.&lt;br /&gt;
	Wie sich jedoch schnell zeigte, beschränkt sich der Nutzen von Kanban dann sehr schnell auf die Visualisierung. Eine echte Verbesserung der Arbeitsauslastung der Teammitglieder kann sich so noch nicht einstellen. Aus diesem Grund werden wir jetzt in weiteren Schritten die Möglichkeiten von Kanban weiter ausschöpfen.&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Kanban – Mittel und Wege zum Kaizen Prozess&lt;/h3&gt;
&lt;p&gt;
	Gerade die Limitierung der Auslastung pro Arbeitsschritt ist ein wichtiger Steuerungshebel, um jedem Teammitglied eine bessere Fokussierung auf die aktuelle Aufgabe zu ermöglichen. Durch dieses Limit, auch Work In Progress (WIP) Limit genannt, wird sichergestellt, dass jeder nur so viele Aufgaben bearbeitet, wir er auch wirklich mit einer hohen Qualität erledigen kann.&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=1188d761-76da-4d86-880c-12770c8bb104&amp;amp;groupId=10458&amp;amp;t=1324027121490" style="width: 600px; height: 247px; float: left; margin-top: 5px; margin-bottom: 5px;" /&gt;&lt;/p&gt;
&lt;p class="big"&gt;
	Abbildung 2: Kanban Board mit WIP Limits&lt;/p&gt;
&lt;p&gt;
	Ist eine Aufgabe erledigt, steht sie dem nächsten Arbeitsschritt zur Verfügung und wenn sie in diesen verschoben wurde, kann eine neue Aufgabe begonnen werden. Damit entsteht ein sogenanntes „Pull-System“. In diesem, hat jeder Arbeitsschritt einen vorgelagerten Puffer, aus dem er sich bedienen kann. Das ist immer dann zulässig, wenn der WIP die Möglichkeit dazu bietet. Dieser Puffer kann ein Puffer im klassischen Sinne sein (z.B. am Startpunkt), oder eben&amp;nbsp; ein vorgelagerter Arbeitsschritt.&lt;br /&gt;
	&lt;br /&gt;
	Eine weitere Möglichkeit zur Optimierung der Abläufe, ist die Einführung von Serviceklassen. Damit ermöglicht es Kanban, bei einzelnen Aufgaben eine Priorisierung vorzunehmen. Damit war es uns möglich,&amp;nbsp; die Abarbeitung von Prio1 Tickets vorzusehen, obwohl ein WIP Limit dieses verhindert hätte.&lt;/p&gt;
&lt;h3&gt;
	Kanban – Die Lösung?&lt;/h3&gt;
&lt;p&gt;
	Zusammenfassend kann man Kanban die Fähigkeit bescheinigen, dass es sich gut auf bestehende Prozesse abbilden lässt. Es erzwingt keine Anpassung, einen echten Gewinn bringt es jedoch erst, wenn man wirklich die (wenigen) „Regeln“ befolgt. Bei deren Einführung gibt Kanban keine Geschwindigkeit vor, sondern ermöglicht eine Eingewöhnungsphase, in der man sich langsam an die für das eigene Team passende Variation heranarbeitet.&lt;br /&gt;
	&lt;br /&gt;
	In dem Wartungsprojekt, in dem ich gerade arbeite, ist Kanban für die Transparenz unserer Aufgaben sehr hilfreich. Wir haben uns dafür entschieden Kanban erst einmal auszuprobieren und gerade am Anfang hat das Kanban-Board einige Änderungen erfahren. Jetzt steht die Einführung eines WIP Limits an, ein Schritt den wir bislang noch nicht durchgeführt haben. Damit kommen dann auch die Serviceklassen und es wird spannend sein, die Auswirkungen zu beobachten.&lt;br /&gt;
	 &lt;/p&gt;</summary>
    <dc:creator>Steffen Kleeberg</dc:creator>
    <dc:date>2011-12-16T09:09:00Z</dc:date>
  </entry>
  <entry>
    <title>IPv6 - Das Internet im Wandel</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/ipv6-das-internet-im-wandel" />
    <author>
      <name>Kresimir Gronjak</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/ipv6-das-internet-im-wandel</id>
    <updated>2011-11-21T20:20:00Z</updated>
    <published>2011-11-21T20:20:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	Als das Internet in den siebziger Jahren ersonnen wurde, hatte niemand damit gerechnet, dass es solch eine überwältigende Popularität erreichen würde. Das einfache IPv4 Protokoll, welches 1981 erfunden wurde, war vollkommen ausreichend. Mit der Verbreitung der PCs und der Entstehung des World Wide Web (WWW) wurde aber schon Mitte der neunziger Jahre klar, dass es früher oder später zu einer Verknappung der IP-Adressen im IPv4 Format kommen würde. Deswegen wurde 1995 das Internet Protocol Next Generation ins Leben gerufen. Dieses Protokoll wurde später in Internet Protocol version 6 oder kurz IPv6 umbenannt. 1998 wurde das Protokoll schließlich standardisiert. Anstatt eine rasante Verbreitung zu finden und schnell das Protokoll IPv4 zu verdrängen, wird es auch heute noch nur sporadisch eingesetzt. Das Abwarten hat nun ein Ende. Seit Februar 2011 gibt es keine freien IPv4 Adressen mehr. Eine Vergrößerung des Adressraums ist nun also nicht mehr eine Option sondern eine Notwendigkeit. Der Blog befasst sich mit dem Aufbau von IPv6, den Gründen für den zögerlichen Einsatz und einem Fazit zum Einsatz von IPv6.&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;
	Aufbau der IPv6 Adresse&lt;/h3&gt;
&lt;p&gt;
	Das IPv6 Protokoll besitzt einen Adressraum von 2^128 Adressen. Im Gegensatz zu den 2^32, also etwa 4 Milliarden Adressen von IPv4 könnten wir praktisch alles im Universum mit einer eigenen Adresse versehen. Um diese Adresse einigermaßen übersichtlich darzustellen, wurde auf die Dezimalschreibweise von IPv4 verzichtet und die Hexadezimal-Schreibweise eingesetzt.&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;2a01:4f80:1310:c200:0000:dead:beef:cafe&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;
	Gehen wir etwas näher auf den Aufbau der IPv6 Adresse ein. Die Adresse wird zunächst in zwei Teile gespalten. Der erste Teil der Adresse, das sog. Präfix wird vom Provider und von der RIR (Regional Internet Registry) vergeben. Der zweite Teil der Adresse erstellt sich der Rechner selbst. Deswegen heißt dieser Teil auch Interface Identifier. Zur Erstellung des Interface Identifiers kommen wir später zu sprechen. In unserem obigen Beispiel wäre das Präfix also&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;2a01:4f80:1310:c200/64&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Dementsprechend wäre&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;0000:dead:beef:cafe/64&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	der Interface Identifier.&lt;br /&gt;
	&lt;br /&gt;
	Der Provider bekam dabei vom RIR wahrscheinlich&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;2a01:4f80/32&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Der Endkunde bekam möglicherweise&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;2a01:4f80:1310/48&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	oder nur&lt;br /&gt;
	&lt;br /&gt;
	2a01:4f80:1310:c200/56.&lt;br /&gt;
	&lt;br /&gt;
	Der Rechner muss diesen Teil im Netz erfragen. Dazu schickt er eine Multicast Abfrage, die sich Router Solicitation nennt, ins Netz und wartet auf die Antwort. Die Antwort auf eine Router Solicitation nennt sich Router Advertisement und die Router schicken sie in regelmäßigen Abständen. Der Rechner merkt sich nämlich die nächsten Router und verschickt über sie die Pakete. Falls sich ein Router für längere Zeit nicht meldet, wird er aus der Liste der möglichen Router entfernt.&lt;/p&gt;
&lt;p&gt;
	Hierbei ist es wichtig zu erwähnen, dass IPv6 unbedingt das Internet Control Message Protocol (ICMP) benötigt. Über das ICMP Protokoll werden die Adressen ausgehandelt. Falls die lokale Firewall das ICMP blockt, kann der Rechner keine Adresse erhalten und die Adressvergabe wird scheitern.&lt;/p&gt;
&lt;p&gt;
	Kommen wir nun zum zweiten Teil der Adresse. Normalerweise wird der Interface Identifier mit Hilfe der Hardware Adresse der Netzwerkkarte, auch MAC Adresse genannt, erstellt. Die MAC Adresse hat nur 48 Bit. Deswegen werden die restlichen 16 Bit als ff:fe auch fest vorgegeben. Nachdem die Adresse erstellt wurde, muss nun sichergestellt werden, dass die Adresse nicht schon existiert. Dieses Vorgehen wird auch Neighbour Solicitation genannt. Der vermeintliche Nachbar wird direkt angesprochen, d. h. wir sprechen hierbei von Unicast. Zu diesem Zeitpunkt würde unser Rechner in einem IPv4 Netzwerk einen Broadcast absenden, um den DHCP Server im Netz zu finden. Dadurch senkt sich die Netzwerkbelastung beträchtlich.&lt;br /&gt;
	&lt;br /&gt;
	Falls die Adresse nun doch vergeben ist, dann vergrößert der Rechner die Adresse einfach um eins und versucht es noch einmal. Im Normalfall heißt das, der Rechner muss irgendwie in das Netz eingesetzt werden. Den Rest erledigt das Netz vollautomatisch.&lt;/p&gt;
&lt;h3&gt;
	Dual Stack&lt;/h3&gt;
&lt;p&gt;
	Das IPv6 Protokoll hat bisher keine große Verbreitung gefunden. Die Gründe dafür sind verschieden. Zum Teil müssen viele Router und Server umgestellt werden. Weiterhin muss auch die Software IPv6 fähig gemacht werden. Deswegen wurde das Dual Stack erfunden. Dual Stack ist die gleichzeitige Nutzung von IPv4 und IPv6. Ein Rechner bekommt also gleichzeitig eine IPv4 und IPv6 Adresse zugewiesen. Dadurch ist es in der Übergangsphase möglich, den Rechner in beiden Netzen zu betreiben. Der Grund für diese Dual Stack Phase ist, dass das Ende der IPv4 Phase nicht eindeutig definiert ist. Der Übergang soll langsam erfolgen.&lt;/p&gt;
&lt;h3&gt;
	Mobile IPv6 und Privacy Extensions&lt;/h3&gt;
&lt;h4&gt;
	Mobile IPv6&lt;/h4&gt;
&lt;p&gt;
	Die IPv6 bringt einige interessante Neuerungen mit. Die erste nennt sich Mobile IPv6 und kann in mobilen Geräten eingesetzt werden. Der Grundgedanke bei diesem Feature ist, dass das mobile Geräte (Notebook, Handy) jederzeit mit seiner lokalen Adresse aufgerufen werden kann. Dadurch kann das Gerät immer gefunden werden, unabhängig davon in welchem Netz es sich zur Zeit befindet.&lt;/p&gt;
&lt;p&gt;
	Wie funktioniert das?&lt;br /&gt;
	Das Notebook befindet sich im lokalen Netz zu Hause und ist mit seiner eindeutigen 128 Bit IPv6 Adresse erreichbar. Nun geht der Besitzer mit dem Rechner aus dem Haus und zur Arbeit. An der Arbeitsstätte angekommen, wird das Notebook im Arbeitsnetz angesteckt und bekommt eine neue Adresse. Das Notebook meldet jetzt dem sog. Home Agent die neue Adresse und er verbreitet die Information weiter im Netz. Nun weiß jeder Kommunikationspartner, in welchem Netz das Notebook zu finden ist.&lt;br /&gt;
	&lt;br /&gt;
	Dieses Feature ist nur soweit gegeben, so lange die Firmenfirewall mitspielt. Wenn die Firewall fremde Netze blockt, kann Mobile IPv6 nicht eingesetzt werden.&lt;/p&gt;
&lt;h4&gt;
	Privacy Extensions&lt;/h4&gt;
&lt;p&gt;
	Ein weiteres Feature sind die Privacy Extensions. Im Gegensatz zu Mobile IPv6 setzt PE auf Privatsphäre. Die Vergabe des Interface Identifiers ist nämlich eindeutig und dadurch kann das Gerät verfolgt werden. Um das zu unterbinden, wird dieser Teil der Adresse zufällig erstellt. Außerdem handelt es sich hierbei um eine zeitlich begrenzte Adresse, die regelmäßig neu erstellt wird. Interessanterweise unterstützen die meisten Betriebssysteme diese Möglichkeit, aber bei einigen ist sie einfach nicht eingeschaltet. Während es bei Serversystemen, wie z. B. Windows Server oder Linux sinnvoll ist, auf diese Möglichkeit zu verzichten, sollten gerade die Betriebssysteme der Smartphones die Privacy Extensions nutzen, um die Nutzer vor Verfolgung zu schützen. Dies ist aber nicht immer gegeben. iOS und Android unterstützen, diese Möglichkeit, aber beim iOS sind Privacy Extensions erst ab der Version 4.3 aktiviert. Beim Android sind sie auch standardmäßig deaktiviert.&lt;/p&gt;
&lt;h3&gt;
	Vorteile von IPv6&lt;/h3&gt;
&lt;p&gt;
	Die Vorteile von IPv6 sind offensichtlich. Durch die Autokonfiguration ist eine einfache Möglichkeit der Adressvergabe gegeben. Dadurch dass kein NAT benutzt werden muss, werden nicht nur die lokalen, sondern auch die großen Router im Netz deutlich entlastet. Es ist nämlich absehbar, dass die Backbones in der Zukunft immer mehr Arbeit haben werden, weil sie den IPv4 Adressraum mittels NAT künstlich vergrößern müssen. Dadurch wird es immer teurer, die IPv4 Adressen zu nutzen, was hoffentlich den Übergang beschleunigen wird.&lt;br /&gt;
	Im privaten Rahmen wird es außerdem noch möglich sein, z. B. einen privaten Mailserver einzurichten. Zur Zeit ist das wegen der sich ständig ändernden Adresse nicht möglich. Solche Mailserver werden automatisch auf eine Sperrliste („Blacklist“) gesetzt.&lt;/p&gt;
&lt;h3&gt;
	Gefahren von IPv6&lt;/h3&gt;
&lt;p&gt;
	Neben den enormen Vorteilen, müssen natürlich auch die Bedenken geäußert werden. Durch die eindeutige Adresse ist eine Verfolgung im Internet möglich. Personalisierte Werbung und Spam könnten die Folge sein.&lt;/p&gt;
&lt;p&gt;
	Eine weitere Gefahr liegt in&amp;nbsp; Mobile IPv6. Wenn man im Netz immer die gleiche Adresse hat, dann können auch die Privacy Extensions hier nur begrenzt helfen.&lt;br /&gt;
	Das Fehlen von NAT könnte auch als eine Einschränkung der Privatsphäre angesehen werden. Durch NAT war zwar eine Ende-zu-Ende Verbindung nicht möglich. Auf der anderen Seite konnten die Pakete nur bis zum Router verfolgt werden. Weiter war es nicht möglich zu erkennen, welcher Rechner die Anfrage gesendet hat. Ein Ende-zu-Ende Protokoll hätte in diesem Fall also auch Nachteile.&lt;/p&gt;
&lt;h3&gt;
	Fazit&lt;/h3&gt;
&lt;p&gt;
	IPv6 kommt mit großen Schritten, da IPv4 an seine Grenzen gestoßen ist. Die Betriebssysteme sind dafür bereit. Es kann sein, dass einige Anwendungen in der Entwicklung noch hinterherhinken, aber das ist nicht das größte Problem. Die Änderungen in der Privatsphäre durch Ende-zu-Ende Protokolle, Mobile IPv6, Eindeutigkeit usw. sind die größten Gefahren. Diese müssen&amp;nbsp; zunächst an die Benutzer kommuniziert werden, damit sie dagegen gewappnet sind. Deswegen ist es vielleicht gut, dass wir noch ein paar Jahren warten müssen, bevor das IPv4 komplett abgeschaltet wird.&lt;/p&gt;
&lt;p&gt;
	Weiterführende Quellen:&lt;a href="http://tools.ietf.org/html/rfc4487"&gt;&lt;br /&gt;
	http://tools.ietf.org/html/rfc4487&lt;/a&gt;&lt;a href="http://www.ripe.net/ripe/docs/ripe-512#assignment_size"&gt;&lt;br /&gt;
	http://www.ripe.net/ripe/docs/ripe-512#assignment_size&lt;/a&gt;&lt;/p&gt;</summary>
    <dc:creator>Kresimir Gronjak</dc:creator>
    <dc:date>2011-11-21T20:20:00Z</dc:date>
  </entry>
  <entry>
    <title>Legacy Code unter Kontrolle - Folge 3, JMockit für Fortgeschrittene</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/legacy-code-unter-kontrolle-folge-3-jmockit-fur-fortgeschrittene-1" />
    <author>
      <name>Pascal Gugenberger</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/legacy-code-unter-kontrolle-folge-3-jmockit-fur-fortgeschrittene-1</id>
    <updated>2011-11-07T12:20:00Z</updated>
    <published>2011-11-07T12:20:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	Im ersten Blog-Eintrag dieser kleinen Serie habe ich erzählt, warum JMockit eine so wichtige Rolle spielt, wenn es darum geht, eine Legacy-Anwendung zu testen. Im nächsten Eintrag habe ich das wichtigste API von JMockit, das Expectations-API vorgestellt. Als Abschluss zeige ich an zwei konkreten Beispielen aus der Praxis, wie JMockit einem auch in schwierigen Fällen einen Unit-Test möglich macht.&lt;/p&gt;
&lt;p&gt;
	Hier nochmal der Überblick über die ganze Serie:&lt;br /&gt;
	•&amp;nbsp;&amp;nbsp;&amp;nbsp; Folge 1: &lt;a href="http://www.it-economics.de/blog/-/blogs/legacy-code-unter-kontrolle-folge-1-vorstellung-von-jmockit?_33_redirect=http%3A%2F%2Fwww.it-economics.de%2Fblog%3Fp_p_id%3D33%26p_p_lifecycle%3D0%26p_p_state%3Dnormal%26p_p_mode%3Dview%26p_p_col_id%3Dcolumn-1%26p_p_col_pos%3D1%26p_p_col_count%3D2"&gt;Vorstellung von JMockit&lt;/a&gt;&lt;br /&gt;
	•&amp;nbsp;&amp;nbsp;&amp;nbsp; Folge 2: &lt;a href="http://www.it-economics.de/blog/-/blogs/legacy-code-unter-kontrolle-folge-2-die-grundkonzepte-von-jmockit"&gt;Die Grundkonzepte von JMockit. Ein erster Test, der ohne JMockit nur schwer zu erstellen wäre.&lt;/a&gt;&lt;br /&gt;
	•&amp;nbsp;&amp;nbsp; &amp;nbsp;Folge 3: Zwei schwierige Fälle aus der Praxis: Ein Schaltjahresproblem und ein Singleton-Factory-Lindwurm.&lt;/p&gt;
&lt;h3&gt;
	Recap: JMockit-Mocks&lt;/h3&gt;
&lt;p&gt;
	Das Grundprinzip eines JMockit-Mocks ist das Folgende: Deklariert man mittels der Annotation &lt;code&gt;@Mocked&lt;/code&gt; eine Klasse als Mock, so wird ab sofort an keiner Stelle im System mehr der Originalcode ausgeführt. Alle Klassenmethoden sind ebenso gemockt wie alle Konstruktoren und alle Instanzmethoden. Dies gilt für neu erzeugte Instanzen ebenso wie für alle bereits im System existierenden Instanzen! Alle non-void-Methoden geben Standard-Werte wie &lt;code&gt;0, false, null,&lt;/code&gt; etc. zurück.&lt;br /&gt;
	Nun kann man Expectations formulieren, d.h. Erwartungen, dass das System-Under-Test (SUT) bestimmte Methoden auf einem solchen Mock aufruft. Dies ist wichtig für verhaltensbasierte Tests.&lt;br /&gt;
	&lt;br /&gt;
	Und man kann mittels NonStrictExpectations vorgeben, dass bestimmte Methoden eines Mocks andere als die Standard-Werte zurückgeben, ohne dass damit eine Erwartung verbunden wäre, dass bzw. in welcher Reihenfolge die Aufrufe erfolgen. Dies wird vor allem eingesetzt, um das SUT aus seiner Umgebung herauszulösen und in einen testbaren Zustand zu versetzen.&lt;br /&gt;
	&lt;br /&gt;
	Mit dieser Funktionalität kann man nun verblüffende Tests schreiben, die ohne JMockit nur möglich wären, indem man zuerst das zu testende System anpasst – eine Änderung, die in einem Legacy-System ohne ein Sicherheitsnetz aus Unit-Tests recht heikel sein kann.&lt;/p&gt;
&lt;h3&gt;
	As Time goes by …&lt;/h3&gt;
&lt;p&gt;
	Mein erstes Beispiel ist die Hilfsklasse &lt;code&gt;DateUtility&lt;/code&gt;, die unter anderem auch die Zahl der Tage im aktuellen Monat zurückgibt. Zu testen ist nun, ob das auch im Februar eines Schaltjahres korrekt funktioniert. Leider verwendet die Routine &lt;code&gt;lastDayOfMonth()&lt;/code&gt; einen direkten Aufruf von &lt;code&gt;new Date()&lt;/code&gt; (bzw. inzwischen &lt;code&gt;new GregorianCalendar()&lt;/code&gt;), um das aktuelle Datum zu ermitteln. Und die Systemzeit lässt sich von Java aus nicht einfach setzen. Vorgefunden habe ich etwa folgenden Test:&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public void lastDayOfMonthUsesLeapYear()&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (new Date().getMonth() == 1) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (DateUtility.isLeapYear()) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assertEquals(29, DateUtility.lastDayOfMonth());&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Auf meinen Hinweis, dass der Schaltjahrestest aber nur alle 4 Jahre einen Monat lang ausgeführt wird, bekam ich vom Entwickler zur Antwort: „Tja, besser als gar nichts. Anders lässt sich das nicht testen!“&lt;br /&gt;
	&lt;br /&gt;
	Gemeinsam haben wir dann unter Einsatz von JMockit folgende Tests erarbeitet:&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;code&gt; private static Calendar FEB_01_2012 = new GregorianCalendar(2012, FEBRUARY, 1);&lt;br /&gt;
	&amp;nbsp; private static Calendar FEB_01_2009 = new GregorianCalendar(2009, FEBRUARY, 1);&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public void leapYearFebruaryHas29Days()&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; modifySystemDate(FEB_01_2012);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assertEquals(29, DateUtility.lastDayOfMonth());&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public void nonLeapYearFebruaryHas28Days()&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; modifySystemDate(FEB_01_2009);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assertEquals(28, DateUtility.lastDayOfMonth());&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; private void modifySystemDate(final Calendar newDate)&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new NonStrictExpectations(System.class) {{&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.currentTimeMillis(); result = newDate.getTimeInMillis();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }};&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Der Test macht sich zunutze, dass &lt;code&gt;Date&lt;/code&gt; und &lt;code&gt;GregorianCalendar&lt;/code&gt; intern die Methode &lt;code&gt;System.currentTimeMillis()&lt;/code&gt; aufrufen, um die aktuelle Zeit zu bestimmen. In der privaten Hilfsmethode &lt;code&gt;modifySystemDate(…) &lt;/code&gt;wird daher die Klasse System teilweise gemockt. Siehe dazu auch im JMockit-Tutorial den Abschnitt „4.14.2 Dynamic partial mocking“:&lt;br /&gt;
	&lt;a href="http://jmockit.googlecode.com/svn/trunk/www/tutorial/BehaviorBasedTesting.html#dynamicPartial"&gt;http://jmockit.googlecode.com/svn/trunk/www/tutorial/BehaviorBasedTesting.html#dynamicPartial&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
	Von Fabriken und Lindwürmern&lt;/h3&gt;
&lt;p&gt;
	Ein anderes, in Legacy Code oft zu findendes Konstrukt ist das Factory-Singleton, gerne kombiniert mit einem Getter-Lindwurm. In meinem aktuellen Projekt findet sich z.B. an einer Stelle der Aufruf&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;File dir = RuntimeFactory.getInstance().getFileSystemUtilities().getUserHomeDirectory();&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Hier der relevante Ausschnitt aus dem Code von RuntimeFactory:&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;public class RuntimeFactory {&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;private static RuntimeFactory instance;&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public static RuntimeFactory getInstance() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (instance == null) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; instance = new RuntimeFactory();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return instance;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public FileSystemUtilities getFileSystemUtilities() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SystemProperties.getRuntimeInfo().isClient()) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return new ClientFileSystemUtilities();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return new ServerFileSystemUtilities();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
	}&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Hier fällt einem als erstes auf, dass man aufgrund des Singleton-Patterns dem SUT nicht einfach eine andere Klasse unterschieben kann. Als zweites erkennt man, dass in &lt;code&gt;getFileSystemUtilities()&lt;/code&gt;der Spaß in eine weitere Runde geht. Hier wird ermittelt, ob man sich auf einem Client befindet, und zwar mit Hilfe eines weiteren Factory-Singletons &lt;code&gt;SystemProperties&lt;/code&gt;, in das man ebenso wenig eingreifen kann.&lt;br /&gt;
	&lt;br /&gt;
	JMockit greift uns in einer solchen Situation mit einer besonderen Art von Mocks unter die Arme, sogenannten kaskadierenden Mocks. Sie unterscheiden sich von normalen Mocks nur durch ein leicht verändertes Standardverhalten bei Methoden, die Objekte liefern. Solche Methoden liefern bei einem kaskadierenden Mock nicht null, sondern ebenfalls einen kaskadierenden Mock. Und damit lässt sich nun folgende elegante Lösung stricken:&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;@Test&lt;br /&gt;
	public void checkDir()&lt;br /&gt;
	{&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; new NonStrictExpectations() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Cascading RuntimeFactory rf;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RuntimeFactory.getInstance().getFileSystemUtilities().getUserHomeDirectory();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = new File("E:\\home");&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; assertEquals("Homedir: E:\\home", new SUT().checkDir());&lt;br /&gt;
	}&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Siehe dazu auch im JMockit-Tutorial den Abschnitt „4.15 Cascading mocks“: &lt;a href="http://jmockit.googlecode.com/svn/trunk/www/tutorial/BehaviorBasedTesting.html#cascading"&gt;http://jmockit.googlecode.com/svn/trunk/www/tutorial/BehaviorBasedTesting.html#cascading&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
	Der Test ist grün, und was nun?&lt;/h3&gt;
&lt;p&gt;
	Mit JMockit findet man meiner Erfahrung nach praktisch immer auch in scheinbar untestbarem Code einen Weg, eine Unit aus dem System zu isolieren und einen Test dafür zu schreiben. Das Legacy Code Dilemma „Du musst den Code ändern, um einen Test schreiben zu können. Und du musst einen Test schreiben, um den Code ändern zu können“ lässt sich so durchbrechen.&lt;br /&gt;
	&lt;br /&gt;
	Was ist also der nächste Schritt? Das Sicherheitsnetz ist gespannt. Nun beginnt die eigentliche Arbeit! Wir ändern in kleinen Schritten den Code, so dass die Klassen und Module auch ohne „JMockit-Magie“ entkoppelt sind. In meinem zweiten Beispiel könnte das Ziel z.B. ein SUT sein, das ein &lt;code&gt;UserHomeDirectory&lt;/code&gt; oder wenigstens die &lt;code&gt;FileSystemUtilities&lt;/code&gt; per Dependency Injection gesetzt bekommt. Und ja, man kann mit JMockit auch einfach einen Mock für ein Interface erzeugen.&lt;/p&gt;
&lt;h3&gt;
	Fazit&lt;/h3&gt;
&lt;p&gt;
	Um Legacy Systeme wieder testbar und damit wartbar und erweiterbar zu machen, ist nach wie vor äußerst mühsam und langwierig. Aber JMockit kann Wege öffnen, die vorher versperrt waren, und so Alternativen zu der höchst riskanten und ebenfalls sehr teuren Komplett-Neuentwicklung ermöglichen. Das sollte meine kleine Blog-Serie verdeutlichen.&lt;br /&gt;
	&lt;br /&gt;
	Und natürlich reicht JMockit alleine nicht aus. Das Refactoring von Legacy-Systemen erfordert von Entwicklern und Architekten eine hohe technische Expertise, oft detailliertes Fachwissen, sowie große Disziplin und ein hohes Qualitätsbewusstsein. Und es verlangt ein kluges Management, das einerseits Verständnis für das schwer greifbare technische Thema hat, aber andererseits den Return-on-Invest nicht aus den Augen verliert. Gerade bei Refactoring-Maßnahmen von Legacy-Systemen ist es wichtig, Fokuspunkte und Prioritäten zu setzen, Ziele zu definieren und Fortschritte sichtbar zu machen.&lt;/p&gt;</summary>
    <dc:creator>Pascal Gugenberger</dc:creator>
    <dc:date>2011-11-07T12:20:00Z</dc:date>
  </entry>
  <entry>
    <title>Lucene und Hibernate Search</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/lucene-und-hibernate-search" />
    <author>
      <name>Quang Phung</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/lucene-und-hibernate-search</id>
    <updated>2011-10-21T12:19:00Z</updated>
    <published>2011-10-21T12:19:00Z</published>
    <summary type="html">&lt;p&gt;
	Searching oder Retrieving Information ist nach wie vor eine der wichtigsten Anforderungen in der aktuellen Entwicklung von JEE-Anwendungen. Der Content eines JEE-Projekts, bzw. einer Webanwendung wird meistens in relationalen Datenbanken gespeichert. Wie kann der Content suchfähig gemacht werden? Wie kann beim Suchen über große Datenmengen eine effiziente Performanz erreicht werden, wenn es sich hier um komplexe Texte handelt? Verwendet man den traditionellen LIKE oder JOIN Operator im SQL, konzentriert man sich auf SQL Statements und es führt dazu, dass die Persistenzschicht schnell komplex, umständlich in der Entwicklung und schwierig zu warten ist. Auf der anderen Seite ist die Transparenz des Zugriffs der Anwendung auf in der relationale Datenbank gespeicherten Content nicht möglich und es ergibt sich ein Performanceverlust bei großen Datenmengen.&lt;br /&gt;
	&lt;br /&gt;
	Um diese oben genannten Probleme zu lösen gibt es verschiedene Möglichkeiten. Die meistverwendetste Lösung ist die Kombination von Hibernate, Lucene und Hibernate Search. Um die Transparenz zu ermöglichen wird&amp;nbsp; Hibernate zur Realisierung der Persistenzschicht eingesetzt. Um die Anwendung suchfähig zu machen, werden Lucene zusammen mit Hibernate Search verwendet.&lt;br /&gt;
	&lt;br /&gt;
	Lucene ist eine von Apache Jakarta Gruppe entwickelte Open Source Bibliothek für Volltextsuche. Lucene wird in Java implementiert und bietet zahlreiche Funktionen für die Abfrage von Informationen aus Textdokumenten an.&lt;br /&gt;
	&lt;br /&gt;
	Hibernate Search ist ein Open Source Projekt, der Hibernate und Lucene verwendet, um die Volltextsuche über persistente Domänenmodelle anzubieten. Mit Hilfe von Hibernate Search kann Lucene leicht in die Hibernate Schicht integriert werden. Hibernate Search läuft über Lucene und ermöglicht die Indexierung durch Annotation über die Domänenklassen. Ohne den Einsatz von Hibernate Search müssen wir die Synchronisierung von Datenbank und Index übernehmen. Hibernate Search bietet eine explizite API an, um manuelle Indexierung oder Entfernung einer Entität von dem Index aufzurufen. Dies ist sehr hilfreich, wenn Content schon vorhanden aber noch nicht indiziert ist, welcher auf die Volltextsuche-Funktionen aber aufgefordert werden soll.&lt;br /&gt;
	&lt;br /&gt;
	Um die Integration der Volltextsuche zu realisieren müssen folgende Schritte durchgeführt werden:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Die Domänenmodell-Objekte annotieren&lt;/li&gt;
	&lt;li&gt;
		Directory Provider auswählen&lt;/li&gt;
	&lt;li&gt;
		Pfad zum Index angeben&lt;/li&gt;
	&lt;li&gt;
		Indexierung einschalten&lt;/li&gt;
	&lt;li&gt;
		Suchen&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Domänenmodell-Objekte nach dem Hinzufügen der Annotation:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=fc2086ea-cf96-4e14-a90e-dafb1790d81b&amp;amp;groupId=10458&amp;amp;t=1319200117288" style="width: 500px; height: 680px; float: left;" /&gt;&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Die Domänenmodell-Objekte annotieren&lt;/h3&gt;
&lt;p&gt;
	Jedes zu indizierende Domänenobjekt muss mit der &lt;em&gt;@Indexed&lt;/em&gt; – Annotation gekennzeichnet werden. Die &lt;em&gt;Id&lt;/em&gt; des Objekts wird als&lt;em&gt; IndexID&lt;/em&gt; mit &lt;em&gt;@DocumentId &lt;/em&gt;annotiert. Diese IndexId muss innerhalb eines Index eindeutig sein. Die Felder &lt;em&gt;Name, Vorname, Geburtsdatum, Strasse, Hausnummer&lt;/em&gt; und &lt;em&gt;PLZ&lt;/em&gt; werden mit dem Parameter&lt;em&gt; index=Index.TOKENIZED&lt;/em&gt; annotiert, damit die Inhalte dieser Felder von dem Tokenizer analysiert werden. Alle Felder werden mit dem Parameter store.NO annotiert. Der Parameter &lt;em&gt;store.NO&lt;/em&gt; gibt an, dass die indizierten Inhalte nicht im Index abgespeichert werden.&lt;br /&gt;
	&lt;br /&gt;
	Hibernate Search bietet auch an, die Beziehung 1:1, 1:n und m:n nachzuvollziehen. In diesem Fall wird in der Adresse &lt;em&gt;person&lt;/em&gt; mit der Annotation &lt;em&gt;@IndexedEmbedded&lt;/em&gt; annotiert. Dies führt dazu, dass alle in der Person zur Indizierung annotierten Felder auch mit in dem Index &lt;em&gt;Adresse&lt;/em&gt; aufgenommen.&lt;/p&gt;
&lt;h3&gt;
	Directory Provider und Pfad zum Index angeben&lt;/h3&gt;
&lt;p&gt;
	Nachdem alle Domänenmodell-Objekte mit Hibernate Search Annotation bereitgestellt werden, wird das Dateisystem als Directory Provider zur Speicherung von Index angegeben Und anschließend der Pfad zum Index. Das ist das Verzeichnis, in dem sich die Indexe aller Domänenobjekte der Anwendung befinden.&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=397c9670-35d8-4987-ab96-73f4515f6672&amp;amp;groupId=10458&amp;amp;t=1319200117290" style="width: 650px; height: 32px; float: left;" /&gt;&lt;/p&gt;
&lt;h4&gt;
	 &lt;/h4&gt;
&lt;h3&gt;
	Indexierung einschalten&lt;/h3&gt;
&lt;p&gt;
	Es ist möglich, jedes Domänenobjekt oder eine Liste von Domänenobjekten zu indizieren.&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=eeef4d13-660a-47b7-85de-7ff54b52c45c&amp;amp;groupId=10458&amp;amp;t=1319200117291" style="width: 635px; height: 297px; float: left;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Nach dem Indizieren haben wir im Ordner home/phungq/index zwei Verzeichnisse&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;. luc.bsp.entity.Person&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;. luc.bsp.entity.Adresse&lt;br /&gt;
	wobei jedes die Index Dateien enthält&lt;/p&gt;
&lt;h3&gt;
	Suchen&lt;/h3&gt;
&lt;p&gt;
	Das Suchen fängt mit der Erzeugung der&lt;em&gt; FullTextSession&lt;/em&gt; an. Danach wird der &lt;em&gt;MultiFieldQueryParser&lt;/em&gt; mit zwei Parametern initialisiert, einem Array, bestehend aus den zu suchenden Feldern, und dem Analyzer. Mit dem &lt;em&gt;MultiFieldQueryParser&lt;/em&gt; ist es möglich, mehrere Felder gleichzeitig in eine Suchanfrage zu kombinieren. Dieser Parser ruft die &lt;em&gt;parse&lt;/em&gt; Methode mit dem übergegebenem Suchmuster auf. Für das Suchmuster stehen viele Möglichkeiten der Lucene Query Syntax zur Verfügung. Anschließend wird eine Volltextsuche-Anfrage mit Hilfe der createFullTextQuery-Methode erstellt und in Form einer Hibernate-Anfrage zurückgegeben.&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=7a752071-982b-4bd9-8729-4fe53f167ae9&amp;amp;groupId=10458&amp;amp;t=1319200117291" style="width: 630px; height: 238px; float: left;" /&gt;&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	Eine Suchmaschine ist eine unverzichtbare Anforderung in der modernen JEE-Anwendung. Sie kann mit Lucene und Hibernate Search leicht in der JEE-Anwendung integriert werden. Ich persönlich finde, dass die Kombination zwischen Lucene und Hibernate Search den Entwicklern eine flexible, leicht zu implementierende und mächtige Lösung für die Volltextsuche anbietet, wenn es sich bei dem Inhalt um umfangreiche Texte handelt.&lt;br /&gt;
	&lt;br /&gt;
	Das Ziel, des in diesem Blog eingeführten Beispiels ist es zu zeigen, wie bereits in einem frühen Stadium der Implementierung eine einfache Integration der Volltextsuche mit Lucene und Hibernate Search möglich ist. Weitere Informationen sind auf folgenden Webseiten zu erhalten:&lt;br /&gt;
	&lt;br /&gt;
	Apache Lucene: &lt;a href="http://lucene.apache.org/"&gt;http://lucene.apache.org/&lt;/a&gt;&lt;br /&gt;
	Hibernate Search: http:&lt;a href="http://www.it-economics.de//www.hibernate.org/subprojects/search.html"&gt;//www.hibernate.org/subprojects/search.html&lt;/a&gt;&lt;/p&gt;</summary>
    <dc:creator>Quang Phung</dc:creator>
    <dc:date>2011-10-21T12:19:00Z</dc:date>
  </entry>
  <entry>
    <title>Legacy Code unter Kontrolle - Folge 2, Die Grundkonzepte von JMockit</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/legacy-code-unter-kontrolle-folge-2-die-grundkonzepte-von-jmockit" />
    <author>
      <name>Pascal Gugenberger</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/legacy-code-unter-kontrolle-folge-2-die-grundkonzepte-von-jmockit</id>
    <updated>2011-10-10T08:27:00Z</updated>
    <published>2011-10-10T08:27:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	In meinem letzten Blog-Eintrag habe ich erläutert, warum JMockit bei meinem aktuellen Kunden eine so wichtige Rolle spielt, wenn es darum geht, eine Legacy-Anwendung testbar zu machen und so änderbar zu halten.&lt;br /&gt;
	In der Folge 2 will ich heute darstellen, wie man konkret Unit-Tests mit JMockit schreibt und welche Konzepte dabei eine Rolle spielen. Es entsteht ein Test für eine Stück Legacy Code, das ohne JMockit nur sehr schwer zu testen wäre.&lt;/p&gt;
&lt;p&gt;
	Hier nochmal der Überblick über die ganze Serie:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Folge 1: &lt;a href="https://www.it-economics.de/blog/-/blogs/legacy-code-unter-kontrolle-folge-1-vorstellung-von-jmockit"&gt;Vorstellung von JMockit&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;
		Folge 2: Die Grundkonzepte von JMockit. Ein erster Test, der ohne JMockit nur sehr schwer zu erstellen wäre.&lt;/li&gt;
	&lt;li&gt;
		Folge 3: Zwei schwierige Fälle aus der Praxis: Ein Remote-Service-Call und eine Schaltjahresregelung.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
	Recap: Die Struktur eines Unit-Tests&lt;/h3&gt;
&lt;p&gt;
	Die meisten Unit-Tests folgen einer einfachen Struktur.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Vorbereiten des System-under-Test (SUT).&lt;/li&gt;
	&lt;li&gt;
		Aufruf der zu testenden Funktionalität im SUT&lt;/li&gt;
	&lt;li&gt;
		Prüfen, ob das erwartete Ergebnis erreicht ist.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Bei jedem der drei Schritte erwarten uns in einem Legacy-System z.T. erhebliche Herausforderungen, die aber oft mit Konzepten von JMockit zu meistern sind.&lt;/p&gt;
&lt;h3&gt;
	Schritt 1: Die Vorbereitung des SUT&lt;/h3&gt;
&lt;p&gt;
	Beginnen wir mit Schritt 1, der Vorbereitung des SUT. Hier ist als erstes zu klären, woraus das zu testende System aus Sicht des Tests überhaupt besteht. Typischerweise handelt es sich hier um eine einzelne Instanz einer Klasse. Schon die direkten „Collaborators“, die Objekte, auf die zu testende Klasse zugreift, gehören nicht mehr dazu. Sie müssen nur ihre Rolle spielen, damit das SUT wie gewünscht funktionieren kann.&lt;br /&gt;
	&lt;br /&gt;
	Daraus ergeben sich zwei Herausforderungen:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		Erzeugen einer Instanz der zu testenden Klasse&lt;/li&gt;
	&lt;li&gt;
		Diese Instanz in eine geeignete Umgebung (Kontext) einbetten, in der die zu testende Funktionalität ausführbar ist.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
	Nehmen wir als Beispiel wieder unseren hypothetischen InvoiceUpdateRecorder aus der letzten Folge. Er protokolliert neu erstelle Rechnungen und liefert unter anderem einen Report dazu. Diese Report-Erstellung, die in der Methode &lt;code&gt;getInvoiceReport&lt;/code&gt; implementiert ist, wollen wir testen. Hier der Code unseres SUT sowie eines Collaborators, der Klasse &lt;code&gt;DbConnection&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;public class InvoiceUpdateRecorder {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; private DbConnection dbConnection;&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public InvoiceUpdateRecorder()&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dbConnection = new DbConnection();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ... Viele weitere Zeilen unverständliche Initialisierung&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public String getInvoiceReport() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String result = "";&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ... Viele Zeilen unverständlicher Code&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List invoices = dbConnection.fetchAllInvoices();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (invoices.isEmpty()) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = "no invoices found";&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Ihr wollt nicht wissen, was hier alles passiert&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	}&lt;br /&gt;
	public class DbConnection {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; Connection jdbcConnection;&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public DbConnection() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;// Holen der JDBC-Connection vom globalen Connection-Manager&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jdbcConnection = JDBCConnectionManager.currentJdbcConnection();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // weiterer Initialisierungscode&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public List fetchAllInvoices() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List result = null;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // JDBC-Code, um Liste aus DB zu holen&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&lt;br /&gt;
	}&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Beginnen wir mit einem besonders einfachen Unit-Test, der prüft, ob als Report „no invoices found“ kommt, wenn die DbConnection keine Invoices liefert. Was ist also unser SUT? Offensichtlich nur die Klasse InvoiceUpdateRecorder, ohne die Klasse DbConnection. Ganz offensichtlich gehört auch nicht JDBC-Connection der DbConnection dazu und schon gar nicht Datenbank selbst mit ihren Inhalten. Beginnen wir also mit dem Schreiben unseres Tests, indem wir das SUT erzeugen:&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;@Test public void newInvoiceUpdateRecorderHasNoInvoices() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // System-Under-Test vorbereiten.&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; InvoiceUpdateRecorder recorder = new InvoiceUpdateRecorder();&lt;br /&gt;
	}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;
	Wenn wir diesen Test ausführen, wird uns sofort die (nicht einmal zu unserem SUT gehörende) Klasse&amp;nbsp; &lt;code&gt;JDBCConnectionManager &lt;/code&gt;eine eigenartige Fehlermeldung um die Ohren hauen, die besagt, dass sie nicht in einem Zustand ist, dass sie eine JDBC-Connection liefern kann. Aber was tun? Ein Blick in den Konstruktur unseres &lt;code&gt;InvoiceUpdateRecorder &lt;/code&gt;zeigt, dass dort hart kodiert eine neue Instanz der Klasse &lt;code&gt;DbConnection&lt;/code&gt; erzeugt wird. Und diese wiederum enthält im Konstruktor den fatalen Aufruf eines globalen Singletons, das uns entweder eine gültige JDBC-Connection oder eine Exception liefert. Wenn wir den Code des SUT nicht ändern wollen, scheitert bereits hier unser Versuch, einen Unit-Test zu schreiben. Und wir haben die zu testende Funktionalität noch nicht einmal aufgerufen!&lt;/p&gt;
&lt;h3&gt;
	Wie kann uns nun JMockit weiterhelfen?&lt;/h3&gt;
&lt;p&gt;
	Das meiner Meinung nach wichtigste Konzept von JMockit ist wird über das sogenannte &lt;em&gt;Expectations API&lt;/em&gt; bereitgestellt. Damit kann man bestimmte Typen zu &lt;em&gt;gemockten Typen&lt;/em&gt; zu machen. Jeder Referenz-Typ kommt dafür in Frage, also konkrete Klassen (wie DbConnection) und Interfaces (wie z.B. List), aber auch abstrakte oder finale Klassen (wie z.B. java.lang.System), nicht aber primitive Typen wie boolean oder int.&lt;br /&gt;
	&lt;br /&gt;
	Wenn ein Typ gemockt ist, werden alle Aufrufe aller seiner Methoden abgefangen. Es wird nicht die Originalimplementierung ausgeführt (sofern es eine gibt). Stattdessen tut der Mock einfach nichts, allenfalls liefert er noch einen Wert zurück. Standardmäßig ist das null, 0, false, EMPTY_LIST, … . Und das funktioniert für ALLE Methoden, also auch für als private, static, final oder native markierte Methoden, für geerbte Methoden, und auch für die Konstruktoren (die nun Mocks liefern). Und es funktioniert auch für alle Instanzen des Typs, für zum Zeitpunkt des Mockens bereits bestehende und für später erzeugte.&lt;br /&gt;
	&lt;br /&gt;
	Die Deklaration eines Typs als „gemockt“ geschieht durch die Angabe der Annotation &lt;code&gt;@Mocked&lt;/code&gt; vor einer Variablendefinition. Das ist nicht überall, sondern nur an folgenden Stellen erlaubt, die sich durch den Gültigkeitsbereich des Mocks unterscheiden:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		Bei der Definition einer Instanzvariable in der Testklasse.&lt;/li&gt;
	&lt;li&gt;
		Bei der Deklaration eines Parameters für eine Testmethode (ja, das geht!).&lt;/li&gt;
	&lt;li&gt;
		Innerhalb eines &lt;em&gt;Expectation Blocks&lt;/em&gt; in einer Testmethode. Das ist die Variante, die uns in unserem Beispiel weiterhilft.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
	Das Expectations API deckt zwei wichtige Aufgaben ab: erstens man kann Erwartungen an die Interaktion zwischen dem SUT und seiner Umgebung formulieren, also etwa „Ich erwarte, dass im Test ein Konstruktoraufruf erfolgt und dann genau dieser weitere Methodenaufruf, wobei übrigens folgender Wert zurückgegeben werden soll“. Aufrufe anderer Methoden oder eine falsche Aufrufreihenfolge werden dabei als Fehler angesehen. Man verwendet für die Definition dieser Erwartungen Expectation Blocks des Typs &lt;code&gt;Expectation&lt;/code&gt;s. Daher stammt auch der Name für das API. Zweitens man kann lediglich Rückgabewerte für Methoden vorgeben. Ob überhaupt, wie oft, und in welcher Reihenfolge die Methoden aufgerufen werden, ist dabei unerheblich. Für die Definition solcher Erwartungen an das Verhalten des Mocks verwendet man Blocks des Typs &lt;code&gt;NonStrictExpectations&lt;/code&gt;. Diese zweite Aufgabe tritt nach meiner Erfahrung wesentlich häufiger auf als die erste. Auch in unserem Beispiel hilft uns solch ein &lt;code&gt;NonStrictExpectations&lt;/code&gt; Block weiter.&lt;/p&gt;
&lt;h3&gt;
	Die Syntax von Expectation Blocks&lt;/h3&gt;
&lt;p&gt;
	Was hat es nun mit diesen Blocks auf sich? Schauen wir uns den Block an, den wir in unserem Beispiel benötigen:&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;@Test public void newInvoiceUpdateRecorderHasNoInvoices() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; …&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; new NonStrictExpectations() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Mocked DbConnection anyDbConnectionMock;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; anyDbConnectionMock.fetchAllInvoices(); result = Collections.EMPTY_LIST;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }};&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; …&lt;br /&gt;
	}&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Syntaktisch haben wir hier die Erzeugung einer Instanz einer anonymen Subklasse der Klasse Expectations vor uns, die eine Instanzvariable und einen statischen Initializer enthält. Die so erzeugte Instanz wird dann umgehend dem Garbage Collector übergeben. Und das soll sinnvoll sein? Puh!&lt;br /&gt;
	&lt;br /&gt;
	Für JMockit bedeutet dieser Block (grob gesagt):&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Der Typ &lt;code&gt;DbConnection&lt;/code&gt; ist für den Rest der Ausführung der Testmethode gemockt. D.h., ALLE Methodenaufrufe auf bereits existierenden Instanzen in der Software greifen nun nicht mehr auf den Original-Code zu, sondern auf den Mock. Ein &lt;code&gt;new DbConnection&lt;/code&gt;() Aufruf erzeugt nun einen Mock. Statische Methoden in &lt;code&gt;DbConnection&lt;/code&gt; sind ebenfalls gemockt.&lt;/li&gt;
	&lt;li&gt;
		Der Mock ist nicht-strikt. Aufrufe aller seiner Methoden sind im Rest des Tests beliebig oft möglich und liefern die Standard-Werte.&lt;/li&gt;
	&lt;li&gt;
		Im Initializer befindet sich der Mock im Aufzeichnungsmodus. Aufrufe und zugehörige Rückgabewerte werden aufgezeichnet. Im Beispiel wird festgelegt, dass Aufrufe der Instanz-Methode &lt;code&gt;fetchAllInvoices(&lt;/code&gt;) immer eine leere Collection liefern sollen. Achtung: anders als z.B. bei Mockito oder EasyMock müssen diese Aufrufe NICHT unbedingt auf der Instanz &lt;code&gt;anyDbConnectionMock&lt;/code&gt; erfolgen! Jeder Aufruf, egal auf welcher Instanz, liefert nun den vorgegebenen Rückgabewert. Die Variable &lt;code&gt;anyDbConnectionMock&lt;/code&gt; ermöglicht es uns nur&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Die eigenartige Syntax hat übrigens meiner Meinung nach einige erwähnenswerte Vorteile:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Innerhalb des Initializers stehen die gemockten Aufrufe nackt ohne jegliche, die Lesbarkeit behindernde „Verzierungen“&amp;nbsp; da, also kein &lt;code&gt;when(…).thenReturn(…)&lt;/code&gt; oder &lt;code&gt;doThrow(…).when(…).…&lt;/code&gt; wie z.B. mit Mockito.&lt;/li&gt;
	&lt;li&gt;
		Die Syntax ist immer dieselbe, egal ob sich um Aufrufe von Methoden mit Rückgabe-Werten, void-Methoden, finalen Methoden oder Konstruktoren handelt.&lt;/li&gt;
	&lt;li&gt;
		In IDEs kann man den ganzen Expectations Block einfach zusammenfalten und sich so beim Lesen des Tests auf das Wesentliche konzentrieren.&lt;/li&gt;
	&lt;li&gt;
		Es ist kein zusätzliches Kommando nötig, um aus dem Aufzeichnungs- und den Abspielmodus zu kommen. Trotzdem ist der Aufzeichnunsmodus optisch und logisch deutlich getrennt vom Abspiel-Modus.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Zurück zu unserem Test, nun erweitert um den Expectations Block:&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;@Test public void newInvoiceUpdateRecorderHasNoInvoices() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // System-Under-Test vorbereiten.&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; new NonStrictExpectations() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Mocked DbConnection anyDbConnectionMock;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; anyDbConnectionMock.fetchAllInvoices(); result = Collections.EMPTY_LIST;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }};&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; InvoiceUpdateRecorder recorder = new InvoiceUpdateRecorder();&lt;br /&gt;
	}&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Nun bekommen wir beim Ausführen den gewünschten grünen Balken, da nicht mehr der Original-Konstruktor von &lt;code&gt;DbConnection&lt;/code&gt; aufgerufen wird, der den „bösen“ JDBCConnectionManager aufruft. Stattdessen wird einfach nur ein Mock erzeugt und in der Instanzvariablen &lt;code&gt;dbConnection&lt;/code&gt; von &lt;code&gt;InvoiceUpdateRecorder&lt;/code&gt; abgelegt. Damit haben wir Schritt 1, die Vorbereitung des SUT erledigt.&lt;/p&gt;
&lt;h3&gt;
	Schritt 2: Der Aufruf des SUT&lt;/h3&gt;
&lt;p&gt;
	Der zweite Schritt ist recht einfach und kurz. Wir ergänzen den Test um den Aufruf.&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;String result = recorder.getInvoiceReport();&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Manchmal muss man bei diesem Aufruf noch einen oder mehrere Parameter-Objekte in das SUT hineinreichen. Wenn diese gemockt werden müssen, genügt es nicht, den Mock innerhalb des Expectation Blocks zu definieren, sondern man muss den Mock als Parameter in die Testmethode hineinreichen, oder gleich als Instanzvariable der ganzen Testklasse definieren.&lt;/p&gt;
&lt;h3&gt;
	Schritt 3: Die Überprüfung des Ergebnisses&lt;/h3&gt;
&lt;p&gt;
	In unserem Fall ist dies einfach. Wir haben eine Funktion aufgerufen, die keine Seiteneffekte hat, sondern einfach ein Ergebnis liefert. Dieses können wir im Test prüfen, hier bereits in der neuen, eingängigeren JUnit 4-Syntax:&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;&lt;em&gt;assertThat&lt;/em&gt;(result, &lt;em&gt;is&lt;/em&gt;("no invoices found"));&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;
	Unser Test sieht damit so aus:&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;@Test public void newInvoiceUpdateRecorderHasNoInvoices() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // Schritt 1: System-Under-Test vorbereiten.&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; new NonStrictExpectations() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Mocked DbConnection anyDbConnectionMock;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; anyDbConnectionMock.fetchAllInvoices(); result = Collections.EMPTY_LIST;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }};&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; InvoiceUpdateRecorder recorder = new InvoiceUpdateRecorder();&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // Schritt 2: SUT aufrufen&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; String result = recorder.getInvoiceReport();&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // Schritt 3: Ergebnis prüfen&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; assertThat(result, is("no invoices found"));&lt;br /&gt;
	}&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Manchmal muss man allerdings auch die Interaktion des SUT mit seiner (typischerweise gemockten) Umgebung prüfen. Dafür setzt man entweder Expectations ein. Das führt allerdings dazu, dass man deutlich mehr Wissen über Implementationsdetails in den Test steckt. Ich habe es schon oft erlebt, dass der Test dann überspezifisch wird und fehlschlägt, wenn sich die Implementierung ändert, obwohl das Ergebnis, das ich eigentlich testen wollte, unverändert geblieben ist.&lt;br /&gt;
	&lt;br /&gt;
	Das Expectations API bietet eine Fülle weiterer Features für fast alle denkbaren Fälle an. So kann man mit Hilfe von Argument Matchers vorgeben, dass z.B. ein Aufruf einer Methode mit einem beliebigen String, der „foo“ enthält, einen bestimmten Wert zurückgeben soll. Um eine Überspezifizierung eines Tests zu vermeiden, kann man nachträglich in einem Verifications Block prüfen, dass einzelne Aufrufe, die man vorher in einem NonStrictExpectations Block ermöglicht hat, stattgefunden haben.&lt;br /&gt;
	&lt;br /&gt;
	Spiegelt sich das Ergebnis eines SUT-Aufrufs nur in einem veränderten Zustand (z.B. dem Wert der privaten Instanzvariablen &lt;code&gt;secret&lt;/code&gt;) des SUT wider, so kann man z.B. mit folgendem Code die Prüfung dennoch vornehmen:&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;String result = Deencapsulation.getField(sut, "secret");&lt;br /&gt;
	assertEquals("expected result", result);&lt;/code&gt;&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Fazit&lt;/h3&gt;
&lt;p&gt;
	Und damit sind wir auch schon am Ende der zweiten Folge meiner Blog-Einträge zum Thema JMockit angekommen. Wir haben einen einfach lesbaren Test für ein Legacy-System vorgenommen, in dem Collaborators vom SUT selbst unkontrollierbar erzeugt und verwendet werden.&amp;nbsp; Dazu haben wir das Expectations API von JMockit eingesetzt, das inzwischen so mächtig geworden ist, dass man das noch flexiblere Mockup API, mit dem man Klassen durch Mock-Klassen teilweise ersetzen kann, nur noch in absoluten Außnahmefällen zu Hilfe nehmen muss.&lt;br /&gt;
	&lt;br /&gt;
	Leider konnte ich trotz der Länge des Blogs nur an der Oberfläche des Expectation APIs kratzen. Weitere Details dazu liest man am besten nach unter &lt;a href="http://jmockit.googlecode.com/svn/trunk/www/tutorial/BehaviorBasedTesting.html"&gt;http://jmockit.googlecode.com/svn/trunk/www/tutorial/BehaviorBasedTesting.html&lt;/a&gt;.&lt;br /&gt;
	&lt;br /&gt;
	Wer sich dafür interessiert, wie JMockit sein anscheinend magisches Verhalten implementiert, der kann hier weiterforschen: es basiert auf dem Java SE5 Feature Instrumentation API (siehe &lt;a href="http://download.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html"&gt;http://download.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html&lt;/a&gt;) und nutzt intern die ASM Library (siehe &lt;a href="http://asm.ow2.org/"&gt;http://asm.ow2.org/&lt;/a&gt;), um Bytecode zur Laufzeit zu modifizieren.&lt;br /&gt;
	&lt;br /&gt;
	Im nächsten und letzten Teil werde ich dann beispielhaft einige weitere typische Problemfälle, die in Legacy-Code vorkommen, vorstellen und eine Lösung mit JMockit präsentieren, darunter Factory-Singletons, Remote-Service-Calls und eine datumsabhängige Funktionalität.&lt;br /&gt;
	&lt;br /&gt;
	 &lt;/p&gt;</summary>
    <dc:creator>Pascal Gugenberger</dc:creator>
    <dc:date>2011-10-10T08:27:00Z</dc:date>
  </entry>
  <entry>
    <title>SEPA Direct Debits</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/sepa-direct-debits" />
    <author>
      <name>Stefan Grimm</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/sepa-direct-debits</id>
    <updated>2011-09-19T11:11:00Z</updated>
    <published>2011-09-19T11:11:00Z</published>
    <summary type="html">&lt;h3&gt;
	Wer ist der Initiator&lt;/h3&gt;
&lt;p&gt;
	Auf Initiative des European Payment Council (EPC) mit Sitz in Brüssel wurde im Januar 2008 SEPA (Single EURO Payment Area) auf den Weg gebracht. Laut EPC soll seit dem Start der SEPA nicht mehr zwischen nationalen und anderen europäischen Staaten unterschieden werden.&amp;nbsp;Dieser regulative Schritt ist aus Sicht Brüssels notwendig, um einen einheitlichen Binnenmarkt zu verwirklichen und die zersplitterten nationalen Zahlungssysteme zu vereinheitlichen. In Ergänzung wurde vorab eine eigene europaweite einheitliche Kontonummer (IBAN) und Bankidentifikation (BIC) eingeführt.&lt;br /&gt;
	Das Ziel von SEPA ist vor allem die Harmonisierung der Zahlungsabwicklung von grenzüberschreitenden Zahlungen sowohl bei Überweisungen als auch Lastschriften. Dies ist eine Voraussetzung für ein effektives und kostengünstiges Settlement bei allen beteiligten Institutionen.&lt;/p&gt;
&lt;h3&gt;
	Mengengerüste und Verbreitung&lt;/h3&gt;
&lt;p&gt;
	SEPA (Single EURO Payment Area) steht für den einheitlichen Euro-Zahlungsverkehrsraum, in dem alle ausschließlichen EURO Zahlungen innerhalb der EU27 Länder, die drei Länder des übrigen europäischen Wirtschaftsraums (EWR) sowie die Schweiz und Monaco wie inländische Zahlungen behandelt werden. Kurzum für den Bereich, der für ca. 90% aller innerhalb Europas vorgenommen Zahlungen steht.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=ad89a742-34a8-4619-bd75-3b402d265006&amp;amp;groupId=10458&amp;amp;t=1316433498012" style="width: 210px; height: 281px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Seit November 2010 müssen auf Betreiben des EPC alle europäischen Banken zumindest passiv SEPA Zahlungen empfangen können. Somit ist Erreichbarkeit über SEPA im ganzen SEPA Raum gegeben.&lt;/p&gt;
&lt;h3&gt;
	&lt;br /&gt;
	Funktionsweise&lt;/h3&gt;
&lt;p&gt;
	Die Hauptverfahren innerhalb von SEPA sind neben der SEPA-Card zum einen die Anfang 2008 eingeführte SEPA-Überweisung, auch SEPA Credit Transfer (SCT) genannt, und zum anderen die 2009 eingeführte SEPA-Lastschrift, auch SEPA Direct Debit (SDD) genannt, in zwei Ausführungen:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		SDD B2B, die dem deutschen Abbuchungsauftrag entspricht (ohne Rückgabemöglichkeit, nur für Firmenkunden, Verpflichtung der Zahler-Bank, das Mandat zu prüfen)&lt;/li&gt;
	&lt;li&gt;
		SDD Core oder B2C entspricht dem Einzugsermächtigungsverfahren (mit Rückgabemöglichkeit, für Privatkunden und auch Firmen)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Für die Teilnahme an SDD muss der Händler eine eindeutige ID, z.B. für Deutschland bei der Bundesbank beantragen (https://extranet.bundesbank.de/scp/lizenz.do) und ein schriftliches oder elektronisches Mandat mit Mindestinformationen (Bank Identifier Codes (BIC), International Bank Account Number (IBAN), Mandats ID etc.) vom Schuldner erhalten. Für andere Länder kann die Creditor ID bei der jeweilgen Hausbank beantragt werden.&lt;br /&gt;
	Das Mandat hat eine Gültigkeit von 36 Monaten und verlängert sich, falls es in dem Zeitraum genutzt wird. Eine Reduzierung der schriftlichen Vorankündigung von 14 Tagen vor dem Fälligkeitstag kann der Händler mit dem Kunden vereinbaren. Im Gegensatz zum nationalen Verfahren, das eine Zahlung bei Sicht vorsieht, geht SEPA von einem festen Fälligkeitstag („Due Date“) aus, was eine bessere Liquiditätsplanung ermöglicht.&amp;nbsp; Im Folgenden ist ein papierhaftes Beispiel Mandat gezeigt. Dieses kann aber auch optisch vom jeweiligen Händler verändert werden muss aber bestimmte Mindestinformationen vorweisen.&lt;/p&gt;
&lt;p&gt;
	SEPA basiert auf dem Creditor Mandate Flow (CDF), der im Gegensatz zu den Gepflogenheiten südlicher Euroteilnehmern (Debtor Mandate Flow (DMF), sehr dem deutschen Verfahren ähnelt, bei dem der Gläubiger der Initiator und Verwalter der bislang papierhaften Dokumente ist und der Kunde nach Kauf ein papierhaftes Mandat dem Gläubiger zuschicken muss.&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://www.it-economics.de/image/image_gallery?uuid=30288a23-f6ca-4b17-ba9f-00e7640bfcab&amp;amp;groupId=10458&amp;amp;t=1325676509772" target="_blank"&gt;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=30288a23-f6ca-4b17-ba9f-00e7640bfcab&amp;amp;groupId=10458&amp;amp;t=1316433498017" style="width: 210px; height: 334px;" /&gt;&lt;/a&gt;&lt;a href="http://www.it-economics.de/image/image_gallery?uuid=2f76f90e-7559-4a30-9044-d1229d546611&amp;amp;groupId=10458&amp;amp;t=1325676509772" target="_blank"&gt;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=2f76f90e-7559-4a30-9044-d1229d546611&amp;amp;groupId=10458&amp;amp;t=1316433498022" style="width: 210px; height: 269px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	Für das e-Payment im Rahmen eine e-Commerce Handels ist dieses Verfahren nur sehr bedingt geeignet. Daher wurde 2009 ein sogenanntes e-Mandate als Additional Optional Service (AOS) vom EPC veröffentlicht, das erst die Eignung von SEPA für den e-Commerce Handel schaffte. Daher wird im Weiteren vor allem in diesem Blog das e-Mandate Verfahren näher vorgestellt.&lt;/p&gt;
&lt;p&gt;
	Das e-Mandate basiert auf dem ISO20022 XML Format und gilt sowohl für SEPA Core und B2B. Das EPC hat dazu Implementation Guidelines und ein Operating Model bereits 2009 vorgestellt.&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://www.it-economics.de/image/image_gallery?uuid=339c5e1a-0ebe-4bb8-a9fd-e23989645e9e&amp;amp;groupId=10458&amp;amp;t=1325676509772" target="_blank"&gt;&lt;img alt="" src="http://www.it-economics.de/image/image_gallery?uuid=339c5e1a-0ebe-4bb8-a9fd-e23989645e9e&amp;amp;groupId=10458&amp;amp;t=1316433498027" style="width: 400px; height: 269px; margin: 5px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="big"&gt;
	Vorstellung des Ablaufs einer e-Mandates Vergabe&lt;br /&gt;
	(Quelle: EPC e-Operating Model V1.5 31 März 2009)&lt;/p&gt;
&lt;p&gt;
	Die wesentlichen Schritte für das auf encrypted Internet Technologien angesiedelte EPC e-Operating Model bei der Generierung eines E-Mandates sind:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		Der Debtor geht auf seinem Rechner auf die Website des Creditors. Er wählt die e-Mandate Option statt z.B. Kartenzahlung. Er&amp;nbsp; bekommt eine Maske angezeigt, in der er die Pflichtinformationen eingibt (vor allem IBAN, BIC des Debtors, oder als Übergangsvorschlag noch die BLZ/Kontonummer und diese mittels eines geeigneten Services (z.B. Bankverlag) werden in IBAN/BIC transferiert)&lt;/li&gt;
	&lt;li&gt;
		Die Creditor Website erzeugt das e-Mandat und schickt dieses zum „Routing Service“ (kann von einer Bank selbst oder einem externen Dienstleister dieser Bank sein) Nach einer Überprüfung der BIC/IBAN wird mittels der angegebenen BIC der entsprechende Validation Service der Debtor Bank rausgesucht.&lt;/li&gt;
	&lt;li&gt;
		Der Routing Service schickt das e-Mandate zum sogenannten „Validation Service“ der Debtor Bank. Des Weiteren wird die Website auf die Debtor Bank Website umgeleitet.&lt;/li&gt;
	&lt;li&gt;
		Die von der Debtor Bank bereitgestellte Validation Service Website fragt den Debtor nach den Online Credentials seiner Online Kontenverbindung.&lt;/li&gt;
	&lt;li&gt;
		Dieser gibt alle Zugangsdaten ein und wird von der Bank authentifiziert.&lt;/li&gt;
	&lt;li&gt;
		Nach einer erfolgreichen Authentifizierung wird ihm das e-Mandate angezeigt und er kann es bestätigen. Ggf. kann die Debtor&amp;nbsp; Bank alle für das e-mandate fehlende Informationen als Service für den Debtor automatisch hinzufügen, die er dann nicht eingeben muss. Die Debtor Bank speichert das Mandat&lt;/li&gt;
	&lt;li&gt;
		Die Debtor Bank schickt das signierte e-Mandate an den Routing Service der Creditor Bank, schliesst ggf. die Session und leitet wieder auf die Creditor site um.&lt;/li&gt;
	&lt;li&gt;
		Anschliessend bestätigt die Creditor Website dem Debtor die erfolgreiche Bestätigung des e-Mandates und speichert das e-Mandat. Somit ist der Verkauf abgeschlossen und es kann im Folgenden eine Lastschrift eingezogen werden.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
	&lt;br /&gt;
	Rechtlicher Rahmen&lt;/h3&gt;
&lt;p&gt;
	Mit der EU-Richtlinie über Zahlungsdienste (ZAG) im Binnenmarkt (Payment Services Directive; PSD) wurde am 1. November 2009 durch das Europäische Parlament (EC) nun auch ein einheitlicher Rechtsrahmen für Eurozahlungen innerhalb der Europäischen Union geschaffen. SEPA basiert auf den Ideen der PSD und wurde vor allem auf Verbraucherschutz ausgerichtet.&lt;/p&gt;
&lt;h3&gt;
	&lt;br /&gt;
	Zusätzliche Schutzfunktionen und Absicherungen&lt;/h3&gt;
&lt;p&gt;
	Der Schuldner hat ein „no questions asked“ Käuferschutz Recht um Zahlungen innerhalb von 8 Wochen zurückzugegeben. Im Fall einer juristisch nachweislich gefälschten oder nicht vorhandenen oder authorisierten Lastschrift hat er sogar ein Recht bis zu 13 Monate nach Fälligkeitstag. Durch den Einsatz eines e-Mandates kann eine Reduzierung des Ausfallrisikos für den Händler auf 8 Wochen erreicht werden.&lt;br /&gt;
	In Deutschland ist eine sechswöchige Rückgabefrist bereits etabliert und gut akzeptiert. Daher ist die Verlängerung auf 8 Wochen eher akademisch zu sehen, da die allermeisten Rückgaben tatsächlich innerhalb der ersten fünf Tage eingehen. Eine Auswirkung durch die Verlängerung um zwei Wochen ist in Deutschland kaum zu befürchten.&lt;br /&gt;
	Der Gläubiger muss sich bei einer zentralen Institution seines Landes (z.B. Bundesbank) eine eindeutige Creditor ID besorgen, so dass für den Einkäufer gesichert ist, dass nur ein dort registrierter Gläubiger auch tatsächlich den Einzug macht.&lt;br /&gt;
	Auch wird die eindeutige Mandatsreferenznummer immer zusammen mit der Creditor ID zu einer eindeutigen Identifizierung und ggf. einer Prüfung eines e-Mandates führen. Viele Banken haben ihre Kunden vor unberechtigten Ersteinzügen durch SEPA DD geschützt in dem sie deren Konten nur auf Anforderung des Kunden freischalten. Einige Lösungen unterscheiden hierbei auch B2C oder B2B.&lt;br /&gt;
	Der Debtor Kunde hat verschiedene Möglichkeiten einzelne oder wiederkehrende Lastschriften auch vorab für bestimmte Creditoren oder bestimmte Zahlungen eines Creditors abzulehnen.&lt;/p&gt;
&lt;h3&gt;
	&lt;br /&gt;
	Kosten für SEPA&lt;/h3&gt;
&lt;p&gt;
	Mit der PSD dürfen die Banken z.B. innerhalb von SEPA nicht mehr die Gebühren für SEPA Zahlungen verlangen wie bei entsprechenden nationalen Zahlungen. Es ist stark davon auszugehen, dass SEPA für Geschäftskunden und den Handel grundsätzlich günstiger angeboten werden könnte als z.B. bei Kreditkarten oder anderen Zahlverfahren. Dies bedeutet natürlich im Umkehrschluss auch, dass die Erträge aus dem Transaction Banking vor allem im AZV im Zuge der Harmonisierung in SEPA sinken werden und durch weitere Effizienzsteigerungen aufgefangen werden müssen.&lt;br /&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Hindernisse und Risiken&lt;/h3&gt;
&lt;p&gt;
	Der Start von SEPA, und dort vor allem bei SDD, ist eher schleppend in Deutschland verlaufen, da viele Unternehmen aus Kosten- und Mandatsumstellungsgründen (Austausch aller im Bestand liegender Einzugsermächtigungen) auf den weiterhin gültigen nationalen Zahlungssystemen beharren. Gerade Versicherungen scheuen neben der Umstellung auf IBAN/BIC den immensen Aufwand. Auch das e-Mandate Verfahren erfreut sich offensichtlich derzeit keines Interesses bei den Banken noch bei den Händlern oder Einkäufern.&lt;br /&gt;
	Daher hat die EU 2010 eine Roadmap für den Ausstieg aus den nationalen Verfahren vorgestellt. Laut diesem Fahrplan sollen die letzten nationalen Überweisungen bis Ende 2012 und die letzten nationalen Lastschriften ein Jahr später aus dem Verkehr gezogen werden. Dabei setzt die EU vor allem auf staatliche und gemeinschaftliche Institutionen, die dort vorangehen sollen.&lt;br /&gt;
	Dazu kommt noch, dass die meisten kleineren Unternehmen sich noch nicht oder nur rudimentär über SEPA informiert haben oder die Auswirkungen kennen. Es wird daher erwartet, dass erst 2012/2013 viele Unternehmen ihre Systeme auf SEPA aufrüsten werden.&lt;br /&gt;
	&lt;br /&gt;
	Auch einige Banken haben die Auswirkungen von SEPA noch nicht voll erkannt oder scheuen die weiteren Investitionen. So haben sehr viele Banken nur die Grundfunktionalitäten von SEPA implementiert und sind tatsächlich nur passiv erreichbar.&lt;br /&gt;
	 &lt;/p&gt;</summary>
    <dc:creator>Stefan Grimm</dc:creator>
    <dc:date>2011-09-19T11:11:00Z</dc:date>
  </entry>
  <entry>
    <title>Legacy Code unter Kontrolle Folge 1 Vorstellung von JMockit</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/legacy-code-unter-kontrolle-folge-1-vorstellung-von-jmockit" />
    <author>
      <name>Pascal Gugenberger</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/legacy-code-unter-kontrolle-folge-1-vorstellung-von-jmockit</id>
    <updated>2011-09-06T11:19:00Z</updated>
    <published>2011-09-06T11:19:00Z</published>
    <summary type="html">&lt;p class="big"&gt;
	Bei meinem aktuellen Kunden setzen wir das Tool „JMockit“ so erfolgreich ein, dass es inzwischen einen wichtigen Platz in meiner „virtuellen Werkzeugkiste“ bekommen hat. Auch wenn sich die Entwickler in meinem Team größte Mühe gegeben haben, ordentlichen Code mit einem sauberen Design zu erstellen, so schlagen wir uns nun dennoch durch inzwischen weit über 1 Million Zeilen Java-Code, aus denen uns die Fehlentscheidungen der letzten 10 Jahre „entgegenmüffeln“. Wir kämpfen mit Legacy Code. Hier helfen uns Unit-Tests. Und JMockit spielt bei der Erstellung dieser Tests eine entscheidende Rolle.&lt;/p&gt;
&lt;p&gt;
	Da JMockit noch recht neu und unbekannt ist, möchte ich es Ihnen hier in einer lockeren Folge von Blog-Einträgen näherbringen:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Folge 1: Vorstellung?&lt;/li&gt;
	&lt;li&gt;
		Folge 2: Die Grundkonzepte von JMockit. Ein erster Test, der ohne JMockit nur sehr schwer zu erstellen wäre.&lt;/li&gt;
	&lt;li&gt;
		Folge 3: Zwei schwierige Fälle aus der Praxis: Ein Remote-Service-Call und eine Schaltjahresregelung.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
	Warum Unit-Tests für Legacy Code?&lt;/h3&gt;
&lt;p&gt;
	Michael Feathers hat in seinem meiner Meinung nach hervorragenden Buch „Working Effectively With Legacy Code“ eine wichtige Erkenntnis formuliert: es reicht nicht aus, das Degenerieren der Code-Qualität verhindern zu wollen! Dieses Bemühen wird immer unvollkommen sein. Denn trotz bester Absichten macht man gelegentlich Fehler, die sich über die Zeit ansammeln und zu einem stetigen Abnehmen der Codequalität führen. Daher gilt es, aktiv gegenzusteuern: ständig muss man Schritte hin zu einem einfacheren, verständlicheren, besser strukturierten System machen.&lt;/p&gt;
&lt;p&gt;
	Eine zentrale Technik für diese Schritte ist der Einsatz von automatisierten Regressionstests. Denn bei jeder noch so kleinen Verbesserung der Struktur muss ja sichergestellt sein, dass nicht versehentlich etwas „kaputtgemacht“&amp;nbsp; wurde. Besonders wichtig sind an dieser Stelle schnell laufende, vollautomatische Tests, die das Ein-/Ausgabeverhalten der vielen, vielen kleinen Einheiten, aus denen ein System besteht, in Isolation überprüfen, die sogenannten Unit Tests. Nach jeder kleinen Verbesserung können wir diese Tests laufen lassen und so prüfen, dass wir nicht versehentlich das Verhalten verändert haben. Ein fehlschlagender Unit Test deutet auf ein lokales, klar identifiziertes Problem in einer der Einheiten hin.&lt;/p&gt;
&lt;h3&gt;
	Das Legacy Code Dilemma&lt;/h3&gt;
&lt;p&gt;
	Nur lassen sich leider aufgrund der mangelhaften Struktur der Software die einzelnen Einheiten oft nicht in Isolation testen. Und hier beißt sich die Katze in den Schwanz: Um die Struktur mit gutem Gewissen zu verbessern, werden&amp;nbsp; Unit-Tests benötigt. Und um Unit-Tests erstellen zu können, muss erst mal die Struktur verbessert werden. Das Legacy-Code-Dilemma.&lt;/p&gt;
&lt;p&gt;
	Warum ist es denn so schwierig, Unit-Tests für Legacy Code zu schreiben? Wir haben doch inzwischen jahrelange Routine darin und außerdem komfortable Mocking-Frameworks wie EasyMock oder Mockito. Auch Unit-Tests, in denen Teile des Systems durch Platzhalter ersetzt werden, sind doch damit leicht möglich. Hier ein hypothetischer &lt;code&gt;InvoiceUpdateRecorder&lt;/code&gt;, dessen Methode &lt;code&gt;getInvoiceReport&lt;/code&gt; wir testen möchten, sowie die &lt;code&gt;DbConnection&lt;/code&gt;, die er benötigt (die Import-Statements lasse ich aus Platzgründen aus):&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt; public class InvoiceUpdateRecorder {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; private DbConnection dbConnection;&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; InvoiceUpdateRecorder(DbConnection aDbConnection)&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dbConnection = aDbConnection;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ... Viele weitere Zeilen unverständliche Initialisierung&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public String getInvoiceReport() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String result = "";&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ... Viele Zeilen unverständlicher Code&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List invoices = dbConnection.fetchAllInvoices();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (invoices.isEmpty()) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = "no invoices found";&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Ihr wollt nicht wissen, was hier alles passiert&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	}&lt;br /&gt;
	public class DbConnection {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; Connection jdbcConnection;&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public DbConnection(Connection ourJdbcConnection) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jdbcConnection = ourJdbcConnection;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // weiterer Initialisierungscode&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public List fetchAllInvoices() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List result = null;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // JDBC-Code, um Liste aus DB zu holen&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&lt;br /&gt;
	}&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Und so sähe beispielsweise eine Testmethode mit Mockito dafür aus:&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt; @Test public void newInvoiceUpdateRecorderHasNoInvoices() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Mock für benachbarte Systemkomponente erzeugen und Verhalten vorgeben&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DbConnection mockedDbConnection = mock(DbConnection.class);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when(mockedDbConnection.fetchAllInvoices()).thenReturn(Collections.EMPTY_LIST);&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // System-Under-Test erzeugen&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; InvoiceUpdateRecorder recorder = new InvoiceUpdateRecorder(mockedDbConnection);&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // SUT arbeiten lassen&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String result = recorder.getInvoiceReport();&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Ergebnis prüfen&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assertTrue(result.contains("no invoices found"));&lt;br /&gt;
	}&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Wir erzeugen einen &lt;code&gt;InvoiceUpdateRecorder&lt;/code&gt;, dem wir eine gemockte Datenbank-Verbindung untergeschieben, die immer eine leere Liste von Invoice-Objekten zurückgibt. So können wir leicht den Fall herbeigeführen, der uns interessiert, ohne tatsächlich eine Datenbank-Verbindung aufbauen zu müssen. Nachdem das SUT seine Arbeit getan hat, prüfen wir, ob das Ergebnis wie erwartet aussieht.&lt;br /&gt;
	Und in gut strukturierten Systemen, in denen sich wie in meinem Beispiel das abhängige Objekt so einfach in das SUT per Dependency Injection hineinreichen lässt, funktioniert dieser Proxy-Ansatz auch wunderbar. Leider hat er einige, im Kontext von Legacy Code besonders nachteilige Einschränkungen:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Es können&amp;nbsp; nur Abhängigkeiten des SUTs gemockt werden, die von außen (er)setzbar sind, denn irgendwie muss ja der im Test erzeugte Mock seinen Weg in das SUT finden. Oft erzeugen in Legacy-Systemen Klassen aber die Objekte, von denen sie abhängen, selbst, oder sie holen sie sich, indem sie statische Methoden konkreter Klassen aufrufen. Das Singleton-Pattern spielt hier oft eine unrühmliche Rolle.&lt;/li&gt;
	&lt;li&gt;
		Allgemein können mit dem Proxy-Ansatz statische, finale oder private Methoden, die das SUT aufruft, nicht gemockt werden.&lt;/li&gt;
	&lt;li&gt;
		Auch finale Klassen können nicht gemockt werden. Darunter sind auch viele Systemklassen, wie z.B.&lt;code&gt; java.lang.System&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
	&lt;br /&gt;
	JMockit: Das Schweizer Messer unter den Test-Tools für Legacy Code&lt;/h3&gt;
&lt;p&gt;
	JMockit bietet eine erstaunliche Alternative ohne diese Einschränkungen. Gemockt werden hier grundsätzlich Klassen und alle ihre Instanzen, egal wer sie erzeugt. Und auch wenn die Syntax anfangs etwas gewöhnungsbedürftig ist, so ist sie doch verblüffend konsistent und mächtig.&lt;br /&gt;
	Hier ein einfaches Beispiel, in dem wir einen etwas widerspenstigeren &lt;code&gt;InvoiceUpdateRecorder&lt;/code&gt; testen wollen, nämlich einen, der seine &lt;code&gt;DbConnection&lt;/code&gt; selbst erzeugt. Hier der relevante Ausschnitt aus unserem SUT:&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;public class LegacyInvoiceUpdateRecorder {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; private DbConnection dbConnection;&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public LegacyInvoiceUpdateRecorder()&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // ACHTUNG: Wir erzeugen uns die DbConnection selbst über einen Konstruktor-Aufruf!&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dbConnection = new DbConnection();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ...&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // getInvoiceReport() wie wie oben&lt;br /&gt;
	}&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	Und hier der entsprechende Test mit JMockit, der so mit Mockito nicht möglich wäre:&lt;br /&gt;
	&lt;br /&gt;
	&lt;code&gt;@Test public void newInvoiceUpdateRecorderHasNoInvoicesWithJMockit() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; new NonStrictExpectations() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Mocked DbConnection mockedDbConnection;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Liefere bei Aufrufen dieser Methode eine leere Liste&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mockedDbConnection.fetchAllInvoices(); result = Collections.EMPTY_LIST;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; }};&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // System-Under-Test erzeugen. Dieses erzeugt selbst seine DbConnection über&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // new DbConnection(), bekommt aber dank JMockit nur einen Mock.&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; LegacyInvoiceUpdateRecorder recorder = new LegacyInvoiceUpdateRecorder();&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // SUT arbeiten lassen. Dabei wird die Methode fetchAllInvoices aufgerufen&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; String result = recorder.getInvoiceReport();&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; // Ergebnis prüfen&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; assertTrue(result.contains("no invoices found"));&lt;br /&gt;
	}&lt;/code&gt;&lt;br /&gt;
	&lt;br /&gt;
	In diesem Test geschieht folgendes: Zunächst wird für die Dauer des Tests die Klasse &lt;code&gt;DbConnection&lt;/code&gt; gemockt. Alle Aufrufe von Konstruktoren von &lt;code&gt;DbConnectio&lt;/code&gt;n liefern nun Mocks. So auch der hier nicht sichtbare Aufruf innerhalb des Konstrukturs von &lt;code&gt;InvoiceUpdateRecorder&lt;/code&gt;. Außerdem liefern nun alle Aufrufe von Klassen- oder Instanzmethoden von &lt;code&gt;DbConnection&lt;/code&gt; Default-Werte: null, false, 0,… . Nur &lt;code&gt;fetchAllInvoices&lt;/code&gt;() liefert das explizit vorgegebene Ergebnis (Bitte nicht stören lassen durch die eigenartige Syntax, in der diese Vorgabe erfolgt. In der nächsten Folge dieser kleinen Serie erkläre ich, was es damit auf sich hat und warum das gar keine so schlechte Idee ist). Der Rest entspricht 1:1 dem vorigen Beispiel: wieder rufen wir das SUT auf und prüfen das Ergebnis.&lt;br /&gt;
	&lt;br /&gt;
	Für erste eigene Experimente mit JMockit empfehle ich die Lektüre des Getting-Started Artikel auf der JMockit-Homepage unter http://jmockit.googlecode.com/svn/trunk/www/gettingStarted.html.&lt;/p&gt;
&lt;h3&gt;
	&lt;br /&gt;
	Mein Fazit&lt;/h3&gt;
&lt;p&gt;
	Die Ausrede „Dieser Code ist untestbar!“ gilt mit JMockit nicht mehr. In den allermeisten Fällen lassen sich Abhängigkeiten in Java-basierten Legacy-Systemen damit aufbrechen. So war es uns in vielen Fällen möglich, die für eine verantwortliche Umstrukturierung erforderlichen Unit-Tests zu erstellen, ohne in den eigentlichen Code des SUT eingreifen zu müssen Dank JMockit&amp;nbsp; konnten wir tatsächlich den langen, mühsamen Weg aus der Legacy-Code-Hölle in Angriff nehmen.&lt;br /&gt;
	&lt;br /&gt;
	In der nächsten Folge schauen wir uns dann einige zentrale Konzepte von JMockit und seine verblüffende Syntax etwas näher an.&lt;br /&gt;
	 &lt;/p&gt;</summary>
    <dc:creator>Pascal Gugenberger</dc:creator>
    <dc:date>2011-09-06T11:19:00Z</dc:date>
  </entry>
  <entry>
    <title>Vendor Selection Process</title>
    <link rel="alternate" href="http://www.it-economics.de/blog/-/blogs/vendor-selection-process" />
    <author>
      <name>Daniel Reis</name>
    </author>
    <id>http://www.it-economics.de/blog/-/blogs/vendor-selection-process</id>
    <updated>2011-08-15T09:57:00Z</updated>
    <published>2011-08-15T09:57:00Z</published>
    <summary type="html">&lt;p&gt;
	Die Auswahl des richtigen Anbieters eines bestimmten Produkts wird in einem immer komplexer werdenden Markt zunehmend schwieriger. Glaubt man den diversen Anbietern, bieten ihre Produkte dem Kunden alle technischen Möglichkeiten und erfüllen alle nur erdenklichen Anforderungen. Zudem sind sie in der Regel robust, bieten eine innovative Architektur und sind natürlich absolut sicher. Wenn die Produkte aber bezüglich Funktionsumfang, Qualität und Stabilität alles bieten, bleibt als Differenzierungsmöglichkeit nur der Preis – oder?&lt;/p&gt;
&lt;p&gt;
	Natürlich nicht! Man muss sich allerdings die Zeit nehmen, die Produkte eingehend zu prüfen und die Angaben des Anbieters kritisch zu hinterfragen. Das ist nicht immer ganz einfach und nicht ohne einen gewissen Zeitaufwand möglich…&lt;/p&gt;
&lt;p&gt;
	Ausgehend von meinen Erfahrungen bei der Auswahl eines Gerätecontrollers für die Steuerung von automatisierten Kassentresoren und Druckern im Schalter/Kasse-Bereich von Banken, möchte ich den Auswahlprozess einmal eingehend betrachten. Dieses Beispiel eignet sich ganz gut, da es sich hierbei um keinen Massenmarkt handelt und wir bei der Betrachtung mit nicht allzu vielen Anbietern konfrontiert sind.&lt;/p&gt;
&lt;p&gt;
	Ziel unserer Voruntersuchung war der Nachweis, dass die Schalter-/Kasse-Anwendung der Bank im WAN betreibbar ist. Als zentrales Element unserer Lösungsarchitektur kristallisierte sich der Gerätetreiber der Bank heraus, über den die verschiedenen Gerätetypen angesprochen werden. Über dieses Gerät müssen nicht nur alle aktuellen und zukünftigen Geräte angesprochen werden, sondern diese auch ausfallsicher, störungsfrei und zugriffssicher betrieben werden können.&lt;/p&gt;
&lt;p&gt;
	Wie finden wir nun das zu uns passende Produkt?&lt;/p&gt;
&lt;h3&gt;
	1.Schritt: von der Evaluierung der Anforderungen zur Longlist&lt;/h3&gt;
&lt;p class="big"&gt;
	Der wichtigste Schritt und das Fundament der Untersuchung besteht zunächst darin, &lt;strong&gt;die eigenen Anforderungen aufzuschreiben und entsprechend zu gewichten&lt;/strong&gt;. Dies bringt Übersichtlichkeit und Struktur in die eigenen Gedanken und schützt davor, sich bei der späteren Entscheidung von Gefühlen leiten zu lassen. Zudem macht es den gesamten Entscheidungsprozess auch für Außenstehende transparent&lt;/p&gt;
&lt;p&gt;
	Die Anforderungen und deren Gewichtung sollten bereichsübergreifend stattfinden. Die Sichtweise eines Support-Mitarbeiters weicht unter Umständen gravierend von der eines Kollegen der IT-Sicherheit ab.&lt;/p&gt;
&lt;p&gt;
	In unserem Fall bildeten wir mit Kollegen aus den Bereichen Betrieb, IT-Sicherheit und Anwendungsentwicklung ein Team. Die erarbeiteten Kriterien hatten nicht nur differenzierte Gewichtungen, sondern beinhalteten auch klare Ausschlusskriterien.&lt;/p&gt;
&lt;p&gt;
	Mit dieser abgestimmten Liste hatten wir nun den Grundstock für eine klare Produktentscheidung gelegt. Was wir jetzt noch brauchten, war eine Aufstellung (möglichst) aller Hersteller und eine erste Bewertung auf Grundlage der Herstellerbeschreibung. Bei der Betrachtung des Marktes stellten wir fest, dass es sich – wie schon eingangs erwähnt – um keinen Massenmarkt handelt und es somit allenfalls eine Handvoll Anbieter geben würde.&lt;/p&gt;
&lt;h3&gt;
	2.Schritt: von der Longlist zur Shortlist&lt;/h3&gt;
&lt;p class="big"&gt;
	Bei einer breiteren Angebotspalette als in unserem Fall, z.B. bei CMS-Produkten, wird man bei dem Versuch, alle Anbieter auf Grundlage der eigenen Kriterien zu bewerten, schnell feststellen, dass es im Grunde zu viele Anbieter gibt. Der Zeitaufwand würde einfach zu groß werden. Es ist daher völlig legitim, bereits hier eine Vorauswahl für die Longlist zu treffen, z.B. nach Kriterien wie Bekanntheit des Produktes oder Produkt-Feedback von Kollegen.&lt;/p&gt;
&lt;p&gt;
	Diese Longlist mit Produkten und Kriterien ist jetzt systematisch abzuarbeiten. Hierzu sollten Sie alle Möglichkeiten nutzen, die Ihnen zur Verfügung stehen, z.B. Herstellerangaben (Request for Information), Internetrecherche, Feedback von Kollegen, Besuch von Messen usw.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Ziel ist es, die Liste so weit zu reduzieren, dass man die Möglichkeit hat, bei den verbliebenen Produkten in die Tiefe zu gehen.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
	Sollte Ihnen dies nicht im ersten Versuch gelingen, gehen Sie ruhig noch einmal zu Schritt 1 zurück und überprüfen Sie Ihre Kriterien. Denn manchmal ändern sich die Meinungen zu den Gewichtungen auch im Laufe des Prozesses…. Es ist sehr wichtig, dass alle Einstufungen und Entscheidungen immer gut dokumentiert sind, damit sie später noch nachvollziehbar sind. Nur eine einzige Note einzutragen, wirft später meist mehr Fragen auf als Antworten zu geben und beraubt Sie der Möglichkeit, diese noch zu ändern oder zu ergänzen.&lt;/p&gt;
&lt;p&gt;
	In unserem Fall hatten wir es in diesem Punkt denkbar einfach – es gab nur zwei Produkte und beide schienen zu passen.&lt;/p&gt;
&lt;h3&gt;
	3.Schritt: Produkttests und Workshops mit dem Hersteller&lt;/h3&gt;
&lt;p class="big"&gt;
	Ihre Liste sollte mittlerweile übersichtlicher sein, und Sie haben vermutlich auch schon ein grundsätzliches Gefühl für die Produkte. Eine Entscheidung werden Sie aber sicher auch jetzt noch nicht treffen können&lt;/p&gt;
&lt;p class="big"&gt;
	Den Herstellerangaben in deren Infoblättern kann man zwar vertrauen, muss man aber nicht… Und eine nachhaltige Entscheidung sollte auch nicht allein von Herstellerversprechen abhängig gemacht werden.&lt;/p&gt;
&lt;p class="big"&gt;
	Daher wird man nicht umhin kommen, sich das Produkt live anzuschauen, zu testen und die Herstellerangaben bewusst in Frage zu stellen.&lt;/p&gt;
&lt;p&gt;
	In unserem Fall hatten wir die beiden Anbieter zunächst jeweils zu einem ganztägigen Workshop eingeladen. Ziel war es, sowohl den Hersteller persönlich kennen zu lernen als auch dem Produkt inhaltlich näherzukommen. Hierfür wurden die Hersteller gebeten, uns entsprechende Testsysteme vor Ort zur Verfügung zu stellen.&lt;/p&gt;
&lt;p&gt;
	Spätestens in den Workshops sollte die Frage nach Referenzkunden und Ansprechpartner kommen. Ein Produkt, das am Markt erfolgreich ist, wird hier sicher glänzen können. Ist der Hersteller eher zurückhaltend mit Auskünften, sollte nachgebohrt werden. Ein Besuch beim Referenzkunden ist auf jeden Fall anzustreben.&lt;/p&gt;
&lt;p&gt;
	Die Workshops bilden meines Erachtens die Grundlage für eine erfolgreiche Produktauswahl, sie schaffen eine Kommunikationsplattform und geben auch dem Hersteller die Möglichkeit, die Anforderung des Kunden besser zu verstehen und darauf einzugehen. Sie werden aber auch hier feststellen, dass Fragezeichen bleiben werden. In unserem Fall war uns z.B. die Anbindung der Drucker nicht ausreichend geklärt – Versprechen und Zusagen der Hersteller sind zwar schön, hinterlassen bei einer Untersuchung aber immer auch ein Fragezeichen. Daher sind wir dazu übergegangen, das Produkt mit kleinen selbst gebauten Prototypen zu testen. Hierdurch erreicht man eine Konkretisierung, die einem einen deutlich tieferen Einblick in das Produkt ermöglicht.&lt;/p&gt;
&lt;p&gt;
	Am Schluss der Workshops sollte neben der fachlichen und technischen Bewertung immer auch eine grobe Kostenplanung stehen&lt;/p&gt;
&lt;p&gt;
	Folgende Ergebnisse lagen uns am Ende dieses Schritts vor:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Testergebnisse der Produkte&lt;/li&gt;
	&lt;li&gt;
		implementierte Prototypen&lt;/li&gt;
	&lt;li&gt;
		persönlicher Eindruck vom Hersteller&lt;/li&gt;
	&lt;li&gt;
		Referenzkunden&lt;/li&gt;
	&lt;li&gt;
		Einschätzung der Hersteller-API&lt;/li&gt;
	&lt;li&gt;
		Preisindikation&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
	4.Schritt: Entscheidung&lt;/h3&gt;
&lt;p class="big"&gt;
	Nachdem alle Fragen mit den Herstellern geklärt sind, muss eine Produktentscheidung gefällt werden. Auch hier sollte die Basis der Entscheidung die Anforderungsliste sein. Gehen Sie alle Anforderungen und Gewichtungen noch einmal kritisch durch&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
	In unserem Fall lagen die beiden Produkte recht nahe beieinander, beide Produkte hatten Stärken und Schwächen. Für uns war es positiv, dass wir die Entscheidung nicht selbst zu treffen hatten, sondern die Ergebnisse mit einer Empfehlung zu präsentieren hatten. Dadurch standen wir vor der Aufgabe, die Ergebnisse gegenüber einem Dritten verteidigen und auch kritischen Fragen standhalten zu müssen. Diese Situation sollte man zumindest im Hinterkopf haben.&lt;/p&gt;
&lt;p&gt;
	Ob die Entscheidung sich nun im Nachhinein als gut oder schlecht erweist, wird sich eventuell erst im Laufe der Zeit zeigen, aber mit der Erstellung einer umfangreichen Anbieterauswahl können Sie viele Probleme bereits im Vorfeld eliminieren und spätere Risiken besser managen. Für ein Risiko, das Sie kennen, können Sie entweder entsprechende Maßnahmen definieren oder das Risiko bewusst eingehen. Beides ist deutlich besser als von einem plötzlich eintretenden Risiko überrascht zu werden&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Eine Anbieterauswahl ist deutlich komplexer und aufwändiger als es im ersten Moment den Anschein hat.&lt;/strong&gt; Für zahlreiche Produkte gibt es bereits eine große Anbieterpalette mit vergleichbarem Funktionsumfang und Niveau, so dass eine Auswahl z.B. auf Basis von Herstellerangaben nicht mehr ohne Weiteres möglich ist. Wer die eigenen Anforderungen falsch oder nur ungenau gewichtet und die Produkte am Markt &lt;strong&gt;nicht im Detail prüft&lt;/strong&gt;, muss damit rechnen, dass am Ende des Auswahlprozesses &lt;strong&gt;nicht das optimale Produkt steht&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;
	Die Folgekosten dürften in diesem Fall &lt;strong&gt;deutlich höher &lt;/strong&gt;sein &lt;strong&gt;als der Aufwand für eine solide Anbieterauswahl&lt;/strong&gt;.&lt;/p&gt;</summary>
    <dc:creator>Daniel Reis</dc:creator>
    <dc:date>2011-08-15T09:57:00Z</dc:date>
  </entry>
</feed>


