﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title><![CDATA[Clean Code Developer - Seitenaktualisierungen]]></title><link>http://clean-code-developer.de/</link><atom:link href="http://clean-code-developer.de/RSS.aspx" rel="self" type="application/rss+xml" /><description><![CDATA[Zuletzt geänderte Seiten]]></description><pubDate>Thu, 23 Feb 2012 01:28:09 GMT</pubDate><generator>ScrewTurn Wiki RSS Feed Generator</generator><item><title><![CDATA[Stellenmarkt]]></title><link>http://clean-code-developer.de/Stellenmarkt.ashx</link><author>StefanR (StefanR)</author><description><![CDATA[Die Zahl der <a class="pagelink" href="Companies.ashx" title="Companies">Firmen</a>, die sich zu CCD bekennen, wächst. Und so wächst auch die Zahl der Stellen, die gezielt nach Entwicklern fragen, die CCD Prinzipien und Praktiken beherrschen.<br /><br />Um diese Tendenz zu befördern, haben alle Anbieter von Positionen für Entwickler, die ausdrücklich CCD-Kompetenz suchen, hier die Möglichkeit, ihre Stellen anzubieten. Wer mag, kann sein Stellenangebot mit einer Zeile (Stellenkurzbeschreibung, Firma, PLZ/Ort, Datum des Eintrags) und Link zu ausführlichen Informationen beschreiben.<br /><br />Die Einträge sind kostenlos und nicht plattformgebunden; es kann sich um Festanstellungen oder Projektpositionen handeln. Bedingung ist jedoch, dass gezielt CCD-Kompetenz gesucht wird.<br /><br /><sup>Der Inhalt dieser Seite wird von den Anbietern selbst gepflegt; einfach beim Wiki anmelden und los geht´s. clean-code-developer.de stellt lediglich den Raum für die Angebote zur Verfügung und hofft auf den verantwortungsvollen Umgang damit durch die Community.<br /><br />Neue Einträge sollten am besten an den Anfang gestellt werden; so sind die aktuellsten Stellenangebote immer oben.</sup><br /><br /><h2 class="separator">Aktuelle CCD-Stellenangebote<a class="headeranchor" id="Aktuelle_CCD-Stellenangebote_0" href="#Aktuelle_CCD-Stellenangebote_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><ul><li><a class="externallink" href="http://www.heiler.de/germany/unternehmen/Entwicklung_JavaDeveloper_Architect.php" title="Senior Java Developer / Software Architect (m/w)" target="_blank">Senior Java Developer / Software Architect (m/w)</a>, Heiler Software AG, Stuttgart/Karlsruhe, 06.02.2012</li><li><a class="externallink" href="http://www.stellen-online.de/index.php/startseite/inserat/software-entwickler-mw-karlsruhe-legodo-ag-21973.html" title="Software-Entwickler (m/w)" target="_blank">Software-Entwickler (m/w)</a>, legodo, Karslruhe, 21.12.2011</li><li><a class="externallink" href="https://www.xing.com/net/net_entwicklung/stellenanzeigen-und-projektkooperationen-7831/softwareentwickler-net-fur-standort-berlin-gesucht-37380222/37380222/" title="Softwareentwickler .NET für Standort Berlin gesucht" target="_blank">Softwareentwickler .NET für Standort Berlin gesucht</a>, travelwindow, Berlin, 5.7.2011</li><li><a class="externallink" href="http://www.mycsharp.de/wbb2/thread.php?threadid=95756" title="Clean Code Developer (.NET/ASP.NET MVC/JavaScript) (m/w)" target="_blank">Clean Code Developer (.NET/ASP.NET MVC/JavaScript) (m/w)</a>, dff-solutions GmbH, Göttingen, 20.05.2011</li><li><a class="externallink" href="http://www.generic.de/de/company/career/jobs/ccc_developer.aspx" title="Clean Code Developer (.NET) (m/w)" target="_blank">Clean Code Developer (.NET) (m/w)</a>, generic.de software technologies AG, Karlsruhe, 9.5.2011</li><li><a class="externallink" href="http://www.web-arts.com/backend-entwickler.html" title="Backend-Entwickler (m/w) Shops und Webportale" target="_blank">Backend-Entwickler (m/w) Shops und Webportale</a>, Web Arts AG, Bad Homburg, 16.4.2011</li><li><a class="externallink" href="http://www.indeca.de/inhalt/cleancodedeveloper.aspx" title="Clean Code Developer (.NET) (m/w) für Leipzig" target="_blank">Clean Code Developer (.NET) (m/w) für Leipzig</a>, INDECA GmbH, Heilbronn, 4.4.2011<br /></li></ul>
]]></description><pubDate>Mon, 06 Feb 2012 13:09:12 GMT</pubDate><guid isPermaLink="false">72BE5F4AA17110B3FE946315FD409D11</guid></item><item><title><![CDATA[Rolle]]></title><link>http://clean-code-developer.de/Rolle.ashx</link><author>Stefan Lieser (slieser)</author><description><![CDATA[<h1 class="separator">Rolle der CCD-Armbandträger<a class="headeranchor" id="Rolle_der_CCD-Armbandträger_0" href="#Rolle_der_CCD-Armbandträger_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
Liste der Träger von CCD-Armbändern mit ihren Kontakt-Daten. Eingetragen wird, <a class="pagelink" href="Armb%c3%a4nder.ashx" title="Das Clean Code Developer Armband">wer bei uns ein CCD-Armband bestellt</a>. Wer nicht gelistet werden möchte, sage uns bitte Bescheid. Schade wäre das aber, denn jeder, der sich öffentlich zum <a class="pagelink" href="Wertesystem.ashx" title="Wertesystem">CCD-Wertesystem</a> bekennt, hilft unserer Branche ein Stück weiter auf dem Weg zu mehr Professionalität.<br /><br /><ol><li>Stefan Lieser</li><li>Ralf Westphal</li><li>Erik Bollow</li><li>Daniel Bloch</li><li>Benjamin Artmann</li><li>Christian Pappert</li><li>Stefan Edlich</li><li>Mario Röcher</li><li>Kai Gloth</li><li>Sebastian Gingter</li><li>Bernd Hengelein</li><li>Albert Weinert</li><li>Bastian Waidelich</li><li>Sebastian Stehle</li><li>Laurin Stoll</li><li>Daniel Meier</li><li>Boas Enkler</li><li>Mathias Raacke</li><li>Alexander Zeitler</li><li>Christian Deger</li><li>Sebastian Jancke</li><li>Larysa Visengeriyeva</li><li>Stefan Wittke</li><li>Christian Kesselheim</li><li>Christoph Muchalla</li><li>Rainer Schuster</li><li>Sascha Hennen</li><li>Thomas Mentzel</li><li>Dennis Traub</li><li>Giuliano Di Pasquale</li><li>Volker Riecken</li><li>Steffen Forkmann</li><li>Daniel Karstaedt</li><li>Christian Schmidt</li><li>Thomas Hasler</li><li>Markus Gallagher</li><li>Adrian Weidermann</li><li>Harry Pfleger</li><li>Michael Schuler</li><li>Holger Detering</li><li>Kai Timmermann</li><li>Ulf Fischer</li><li>Sandro Ciervo</li><li>Clivaz Olivier</li><li>Gregor Biswanger</li><li>Christian Kesselheim</li><li>Andreas Kaczmarek</li><li>Lukas Burri</li><li>Ingmar Schaefer</li><li>Sebastian Lehman</li><li>Wolfgang Haese</li><li>Robert Niemann</li><li>Ronald Dathe</li><li>Ronny Kretzmann</li><li>Andy Zimmermann</li><li>Jan Eisner</li><li>Peter Rinas</li><li>Toni Geyer</li><li>Oliver Boeff</li><li>Nils Steenbock</li><li>Florian Kiesl</li><li>Martin Hachenberg</li><li>Ronald Bouras</li><li>Markus Stoeger</li><li>Thomas Vogel</li><li>Falk Atmanspacher</li><li>Daniel Teubner</li><li>Rolf Katt</li><li>Martin Uitz</li><li>Soenke Schwenk</li><li>Stefan Rösch</li><li>Bodo Sander</li><li>Andreas Caspers</li><li>Klaus J. Stadlbauer</li><li>Andreas J. Wurzer</li><li>Bernhard Sillipp</li><li>Bernd Liesinger</li><li>Ivo Kremliczka</li><li>Andreas Bräsen</li><li>Philipp Koster</li><li>Pawel Tscherkaschin</li><li>Christian Schultze</li><li>Daniel Czerwonk</li><li>Peter Dietz</li><li>Klaas Kersting</li><li>Marcel Hoyer</li><li>Boris Nicolai</li><li>Thomas Lüera</li><li>Markus Eggers</li><li>Pawel Tscherkaschin</li><li>Christian Jacob</li><li>Adrian Weidermann</li><li>Dennis Heckert</li><li>Andreas Linden</li><li>Nils Wloka</li><li>Volker von Einem</li><li>Rudolf Batt</li><li>Manuel Beetz</li><li>Johann-Georg Vogelhuber</li><li>Klemens Schwarz</li><li>Carsten Schaefer</li><li>Norbert Baum</li><li>Michael Bohn</li><li>Martin Hoeft</li><li>Sergey Shishkin</li><li>Adrian Weidermann</li><li>Alexander Stuckenholz</li><li>Lars Kaufmann</li><li>Andreas Rademacher</li><li>Sozial Software GmbH</li><li>Yves Däschle</li><li>Henning Krapoth</li><li>Frank Gnad</li><li>Thomas Mutzl</li><li>Johannes Hoppe</li><li>Patrick Joseph</li><li>Daniel Trinter</li><li>Frank Huster</li><li>Felix Deierlein</li><li>Harald Schlindwein</li><li>Olaf Potratz</li><li>Christoph Faustein</li><li>Christian Raschka</li><li>Marcel Eppel</li><li>Martin Schäffner</li><li>Jürgen Hofmann</li><li>Klaus Backes</li><li>Christian Schultze</li><li>Christian Kolb</li><li>Martin Hey</li><li>Andreas Schlapsi</li><li>Andre Fleischer</li><li>Daniel Friedrich</li><li>Andreas Glunz</li><li>Jürgen Gutsch</li><li>Brigitte Kiesenhofer</li><li>Claus Riedel</li><li>Simon Rückert</li><li>Mirko Dobermann</li><li>Timo Pijnappel</li><li>Kai Simons</li><li>Kristian Herpel</li><li>Stephen Price</li><li>Andreas Figge</li><li>Michael Speer</li><li>Randolf Sitz</li><li>Uwe Grunwald</li><li>Gunnar Wendt</li><li>Martin Meier</li><li>Jennifer Siebigteroth</li><li>Dirk Richter</li><li>Andreas Heil</li><li>Tim Hans</li><li>Tilo Renz</li><li>Markus Terbrüggen</li><li>Florian Schwarz</li><li>Alexander Mühlbauer</li><li>Marco Walz</li><li>Georg Winkelhofer</li><li>Martin Schäffner</li><li>Martin Schäffner</li><li>Michael Piendl</li><li>Matthias Bilger</li><li>Andreas Patock</li><li>Thomas Krause</li><li>Nils Schmädeke</li><li>Jan Nonnen</li><li>Joachim Karrer</li><li>Thomas Gröner</li><li>Stefan Schnietz</li><li>Oliver Paulus</li><li>Sebastian Edelmeier</li><li>Dirk Helbig</li><li>Peter Kostros</li><li>Ramon Zöllner</li><li>Ole Trenner</li><li>Mario Mazilescu</li><li>Michael Lücke</li><li>Benjamin Hofmann</li><li>Bernhard Götz</li><li>William Schick</li><li>Stefan Poggenpohl</li><li>Alexander Esser</li><li>Kai Bausch</li><li>Manuel Dejonghe</li><li>Arne Klein</li><li>Carl-Christian Müller</li><li>Beat Fluri</li><li>Soner Akdemir</li><li>Louis Bernath</li><li>Pascal Ullrich</li><li>Michael Hirst</li><li>Andreas Neuenschwander</li><li>Martin Eckardt</li><li>Daniel Lindemann</li><li>Florian Finke</li><li>Andreas Simon</li><li>Reguel Wermelinger</li><li>Frank Endriss</li><li>Marc Knaup</li><li>Robert Rößger</li><li>Thomas Steglich</li><li>Tomislav Matas</li><li>Andreas Kotes</li><li>Timo Lotterbach</li><li>Manuel Klimek</li><li>Jan Rüdiger</li><li>Volker Richter</li><li>Heiner Schriever</li><li>Ralf Freischlag</li><li>Jürgen Hoheisel</li><li>Fabian Busse</li><li>André Röhlk</li><li>Nicolas Golubovic</li><li>Markus John</li><li>Julian Ruppel</li><li>Christian Caroli</li><li>Jörg Hösel</li><li>Christian Bruns</li><li>Matthias Hammer</li><li>Gregor Karzelek</li><li>Alexander Bouz</li><li>Peter Schaefer-Hutter</li><li>Uwe Emmrich-Kiessling</li><li>Andreas Winkler</li><li>Philipp Buergin</li><li>Kristof Zerbe</li><li>Thomas Woehlke</li><li>Christian Marchl</li><li>Peter Kofler</li><li>Robert Janzen</li><li>Andre Maucher</li><li>Florian Feith</li><li>Uwe Klawitter</li><li>Manfred Wolff</li><li>Sebastian Ziebell</li><li>Michael Fuchs</li><li>Alexander Fürstenau</li><li>Ralf Freischlag</li><li>Jan Schäfer</li><li>Alex Habermann</li><li>Lars Guse</li><li>Rainhard Mösl</li><li>Kai Thiele</li><li>Albrecht Wöß</li><li>Stephan Diezinger</li><li>Axel Marx</li><li>Erwin Haese</li><li>Marc-André Möller</li><li>Stoll Laurin</li><li>Uwe Zimmermann</li><li>Christoph Pater</li><li>Christian Burri</li><li>Markus Knittig</li><li>Daniel Hemmerling</li><li>Hans-Theo Jungeblut</li><li>Christian Vogt</li><li>Michael Paetzold</li><li>Norbert Wellnitz</li><li>Stefan Baier</li><li>Rene Kueppers</li><li>Amancio Bouza Liste</li><li>Alexander Müller</li><li>Sebastian Hempel</li><li>Hozelito Vajcek</li><li>Sebastian Hardt</li><li>Dirk Janssen</li><li>Murat Knecht</li><li>Andreas Sachs</li><li>André Weichert</li><li>Michael Topf</li><li>Torsten Strauch</li><li>Ralf Abramowitsch</li><li>Thomas Zeman</li><li>Raffael Spirig</li><li>Markus Harzdorf</li><li>Manfred Specht</li><li>Stefan Matyba</li><li>Stefan Knippenberg</li><li>Jürgen Gruber</li><li>Manuel Naujoks</li><li>Rainer Pirsch</li><li>Daniel Weinand</li><li>Wilfried Hahn</li><li>Markus Degen</li><li>Christian Hauß</li><li>Helmut Hechelbauer</li><li>Andreas Volk</li><li>Matthias Fuchs</li><li>Markus Wellmann</li><li>Ingo Ahrens</li><li>Carsten Ringe</li><li>Erik Zühlke</li><li>Timo Wagner</li><li>Sebastian Daser</li><li>Thomas Papendieck</li><li>Bert Speckels</li><li>Marinho Tobolla</li><li>Thomas Schedler</li><li>Mirko Sykorra</li><li>Stefan Böhm</li><li>Rick-Rainer Ludwig</li><li>Thomas Klute</li><li>Ronald Höllwarth</li><li>Daniel Leidisch</li><li>Manuel Wagner</li><li>Robert Kosten</li><li>Martin Kortstiege</li><li>Gerhard Hansch</li><li>Michael Schneider</li><li>Uwe Vigano</li><li>Sven Bischoff</li><li>Erik Biermann</li><li>Florian Schulz</li><li>Gerhard Kerl</li><li>Oezcan Acar</li><li>Marcel Besancon</li><li>Thomas Regner</li><li>Jürgen Stephan</li><li>Erik Heim</li><li>Dirk Pass</li><li>Marco Bellavia</li><li>Matthias Boldt</li><li>Klaus Fleerkötter</li><li>Thomas Weber</li><li>Ole Bulbuk</li><li>philipp grathwohl</li><li>Tobias Geisler</li><li>Nicolai Braszka</li><li>Patrick Ungeheuer</li><li>Markus Burger</li><li>Wolfgang Stamm</li><li>Stefan Drzazga</li><li>Markus Maier</li><li>Christian Albert</li><li>Maximilian Hoecker</li><li>Ernst Satzer</li><li>Jens Vogel</li><li>Michael Spörri</li><li>Felix Hoff</li><li>Michael Quenzer</li><li>Lutz Wedler</li><li>Benjamin Lilienthal</li><li>Oliver Abraham</li><li>Henning Scheibner</li><li>CHRISTIAN GOETZ</li><li>Nina Kaminski</li><li>Peter Guerra</li><li>Udo Trappe</li><li>Timon Schubert</li><li>Jens-Uwe Gaspar</li><li>Fridtjof Ahlswede</li><li>Andreas Urban</li><li>Robin Gressmann</li><li>Stefan Bachmann</li><li>Carsten Eichelberger</li><li>Stefan Wimmer</li><li>Maik Vlcek</li><li>Christian Kasparek</li><li>Peter Conrad</li><li>Matthias Kling</li><li>Michael Oppel</li><li>Martin Blume</li><li>Konrad Mattheis</li><li>Dominik Schiefer</li><li>Tilmann Kuhn</li><li>Thomas Enßner</li><li>Robert Labudda</li><li>Thomas Frase</li><li>Robert Spielmann</li><li>Andre Dierker</li><li>Sebastian Will</li><li>Wolfgang Gottschalk</li><li>Sebastian Meisner</li><li>Ekkehard Hess</li><li>Thomas Lattner</li><li>Andreas Widmaier</li><li>Robert Bedner</li><li>Stephan Roth</li><li>Johannes Stammel</li><li>fikre leguesse</li><li>BJOERN WILDENHAIN</li><li>Marc Becker</li><li>Matthias Jürgens</li><li>Thomas Hoeth</li><li>Jan Lorenz</li><li>Silvio Katzmann</li><li>Bernd-Christoph Schwede</li><li>Mirko Schneider</li><li>Thomas Tym</li><li>Uwe Zimmermann</li><li>Marc Bredt</li><li>Pierre Dedy</li><li>Peter Lorenz</li><li>Gareth Marshall</li><li>Martin Talamona</li><li>Matthias Laug</li><li>Peter Lech</li><li>Rolf Draether</li><li>Jens Burmeister</li><li>Sven Muhle</li><li>Frank Budwillat</li><li>Martin Monsorno</li><li>Robin Parker</li><li>Karsten Korte</li><li>Florian Geyer</li><li>Michael Winter</li><li>Tobias Rauche</li><li>Cédric Menzi</li><li>Thomas Schulte</li><li>Christoph Hornfischer</li><li>Horst Gaussmann</li><li>Golo Roden</li><li>Kai Jung</li><li>Roman Maeder</li><li>Marcell Spies</li><li>Christian Andersen</li><li>Marc Beierlein</li><li>Christian Polonio</li><li>Peter Breuer</li><li>Michaela Hofmann</li><li>Timo Müller</li><li>Markus Mayerle</li><li>Marius Schulz</li><li>Andre Krüger</li><li>Martin Blankenstein</li><li>Kai Reul</li><li>Christoph Luehr</li><li>Daniel Wurst</li><li>Michael Damm</li><li>Markus Letsch</li><li>Frank Jacobi</li><li>Thorsten Huber</li><li>Katharina Trbara</li><li>Stefan Diener</li><li>Frank Schröder</li><li>Eric Windmeier</li><li>Chris Swanepoel</li><li>Thomas Zimmermann</li><li>Maik Lüdeke</li><li>Michael Krisper</li><li>Sascha Hinlang</li><li>Chris Papenfuß</li><li>Torsten Klein</li><li>Alexej Klassen</li><li>Thomas Zimmermann</li><li>Peter Sonderegger</li><li>Rico Schäpe</li><li>Theo Pack</li><li>Wilfried Hahn</li><li>Johannes Lang</li><li>Andreas Werner</li><li>Marc Bless</li><li>Marcel Felder</li><li>Serkan Uslubas</li><li>Chris Swanepoel</li><li>Sven Peters</li><li>Malte Buchholz</li><li>marco mannucci</li><li>Anja Odenthal</li><li>Rene Philipp Heindl</li><li>Thomas Bünger</li><li>Alexander-Gregor Skrypzinski</li><li>Ingo Richter</li><li>Christian Kauer</li><li>Lars Konieczny</li><li>Ramon Kania, moveo Software GmbH</li><li>Linus Hechinger</li><li>Michael Neuhaus</li><li>Sascha Bühler</li><li>Manuel Wenk</li><li>David Rietz</li><li>Kiaresch Mussawisade</li><li>Daniel Opalla</li><li>Thomas Dralle</li><li>Peter Gfader</li><li>Lucas Heuvelmann</li><li>Erwin Altersberger</li><li>Alexander Zeitler</li><li>Leo von Wyss</li><li>Sebastian Rumpf</li><li>René Holy</li><li>Giuliano Di Pasquale</li><li>Haiko Emmel</li><li>Christopher Kamper</li><li>Axel Schuhmacher</li><li>Patrick Riccius</li><li>David Wendland</li><li>Martin Monsorno</li><li>Peter Wagner</li><li>Alexander John-Anacker</li><li>Johannes Keßler</li><li>Sven Günthner</li><li>Sandra Sieroux</li><li>Sebastian Stiehl</li><li>Johannes Weiß</li><li>Claudia Schwarz</li><li>Rainer Queck</li><li>Wolf-Dieter Hofmann</li><li>Christian Bleser</li><li>Dominik Kellner</li><li>Thomas Krooß</li><li>Timo Steigerwald</li><li>Jan Mohrmann</li><li>Thomas Warnick</li><li>Marco Schuster</li><li>Guido Leibbrand</li><li>Rainer Jung</li><li>dominik panzer</li><li>Sven Fleige</li><li>Marc Jodkuhn</li><li>Tobias Bergmann</li><li>Thomas Kuhn</li><li>Frank Jurisch</li><li>Christian Daniel</li><li>Michael Theis</li><li>Martin Zauner</li><li>Robert Karmann</li><li>Christian Daniel</li><li>THOMAS SCHROETER</li><li>Uwe Zimmermann</li><li>Rüdiger Schmidt</li><li>Johannes Maier</li><li>Stephan Bartl</li><li>Carsten Heuer</li><li>Thomas Bertz</li><li>Roland Bär</li><li>Roman Bartke</li><li>Thorsten Diekhof</li><li>Stefan Roock</li><li>Steffen Monarth</li><li>Martin Holzhauer</li><li>Zack Brown</li><li>Wolfgang Braun</li><li>Jakob Bysewski</li><li>Jörg Wiedmann</li><li>Pascal Soell</li><li>Stephan Weißenberger</li><li>Manuel Sidler</li><li>Andreas Mahr</li><li>Thomas Schell</li><li>marcus vengels</li><li>Jane Trümner</li><li>Sven Reske</li><li>Tobias Wiesenthal</li><li>Andre Kunz</li><li>Gunnar Magholder</li><li>Martin Monsorno</li><li>Rainer Bauer</li><li>Georg Karpala</li><li>Felix Maschek</li><li>Uli Armbruster</li><li>Maik Römpagel</li><li>Thomas Weller</li><li>Mischa Landwehr</li><li>Konrad Brunner</li><li>Matthias Luenemann</li><li>Marcel Kummerow</li><li>Marcus Kraßmann</li><li>Michael Schommer</li><li>Hinrich Kück</li><li>Tulug Yuecel</li><li>Christian Haug</li><li>Philipp Zipfel</li><li>Andreas Lennartz</li><li>Andreas Baumgart</li><li>Wolfram Wagner</li><li>Matthias Schönau</li><li>Tobias Demuth</li><li>Thomas Hertel</li><li>Dennis Moldenhauer</li><li>Alexander Kirsch</li><li>Patrick Koglin</li><li>Stefan Stolz</li><li>Sybit GmbH Sybit GmbH</li><li>Philipp Lenz</li><li>Andre Voll</li><li>Sebastian Dietz</li><li>Harmen Weber</li><li>Nico Zimmermann</li><li>René Pfeuffer</li><li>Ricardo Ferreira</li><li>Silvio Pohl</li><li>Ronny Windolph</li><li>Birgit Kratz</li><li>Jens Hausherr</li><li>Ronny Windolph</li><li>Jörg Vollmer</li><li>Stefan Cullmann</li><li>Florian Schinagl</li><li>Nikolaus Themeßl</li><li>Stefan Zeller</li><li>Frank Banzhoff</li><li>Christian Fritsch</li><li>Stephan Knitelius</li><li>Matthias Kramp, moveo Software GmbH</li><li>Sebastian Kroop, moveo Software GmbH</li><li>André Hurschler</li><li>Johannes Lattrich</li><li>Sabine Plüß</li><li>Sven Kobow</li><li>Axel Roeber</li><li>Rene Richter</li><li>Norman Tunger</li><li>Tino Hertlein</li><li>Frank Pfattheicher</li><li>Georg Brüstle</li><li>Stefan Glabisch</li><li>Nils Grieger</li><li>Michael Romer</li><li>Sabine Kalb</li><li>Frank Prill</li><li>Thomas Baustert</li><li>Ewald Ottmann</li><li>Siegfried Winkler</li><li>York Xylander</li><li>Jan Wetterau</li><li>Timo Waeschke</li><li>Jan Becker</li><li>Daniel Schwartz</li><li>Christoph Emonds</li><li>Sven Köhler</li><li>Lukas Weibel</li><li>Sandra Hinz</li><li>Ruth Findenig</li><li>Julia Wolk</li><li>Manuel Korrmann</li><li>Benjamin Toussaint</li><li>Elias Froschauer</li><li>Peter Daum</li><li>Florian Mätschke</li><li>Jan Bosshard</li><li>Ralf Pannemans</li><li>Lennart Johansson</li><li>Klaus Greff</li><li>Andreas Rupp</li><li>Richard Papenfuss</li><li>Martin Murrer</li><li>Daniel Zwicker</li><li>Enrico Lefass</li><li>Fries David</li><li>Steffen Märcker</li><li>Roland Ließ</li><li>ansgar simon</li><li>George Mamaladze</li><li>Sandro Lehmann</li><li>André Hinz</li><li>Christian Schmitterer</li><li>Pascal Schäfer</li><li>Olaf Kronefeld</li><li>Elena Asyova</li><li>Stefan Billeb</li><li>Christian Müller</li><li>Thomas Götzinger</li><li>Beat Bögli</li><li>Dag Frommhold</li><li>Simon Langbehn</li><li>Marc Sallin</li><li>Stephan Lindner</li><li>Kristin Wagner</li><li>Philipp Dreher</li><li>Bernd Zeitler</li><li>Stefan Jamin</li><li>Patricia Tiedemann</li><li>Alexander Mikuta</li><li>Peter Krämer</li><li>Thorsten Gutbrod</li><li>Timo Haberkern</li><li>Marlene Knoche</li><li>Jens Thirmeyer</li><li>Gerrit Wanderer</li><li>Christian Weiß</li><li>Yvonne Opalka</li><li>Serge Hänni</li><li>Jens Vogel</li><li>Daniel Rast</li><li>Bernd-Christoph Schwede</li><li>Christof Schoell</li><li>Matthias Geörg</li><li>Horst Dehmer</li><li>Dominik Hirt</li><li>Tobias Schafer</li><li>Joachim Eckert</li><li>Viktor Engelmann</li><li>Jon Krom</li><li>Selim Celik</li><li>Damir Majer</li><li>Björn Lundström</li><li>Steve Rakebrandt</li><li>Matthias Gernand</li><li>Heinz van Pee</li><li>Michael Engelin</li><li>Sascha Kegreiß</li><li>Michael Free</li><li>Alexander Mueller</li><li>Bastian Busch</li><li>Patrick Peer</li><li>Alexander Bierbaumer</li><li>Andrea Weikert</li><li>Tobias Sinz</li><li>Benjamin Stein</li><li>Malte Fiala</li><li>Bastian Helfert</li><li>Thomas Michel</li><li>Roman Hartmann</li><li>Stefan Becker</li><li>Johann Krez</li><li>Uta Schulze</li><li>Sven Mulholland</li><li>Thomas Schubert</li><li>Florian Quadt</li><li>Sven Laschinski</li><li>Ferenc Becker</li><li>Andreas Kaubisch</li><li>Daniel Albertini</li><li>Philipp Thun</li><li>Thomas Gaub</li><li>Tobias Baumann</li><li>Tim Vengels</li><li>Johann Blauensteiner</li><li>Markus Kiss</li><li>Anke Bremer</li><li>Daniel Kreiseder</li><li>Marco Schmittnägel</li><li>Christopher Kruczek</li><li>Sybit GmbH</li><li>Claudia Wechselberger</li><li>Thomas Nagel</li><li>Tobias Mueller</li><li>Reik Oberrath</li><li>Christian Stolcis</li><li>Bernd Zuther</li><li>Carsten Igel</li><li>Uwe Walter</li><li>Klaus-Martin Scheuer</li><li>Michael Dörsam</li><li>Peter Kessler</li><li>Yvonne Huebner</li><li>Robert Sauer</li><li>Jörg Stelkens</li><li>Christian Pfisterer</li><li>Peter Schaeffer</li><li>stefan Gamerith</li><li>Roland Schneider</li><li>Peter Merkel</li><li>Sebastian Behrendt</li><li>Patrick Pekczynski</li><li>Christoph Neumann</li><li>Matthias Fischer</li><li>Martin Wesemann</li><li>Kilian Lütkemeyer</li><li>Denis Reichelt</li><li>Susann Schmidt</li><li>Susanne Schramm</li><li>Steffen Schnaufer</li><li>Kathrin Schulz</li><li>Markus Eder</li><li>Pascal Witte</li><li>Marco Feltmann</li><li>John Gerdeman</li><li>Sebastian Sauer</li><li>Kai Mengel</li><li>Bastian Stölb</li><li>Maik Zosel</li><li>Marcel Stoer</li><li>Volker Janzen</li><li>Daniel Jakobs</li><li>Manuel Markwalder</li><li>Christel Mersch</li><li>Daniel Brün</li><li>Marc Tinnemeyer</li><li>Gerhard Ahlers</li><li>Harald Jedele</li><li>Jochen Linnemann</li><li>Seibert Stefan</li><li>Timo Peter</li><li>Ekaterina Dikushina</li><li>Matthias Münnich</li><li>Jakob Kroeker<br /></li></ol>
]]></description><pubDate>Sun, 05 Feb 2012 08:52:01 GMT</pubDate><guid isPermaLink="false">BD23BFE1725BFE4DA7B706B8F713B775</guid></item><item><title><![CDATA[Tools]]></title><link>http://clean-code-developer.de/Tools.ashx</link><author>mkania (mkania)</author><description><![CDATA[<h1 class="separator">Werkzeuge für Clean Code Developer<a class="headeranchor" id="Werkzeuge_für_Clean_Code_Developer_19" href="#Werkzeuge_für_Clean_Code_Developer_19" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
<table id="TocContainerTable"><tr><td><div id="TocContainer"><p class="small"><b>Inhaltsverzeichnis</b><span id="ExpandTocSpan"> [<a href="#" onclick="javascript:if(document.getElementById('Toc').style['display']=='none') document.getElementById('Toc').style['display']=''; else document.getElementById('Toc').style['display']='none'; return false;">Anzeigen/Verbergen</a>]</span></p><div id="Toc"><p><br /><b><a href="#Werkzeuge_für_Clean_Code_Developer_19">Werkzeuge für Clean Code Developer</a></b><br />&nbsp;&nbsp;&nbsp;<a href="#Architektur__Design_14">Architektur / Design</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Inversion_of_Control__Dependency_Injection_2">Inversion of Control / Dependency Injection</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Refaktorisierung_3">Refaktorisierung</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Metriken__Codeanalyse_4">Metriken / Codeanalyse</a><br />&nbsp;&nbsp;&nbsp;<a href="#Automatisiertes_Testen_15">Automatisiertes Testen</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Integrationstests_UI_Tests_5">Integrationstests, UI Tests</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Unit_Tests_6">Unit Tests</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Mockup_Frameworks_7">Mockup Frameworks</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Code_Coverage_Analyse_8">Code Coverage Analyse</a><br />&nbsp;&nbsp;&nbsp;<a href="#Produktion_16">Produktion</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Build-Tools_9">Build-Tools</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Versionskontrolle_10">Versionskontrolle</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<small><a href="#Zentral_0">Zentral</a></small><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<small><a href="#Verteilt_1">Verteilt</a></small><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Continuous_Integration_11">Continuous Integration</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Profiler_12">Profiler</a><br />&nbsp;&nbsp;&nbsp;<a href="#Entwicklungsprozess_17">Entwicklungsprozess</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Issue_Tracking_13">Issue Tracking</a><br />&nbsp;&nbsp;&nbsp;<a href="#Clean_Code_Developer_18">Clean Code Developer</a><br /></p></div></div></td></tr></table><br /><h2 class="separator">Architektur / Design<a class="headeranchor" id="Architektur__Design_14" href="#Architektur__Design_14" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Inversion of Control / Dependency Injection<a class="headeranchor" id="Inversion_of_Control__Dependency_Injection_2" href="#Inversion_of_Control__Dependency_Injection_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><ul><li>.Net<ul><li>autofac, <a class="externallink" href="http://code.google.com/p/autofac/" title="http://code.google.com/p/autofac/" target="_blank">http://code.google.com/p/autofac/</a></li><li>Castle Windsor (IoC Container), <a class="externallink" href="http://www.castleproject.org/container/index.html" title="http://www.castleproject.org/container/index.html" target="_blank">http://www.castleproject.org/container/index.html</a></li><li>Microsoft Unity, <a class="externallink" href="http://msdn.microsoft.com/en-us/library/cc468366.aspx" title="http://msdn.microsoft.com/en-us/library/cc468366.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/cc468366.aspx</a></li><li>NinJect, <a class="externallink" href="http://ninject.org/" title="http://ninject.org/" target="_blank">http://ninject.org/</a></li><li>Spring.NET, <a class="externallink" href="http://www.springframework.net/" title="http://www.springframework.net/" target="_blank">http://www.springframework.net/</a></li><li>StructureMap, <a class="externallink" href="http://structuremap.sourceforge.net/Default.htm" title="http://structuremap.sourceforge.net/Default.htm" target="_blank">http://structuremap.sourceforge.net/Default.htm</a></li><li>LightCore, <a class="externallink" href="http://lightcore.ch/" title="http://lightcore.ch/" target="_blank">http://lightcore.ch/</a><br /></li></ul></li></ul><br />Versuch einer Vereinheitlichung des Zugriffs auf DI Container:
<ul><li>Microsoft Common Service Locator, <a class="externallink" href="http://www.codeplex.com/CommonServiceLocator" title="http://www.codeplex.com/CommonServiceLocator" target="_blank">http://www.codeplex.com/CommonServiceLocator</a><br /></li></ul><br /><a class="externallink" href="http://blog.ashmind.com/index.php/2008/08/19/comparing-net-di-ioc-frameworks-part-1/" title="Vergleich" target="_blank">Vergleich</a> einiger DI Frameworks.<br /><br /><ul><li>Java<ul><li>Guice, <a class="externallink" href="http://code.google.com/p/google-guice/" title="http://code.google.com/p/google-guice/" target="_blank">http://code.google.com/p/google-guice/</a></li><li>Spring Framework, <a class="externallink" href="http://www.springsource.org/" title="http://www.springsource.org/" target="_blank">http://www.springsource.org/</a><br /></li></ul></li></ul><br />
<h3 class="separator">Refaktorisierung<a class="headeranchor" id="Refaktorisierung_3" href="#Refaktorisierung_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><ul><li>.Net<ul><li>JetBrains ReSharper (VS Add-In), <a class="externallink" href="http://www.jetbrains.com/resharper" title="http://www.jetbrains.com/resharper" target="_blank">http://www.jetbrains.com/resharper</a></li><li>Telerik JustCode (VS Add-In), <a class="externallink" href="http://www.telerik.com/products/justcode.aspx" title="http://www.telerik.com/products/justcode.aspx" target="_blank">http://www.telerik.com/products/justcode.aspx</a></li><li>DevExpress <a class="externallink" href="http://www.devexpress.com/Products/Visual_Studio_Add-in/CodeRushX/" title="CodeRush Express (VS Add-In)" target="_blank">CodeRush Express (VS Add-In)</a></li><li>Visual Studio (ab der Std Edition)</li></ul></li><li>C++<ul><li>VisualAssistX, Plugin für Visual Studio, <a class="externallink" href="http://www.wholetomato.com/" title="http://www.wholetomato.com/" target="_blank">http://www.wholetomato.com/</a></li></ul></li><li>Java<ul><li>in Eclipse enthalten <a class="externallink" href="http://www.eclipse.org" title="http://www.eclipse.org" target="_blank">http://www.eclipse.org</a><br /></li></ul></li></ul><br /><h3 class="separator">Metriken / Codeanalyse<a class="headeranchor" id="Metriken__Codeanalyse_4" href="#Metriken__Codeanalyse_4" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><ul><li>.Net<ul><li>FxCop, <a class="externallink" href="http://code.msdn.microsoft.com/codeanalysis/Release/ProjectReleases.aspx?ReleaseId=553" title="http://code.msdn.microsoft.com/codeanalysis/Release/ProjectReleases.aspx?ReleaseId=553" target="_blank">http://code.msdn.microsoft.com/codeanalysis/Release/ProjectReleases.aspx?ReleaseId=553</a></li><li>NDepend, <a class="externallink" href="http://ndepend.com/" title="http://ndepend.com/" target="_blank">http://ndepend.com/</a></li><li>Simian, <a class="externallink" href="http://www.redhillconsulting.com.au/products/simian/" title="http://www.redhillconsulting.com.au/products/simian/" target="_blank">http://www.redhillconsulting.com.au/products/simian/</a> - spürt Verletzungen des DRY-Prinzips im Code auf</li><li>SourceMonitor, <a class="externallink" href="http://www.campwoodsw.com/sourcemonitor.html" title="http://www.campwoodsw.com/sourcemonitor.html" target="_blank">http://www.campwoodsw.com/sourcemonitor.html</a></li><li>StyleCop, <a class="externallink" href="http://code.msdn.microsoft.com/sourceanalysis" title="http://code.msdn.microsoft.com/sourceanalysis" target="_blank">http://code.msdn.microsoft.com/sourceanalysis</a></li></ul></li><li>Java<ul><li>Sonar, <a class="externallink" href="http://www.sonarsource.org/" title="http://www.sonarsource.org/" target="_blank">http://www.sonarsource.org/</a></li><li>PMD, <a class="externallink" href="http://pmd.sourceforge.net/" title="http://pmd.sourceforge.net/" target="_blank">http://pmd.sourceforge.net/</a> auch als Maven Plugin</li><li>Checkstyle, <a class="externallink" href="http://checkstyle.sourceforge.net/" title="http://checkstyle.sourceforge.net/" target="_blank">http://checkstyle.sourceforge.net/</a> auch als Maven Plugin</li><li>FindBugs, <a class="externallink" href="http://findbugs.sourceforge.net/" title="http://findbugs.sourceforge.net/" target="_blank">http://findbugs.sourceforge.net/</a> auch als Maven Plugin<br /></li></ul></li></ul><br /><br /><br /><h2 class="separator">Automatisiertes Testen<a class="headeranchor" id="Automatisiertes_Testen_15" href="#Automatisiertes_Testen_15" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Integrationstests, UI Tests<a class="headeranchor" id="Integrationstests_UI_Tests_5" href="#Integrationstests_UI_Tests_5" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><ul><li>.Net<ul><li>Ranorex (Integrationstests für Desktop- und Webanwendungen und allgemein UI-Automatisation), <a class="externallink" href="http://www.ranorex.com/" title="http://www.ranorex.com/" target="_blank">http://www.ranorex.com/</a></li><li>WatiN (Integrationstests für Webanwendungen), <a class="externallink" href="http://watin.sourceforge.net/" title="http://watin.sourceforge.net/" target="_blank">http://watin.sourceforge.net/</a></li><li>WatiR (Webanwendungen), <a class="externallink" href="http://watir.com/" title="http://watir.com/" target="_blank">http://watir.com/</a></li><li>WebAii, Design Canvas (Testen von Web- und Silverlight Anwendungen), <a class="externallink" href="http://www.artoftest.com/" title="http://www.artoftest.com/" target="_blank">http://www.artoftest.com/</a></li><li>Web UI Test Studio (Testen von Web- und Silverlight Anwendungen), <a class="externallink" href="http://www.telerik.com/products/web-testing-tools.aspx" title="http://www.telerik.com/products/web-testing-tools.aspx" target="_blank">http://www.telerik.com/products/web-testing-tools.aspx</a></li><li>white (Win32, WinForms, WPF, SWT), <a class="externallink" href="http://www.codeplex.com/white" title="http://www.codeplex.com/white" target="_blank">http://www.codeplex.com/white</a></li><li>Selenium (Webanwendungen), <a class="externallink" href="http://seleniumhq.org/" title="http://seleniumhq.org/" target="_blank">http://seleniumhq.org/</a></li><li>Silverlight Selenium (Silverlight Anwendungen), <a class="externallink" href="http://code.google.com/p/silverlight-selenium/" title="http://code.google.com/p/silverlight-selenium/" target="_blank">http://code.google.com/p/silverlight-selenium/</a></li><li>SilverUnit (Silverlight Anwendungen), <a class="externallink" href="http://cthru.codeplex.com/" title="http://cthru.codeplex.com/" target="_blank">http://cthru.codeplex.com/</a><br /></li></ul></li></ul><br /><ul><li>Java<ul><li>QF-Test - für Swing, SWT und Web-Anwendungen <a class="externallink" href="http://www.qfs.de/de/qftest/index.html" title="http://www.qfs.de/de/qftest/index.html" target="_blank">http://www.qfs.de/de/qftest/index.html</a><br /></li></ul></li></ul><br />
<h3 class="separator">Unit Tests<a class="headeranchor" id="Unit_Tests_6" href="#Unit_Tests_6" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><ul><li>.Net<ul><li>gallio, <a class="externallink" href="http://www.gallio.org/" title="http://www.gallio.org/" target="_blank">http://www.gallio.org/</a> (Testrunner für verschiedene Testframeworks)</li><li>MBUnit, <a class="externallink" href="http://www.mbunit.com/" title="http://www.mbunit.com/" target="_blank">http://www.mbunit.com/</a></li><li>NUnit (Unit Test Framework), <a class="externallink" href="http://nunit.org/" title="http://nunit.org/" target="_blank">http://nunit.org/</a></li><li>JetBrains ReSharper (VS Add-In), <a class="externallink" href="http://www.jetbrains.com/resharper/" title="http://www.jetbrains.com/resharper/" target="_blank">http://www.jetbrains.com/resharper/</a> (enthält einen Testrunner für NUnit und andere Testframeworks)</li><li>Testdriven.Net (VS Add-In), <a class="externallink" href="http://testdriven.net/" title="http://testdriven.net/" target="_blank">http://testdriven.net/</a> (Testrunner für NUnit und andere Testframeworks)</li><li>Testmatrix (VS Add-In), <a class="externallink" href="http://www.exactmagic.com/products/testmatrix/index.html" title="http://www.exactmagic.com/products/testmatrix/index.html" target="_blank">http://www.exactmagic.com/products/testmatrix/index.html</a> (Testrunner für NUnit)</li><li>Visual Studio (ab der Pro Edition)</li><li>xUnit.net, <a class="externallink" href="http://www.codeplex.com/xunit" title="http://www.codeplex.com/xunit" target="_blank">http://www.codeplex.com/xunit</a></li><li>xUnit BDD Extensions<ul><li>Blog Post <a class="externallink" href="http://www.bjoernrochel.de/2008/10/04/introducing-xunitbddextensions/" title="http://www.bjoernrochel.de/2008/10/04/introducing-xunitbddextensions/" target="_blank">http://www.bjoernrochel.de/2008/10/04/introducing-xunitbddextensions/</a></li><li>Code <a class="externallink" href="http://code.google.com/p/xunitbddextensions/" title="http://code.google.com/p/xunitbddextensions/" target="_blank">http://code.google.com/p/xunitbddextensions/</a></li></ul></li></ul></li><li>C++:<ul><li>Google Test, <a class="externallink" href="http://code.google.com/p/googletest/" title="http://code.google.com/p/googletest/" target="_blank">http://code.google.com/p/googletest/</a></li><li>CppUnit, <a class="externallink" href="http://cppunit.sourceforge.net/" title="http://cppunit.sourceforge.net/" target="_blank">http://cppunit.sourceforge.net/</a></li></ul></li><li>Java<ul><li>JUnit, <a class="externallink" href="http://www.junit.org/" title="http://www.junit.org/" target="_blank">http://www.junit.org/</a> (in Eclipse bereits entalten, inkl. Testrunner)</li><li>Hamcrest, <a class="externallink" href="http://code.google.com/p/hamcrest/" title="http://code.google.com/p/hamcrest/" target="_blank">http://code.google.com/p/hamcrest/</a></li></ul></li><li>JavaScript<ul><li>QUnit, <a class="externallink" href="http://docs.jquery.com/Qunit" title="http://docs.jquery.com/Qunit" target="_blank">http://docs.jquery.com/Qunit</a></li></ul></li><li>Python<ul><li>unittest - in der Standard Lib integriert</li><li>unittest2, <a class="externallink" href="http://pypi.python.org/pypi/unittest2/" title="http://pypi.python.org/pypi/unittest2/" target="_blank">http://pypi.python.org/pypi/unittest2/</a></li><li>nose, <a class="externallink" href="http://pypi.python.org/pypi/nose/" title="http://pypi.python.org/pypi/nose/" target="_blank">http://pypi.python.org/pypi/nose/</a><br /></li></ul></li></ul><br /><a class="externallink" href="http://de.wikipedia.org/wiki/Liste_von_Modultest-Software" title="Liste von Unittest-Frameworks bei Wikipedia" target="_blank">Liste von Unittest-Frameworks bei Wikipedia</a><br /><br />
<h3 class="separator">Mockup Frameworks<a class="headeranchor" id="Mockup_Frameworks_7" href="#Mockup_Frameworks_7" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><ul><li>.Net<ul><li>Moq, <a class="externallink" href="http://code.google.com/p/moq/" title="http://code.google.com/p/moq/" target="_blank">http://code.google.com/p/moq/</a></li><li>NMock, <a class="externallink" href="http://nmock.org/" title="http://nmock.org/" target="_blank">http://nmock.org/</a></li><li>Rhino Mocks, <a class="externallink" href="http://ayende.com/projects/rhino-mocks.aspx" title="http://ayende.com/projects/rhino-mocks.aspx" target="_blank">http://ayende.com/projects/rhino-mocks.aspx</a></li><li>TypeMock Isolator, <a class="externallink" href="http://typemock.com/" title="http://typemock.com/" target="_blank">http://typemock.com/</a></li></ul></li><li>C++<ul><li>Google Mock, <a class="externallink" href="http://code.google.com/p/googlemock/" title="http://code.google.com/p/googlemock/" target="_blank">http://code.google.com/p/googlemock/</a></li><li>mockpp, <a class="externallink" href="http://mockpp.sourceforge.net/" title="http://mockpp.sourceforge.net/" target="_blank">http://mockpp.sourceforge.net/</a></li></ul></li><li>Java<ul><li>EasyMock, <a class="externallink" href="http://easymock.org/" title="http://easymock.org/" target="_blank">http://easymock.org/</a></li><li>JMock, <a class="externallink" href="http://www.jmock.org/" title="http://www.jmock.org/" target="_blank">http://www.jmock.org/</a></li><li>mockito, <a class="externallink" href="http://code.google.com/p/mockito/" title="http://code.google.com/p/mockito/" target="_blank">http://code.google.com/p/mockito/</a><br /></li></ul></li></ul><br /><h3 class="separator">Code Coverage Analyse<a class="headeranchor" id="Code_Coverage_Analyse_8" href="#Code_Coverage_Analyse_8" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><ul><li>.Net<ul><li>JetBrains dotCover, <a class="externallink" href="http://www.jetbrains.com/dotcover/" title="http://www.jetbrains.com/dotcover/" target="_blank">http://www.jetbrains.com/dotcover/</a></li><li>NCover, <a class="externallink" href="http://www.ncover.com/" title="http://www.ncover.com/" target="_blank">http://www.ncover.com/</a></li><li>Testmatrix (VS Add-In), <a class="externallink" href="http://www.exactmagic.com/products/testmatrix/index.html" title="http://www.exactmagic.com/products/testmatrix/index.html" target="_blank">http://www.exactmagic.com/products/testmatrix/index.html</a> (Testrunner für NUnit)</li><li>Visual Studio Team System</li></ul></li><li>C++<ul><li>BullseyeCoverage, <a class="externallink" href="http://www.bullseye.com/" title="http://www.bullseye.com/" target="_blank">http://www.bullseye.com/</a></li></ul></li><li>Java<ul><li>Cobertura <a class="externallink" href="http://cobertura.sourceforge.net/" title="http://cobertura.sourceforge.net/" target="_blank">http://cobertura.sourceforge.net/</a>, gibt's auch als Maven Plugin</li><li>Emma <a class="externallink" href="http://emma.sourceforge.net/" title="http://emma.sourceforge.net/" target="_blank">http://emma.sourceforge.net/</a>, gibt's ebenfalls als Maven Plugin</li></ul></li><li>Python<ul><li>In PyDev integriert: <a class="externallink" href="http://stackoverflow.com/questions/2262777/how-to-get-unit-test-coverage-results-in-eclipse-pydev" title="http://stackoverflow.com/questions/2262777/how-to-get-unit-test-coverage-results-in-eclipse-pydev" target="_blank">http://stackoverflow.com/questions/2262777/how-to-get-unit-test-coverage-results-in-eclipse-pydev</a><br /></li></ul></li></ul><br />
<h2 class="separator">Produktion<a class="headeranchor" id="Produktion_16" href="#Produktion_16" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Build-Tools<a class="headeranchor" id="Build-Tools_9" href="#Build-Tools_9" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<ul><li>ANT die <i>unverzichtbare </i> fleißige Ameise <a class="externallink" href="http://ant.apache.org" title="http://ant.apache.org" target="_blank">http://ant.apache.org</a></li><li>MAVEN Prototypen-gesteuerter Generator, Build-Controller, Internet-Repository <a class="externallink" href="http://maven.apache.org" title="http://maven.apache.org" target="_blank">http://maven.apache.org</a><br /></li></ul><br />
<h3 class="separator">Versionskontrolle<a class="headeranchor" id="Versionskontrolle_10" href="#Versionskontrolle_10" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<h4 class="separator">Zentral<a class="headeranchor" id="Zentral_0" href="#Zentral_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4><ul><li>Subversion (SVN), <a class="externallink" href="http://subversion.tigris.org/" title="http://subversion.tigris.org/" target="_blank">http://subversion.tigris.org/</a><ul><li>SVN-Monitor, <a class="externallink" href="http://www.svnmonitor.com/" title="http://www.svnmonitor.com/" target="_blank">http://www.svnmonitor.com/</a></li><li>VisualSVN (VS Add-In, Subversion Server), <a class="externallink" href="http://visualsvn.com/" title="http://visualsvn.com/" target="_blank">http://visualsvn.com/</a></li><li>TortoiseSVN, <a class="externallink" href="http://tortoisesvn.tigris.org/" title="http://tortoisesvn.tigris.org/" target="_blank">http://tortoisesvn.tigris.org/</a></li></ul></li><li>Team Foundation Server, <a class="externallink" href="http://msdn.microsoft.com/en-us/tfs2008/default.aspx" title="http://msdn.microsoft.com/en-us/tfs2008/default.aspx" target="_blank">http://msdn.microsoft.com/en-us/tfs2008/default.aspx</a></li><li>Vault, <a class="externallink" href="http://www.sourcegear.com/vault/index.html" title="http://www.sourcegear.com/vault/index.html" target="_blank">http://www.sourcegear.com/vault/index.html</a><br /></li></ul><br /><h4 class="separator">Verteilt<a class="headeranchor" id="Verteilt_1" href="#Verteilt_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4><ul><li>Mercurial (HG), <a class="externallink" href="http://mercurial.selenic.com/" title="http://mercurial.selenic.com/" target="_blank">http://mercurial.selenic.com/</a><ul><li>TortoiseHG, Windwos Explorer Erweiterung, <a class="externallink" href="http://tortoisehg.bitbucket.org/" title="http://tortoisehg.bitbucket.org/" target="_blank">http://tortoisehg.bitbucket.org/</a></li><li>hgscc, Visual Studio SCC Addin, <a class="externallink" href="http://www.newsupaplex.pp.ru/hgscc_news_eng.html" title="http://www.newsupaplex.pp.ru/hgscc_news_eng.html" target="_blank">http://www.newsupaplex.pp.ru/hgscc_news_eng.html</a></li></ul></li><li>Git, <a class="externallink" href="http://git-scm.com/" title="http://git-scm.com/" target="_blank">http://git-scm.com/</a><ul><li>TortoiseGIT, <a class="externallink" href="http://code.google.com/p/tortoisegit/" title="http://code.google.com/p/tortoisegit/" target="_blank">http://code.google.com/p/tortoisegit/</a></li><li>Gerrit, <a class="externallink" href="http://code.google.com/p/gerrit/" title="http://code.google.com/p/gerrit/" target="_blank">http://code.google.com/p/gerrit/</a></li><li>msysit, <a class="externallink" href="http://code.google.com/p/msysgit/" title="http://code.google.com/p/msysgit/" target="_blank">http://code.google.com/p/msysgit/</a></li></ul></li><li>Bazaar, <a class="externallink" href="http://bazaar.canonical.com/en/" title="http://bazaar.canonical.com/en/" target="_blank">http://bazaar.canonical.com/en/</a><ul><li>TortoiseBzr, <a class="externallink" href="https://launchpad.net/tortoisebzr" title="https://launchpad.net/tortoisebzr" target="_blank">https://launchpad.net/tortoisebzr</a></li></ul></li><li>Pastic SCM, <a class="externallink" href="http://www.plasticscm.com" title="http://www.plasticscm.com" target="_blank">http://www.plasticscm.com</a></li><li>Darcs, <a class="externallink" href="http://darcs.net/" title="http://darcs.net/" target="_blank">http://darcs.net/</a><ul><li>TortoiseDarcs, <a class="externallink" href="http://tortoisedarcs.sourceforge.net/" title="http://tortoisedarcs.sourceforge.net/" target="_blank">http://tortoisedarcs.sourceforge.net/</a></li></ul></li><li>IBM CM Synergy <a class="externallink" href="http://www-01.ibm.com/software/awdtools/synergy/" title="http://www-01.ibm.com/software/awdtools/synergy/" target="_blank">http://www-01.ibm.com/software/awdtools/synergy/</a><br /></li></ul><br />
<h3 class="separator">Continuous Integration<a class="headeranchor" id="Continuous_Integration_11" href="#Continuous_Integration_11" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><ul><li>CruiseControl.NET (CC.NET), <a class="externallink" href="http://ccnet.thoughtworks.com/" title="http://ccnet.thoughtworks.com/" target="_blank">http://ccnet.thoughtworks.com/</a><ul><li>GUI für CC.NET, <a class="externallink" href="http://ccnetconfig.org/" title="http://ccnetconfig.org/" target="_blank">http://ccnetconfig.org/</a></li></ul></li><li>FinalBuilder (visuelle Scripts für CI und allgm. Batch-Aufgaben), <a class="externallink" href="http://www.finalbuilder.com" title="http://www.finalbuilder.com" target="_blank">http://www.finalbuilder.com</a></li><li>Hudson CI Server, <a class="externallink" href="https://hudson.dev.java.net/" title="https://hudson.dev.java.net/" target="_blank">https://hudson.dev.java.net/</a></li><li>JetBrains TeamCity, <a class="externallink" href="http://www.jetbrains.com/teamcity/" title="http://www.jetbrains.com/teamcity/" target="_blank">http://www.jetbrains.com/teamcity/</a></li><li>Team Foundation Server, <a class="externallink" href="http://msdn.microsoft.com/en-us/tfs2008/default.aspx" title="http://msdn.microsoft.com/en-us/tfs2008/default.aspx" target="_blank">http://msdn.microsoft.com/en-us/tfs2008/default.aspx</a></li><li>VisualBuild, <a class="externallink" href="http://www.kinook.com/VisBuildPro/" title="http://www.kinook.com/VisBuildPro/" target="_blank">http://www.kinook.com/VisBuildPro/</a><br /></li></ul><br /><a class="externallink" href="http://confluence.public.thoughtworks.org/display/CC/CI+Feature+Matrix" title="Vergleich" target="_blank">Vergleich</a> einiger CI Tools.<br /><br /><h3 class="separator">Profiler<a class="headeranchor" id="Profiler_12" href="#Profiler_12" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><ul><li>.Net<ul><li>JetBrains dotTrace, <a class="externallink" href="http://www.jetbrains.com/profiler/" title="http://www.jetbrains.com/profiler/" target="_blank">http://www.jetbrains.com/profiler/</a></li><li>Red-Gate ANTS, <a class="externallink" href="http://www.red-gate.com/products/ants_performance_profiler/index.htm" title="http://www.red-gate.com/products/ants_performance_profiler/index.htm" target="_blank">http://www.red-gate.com/products/ants_performance_profiler/index.htm</a></li></ul></li><li>Java<ul><li>YourKit, <a class="externallink" href="http://www.yourkit.com/" title="http://www.yourkit.com/" target="_blank">http://www.yourkit.com/</a><br /></li></ul></li></ul><br /><h2 class="separator">Entwicklungsprozess<a class="headeranchor" id="Entwicklungsprozess_17" href="#Entwicklungsprozess_17" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><ul><li>Team Foundation Server, <a class="externallink" href="http://msdn.microsoft.com/en-us/tfs2008/default.aspx" title="http://msdn.microsoft.com/en-us/tfs2008/default.aspx" target="_blank">http://msdn.microsoft.com/en-us/tfs2008/default.aspx</a></li><li>VersionOne, <a class="externallink" href="http://www.versionone.com/" title="http://www.versionone.com/" target="_blank">http://www.versionone.com/</a></li><li>AgileZen, <a class="externallink" href="http://agilezen.com/" title="http://agilezen.com/" target="_blank">http://agilezen.com/</a></li><li>Pivotal Tracker, <a class="externallink" href="http://www.pivotaltracker.com/" title="http://www.pivotaltracker.com/" target="_blank">http://www.pivotaltracker.com/</a></li><li>Redmine, <a class="externallink" href="http://www.redmine.org/" title="http://www.redmine.org/" target="_blank">http://www.redmine.org/</a><br /></li></ul><br /><h3 class="separator">Issue Tracking<a class="headeranchor" id="Issue_Tracking_13" href="#Issue_Tracking_13" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><ul><li>Bugzilla, <a class="externallink" href="http://www.bugzilla.org/" title="http://www.bugzilla.org/" target="_blank">http://www.bugzilla.org/</a></li><li>Team Foundation Server, <a class="externallink" href="http://msdn.microsoft.com/en-us/tfs2008/default.aspx" title="http://msdn.microsoft.com/en-us/tfs2008/default.aspx" target="_blank">http://msdn.microsoft.com/en-us/tfs2008/default.aspx</a></li><li>Trac, <a class="externallink" href="http://trac.edgewall.org/" title="http://trac.edgewall.org/" target="_blank">http://trac.edgewall.org/</a></li><li>JetBrains YouTRACK, <a class="externallink" href="http://www.jetbrains.com/youtrack/index.html" title="http://www.jetbrains.com/youtrack/index.html" target="_blank">http://www.jetbrains.com/youtrack/index.html</a></li><li>Mantis, <a class="externallink" href="http://www.mantisbt.org/" title="http://www.mantisbt.org/" target="_blank">http://www.mantisbt.org/</a></li><li>fixx, <a class="externallink" href="http://hedgehoglab.com/products/fixx/" title="http://hedgehoglab.com/products/fixx/" target="_blank">http://hedgehoglab.com/products/fixx/</a></li><li>JIRA, <a class="externallink" href="http://www.atlassian.com/software/jira/" title="http://www.atlassian.com/software/jira/" target="_blank">http://www.atlassian.com/software/jira/</a></li><li>Polarion TRACK & WIKI, <a class="externallink" href="http://www.polarion.com/" title="http://www.polarion.com/" target="_blank">http://www.polarion.com/</a></li><li>IBM CM Change <a class="externallink" href="http://www-01.ibm.com/software/awdtools/change/" title="http://www-01.ibm.com/software/awdtools/change/" target="_blank">http://www-01.ibm.com/software/awdtools/change/</a><br />kann mit dem o.g. CM Synergy integriert werden</li><li>Redmine, <a class="externallink" href="http://www.redmine.org/" title="http://www.redmine.org/" target="_blank">http://www.redmine.org/</a><br />===Application Lifecycle Management===<br />Requirements Engineering, Software Configuration Management, Quality Management</li><li>Polarion, <a class="externallink" href="http://www.polarion.com/" title="http://www.polarion.com/" target="_blank">http://www.polarion.com/</a></li><li>Rational,<a class="externallink" href="http://www-01.ibm.com/software/rational/offerings/lifecycle/?ca=rhp" title="http://www-01.ibm.com/software/rational/offerings/lifecycle/?ca=rhp" target="_blank">http://www-01.ibm.com/software/rational/offerings/lifecycle/?ca=rhp</a><br /></li></ul><br /><h2 class="separator">Clean Code Developer<a class="headeranchor" id="Clean_Code_Developer_18" href="#Clean_Code_Developer_18" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><ul><li>CCD Spickzettel in Visual Studio, <a class="externallink" href="http://code.google.com/p/ccdaddin/" title="http://code.google.com/p/ccdaddin/" target="_blank">http://code.google.com/p/ccdaddin/</a><br /></li></ul>
]]></description><pubDate>Fri, 27 Jan 2012 15:05:25 GMT</pubDate><guid isPermaLink="false">E74EF335865DD80BA8777D0AB98D4764</guid></item><item><title><![CDATA[Die Clean Code Developer Grade]]></title><link>http://clean-code-developer.de/Grade.ashx</link><author>elias (elias)</author><description><![CDATA[<h1 class="separator">Die Clean Code Developer Grade<a class="headeranchor" id="Die_Clean_Code_Developer_Grade_10" href="#Die_Clean_Code_Developer_Grade_10" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
<table id="TocContainerTable"><tr><td><div id="TocContainer"><p class="small"><b>Inhaltsverzeichnis</b><span id="ExpandTocSpan"> [<a href="#" onclick="javascript:if(document.getElementById('Toc').style['display']=='none') document.getElementById('Toc').style['display']=''; else document.getElementById('Toc').style['display']='none'; return false;">Anzeigen/Verbergen</a>]</span></p><div id="Toc"><p><br /><b><a href="#Die_Clean_Code_Developer_Grade_10">Die Clean Code Developer Grade</a></b><br />&nbsp;&nbsp;&nbsp;<a href="#Schwarzer_A_Grad_0">Schwarzer 0. Grad</a><br />&nbsp;&nbsp;&nbsp;<a href="#Roter_B_Grad_1">Roter 1. Grad</a><br />&nbsp;&nbsp;&nbsp;<a href="#Oranger_C_Grad_2">Oranger 2. Grad</a><br />&nbsp;&nbsp;&nbsp;<a href="#Gelber_D_Grad_3">Gelber 3. Grad</a><br />&nbsp;&nbsp;&nbsp;<a href="#Grüner_E_Grad_4">Grüner 4. Grad</a><br />&nbsp;&nbsp;&nbsp;<a href="#Blauer_F_Grad_5">Blauer 5. Grad</a><br />&nbsp;&nbsp;&nbsp;<a href="#Weißer_G_Grad_6">Weißer 6. Grad</a><br />&nbsp;&nbsp;&nbsp;<a href="#Bedeutung_der_Grade_7">Bedeutung der Grade</a><br />&nbsp;&nbsp;&nbsp;<a href="#Fortbildung_8">Fortbildung</a><br />&nbsp;&nbsp;&nbsp;<a href="#Übungspraxis_9">Übungspraxis</a><br /></p></div></div></td></tr></table><br />Clean Code Developer ist man nicht einfach, sondern wird es. Es geht nämlich nicht darum, ein paar Regeln auswendig zu lernen, sondern das <a class="pagelink" href="Wertesystem.ashx" title="Wertesystem">CCD-Wertesystem</a> wirklich zu verinnerlichen. Das braucht Zeit und Übung. Deshalb haben wir das CCD-Wertesystem in Stufen unterteilt, die man als Entwickler eine nach der anderen erklimmt. Allerdings sehen wir den gesamten Prozess als Kreis: wer alle Grade bearbeitet hat, beginnt wieder von vorne.<br /><br />Jeder Entwicklungsstufe ist eine Farbe zugeordnet. Und wer an sich als Clean Code Developer auf einer Stufe arbeitet, der trägt ein <a class="pagelink" href="Armb%c3%a4nder.ashx" title="Das Clean Code Developer Armband">CCD Armband</a> als Zeichen seines Willens, sie zu meistern. Anders als im Judo-Sport entspricht die Farbe also nicht einem erreichten Grad, sondern dem in Arbeit befindlichen.<br /><br /><h2 class="separator">Schwarzer 0. Grad<a class="headeranchor" id="Schwarzer_A_Grad_0" href="#Schwarzer_A_Grad_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Den <a class="pagelink" href="Schwarzer-Grad.ashx" title="Schwarzer Grad">schwarzen Grad</a> hat jeder, der sich noch nicht auf den Weg gemacht hat. Ein schwarzes Armband signalisiert deshalb nur, dass man sich für CCD interessiert. Man kann es tragen, wenn für den ersten richtigen Grad noch nicht alle Voraussetzungen erfüllt sind.<br /><br /><h2 class="separator">Roter 1. Grad<a class="headeranchor" id="Roter_B_Grad_1" href="#Roter_B_Grad_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Der wirkliche Weg zum Clean Code Developer beginnt mit dem <a class="pagelink" href="Roter-Grad.ashx" title="Roter Grad">roten Grad</a>. Mit dem roten Grad setzt die Übungspraxis ein. Er enthält deshalb nur Elemente des CCD-Wertesystems, die absolut unverzichtbar sind. Der Einstieg soll so leicht wie möglich sein. Auf dieser Stufe geht es deshalb noch nicht so sehr um Softwareentwicklungsprinzipien, als vielmehr um den Aufbau einer fundamentalen Haltung zur Softwareentwicklung und zum Clean Code Developer.<br /><br /><h2 class="separator">Oranger 2. Grad<a class="headeranchor" id="Oranger_C_Grad_2" href="#Oranger_C_Grad_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Nachdem im roten Grad die Grundlagen für den Prozess der kontinuierlichen Verbesserung geschaffen wurden, geht es im <a class="pagelink" href="Oranger-Grad.ashx" title="Oranger Grad">orangen Grad</a> darum, einige fundamentale Prinzipien auf den Code anzuwenden und erste Erfahrungen mit dem Mittel Nr. 1 zur Produktivitätssteigerung zu gewinnen: der Automatisierung von Abläufen. Da nur korrekter Code guter Code ist, dient die Automatisierung der Korrektheitsprüfung. Es geht also nicht um eine nice-to-have Eigenschaft von Code, sondern um seine Essenz.<br /><br /><h2 class="separator">Gelber 3. Grad<a class="headeranchor" id="Gelber_D_Grad_3" href="#Gelber_D_Grad_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Der <a class="pagelink" href="Gelber-Grad.ashx" title="Gelber Grad">gelbe Grad</a> steht ganz im Zeichen automatisierter Tests. Beim orangen Grad ging es noch um die von außen ansetzbaren Integrationstests. Für sie war nicht unbedingt ein Eingriff in den Code nötig. Ab dem gelben Grad allerdings geht es nicht mehr ohne Tests unter der Oberfläche. Und nicht nur das: getestet werden sollen die kleinstmöglichen Einheiten, nicht nur funktionale Durchstiche. Das bedeutet ein Änderung der Codierungspraxis, denn sonst lassen sich einzelne Klassen nicht isoliert, d.h. unabhängig von genutzten Diensten prüfen. Deshalb gehören zum gelben Grad auch objektorientierte Prinzipien, denn nur mit ihnen ist eine Ablösung von zu testendem Code von seinem "Untergrund" möglich.<br /><br /><h2 class="separator">Grüner 4. Grad<a class="headeranchor" id="Grüner_E_Grad_4" href="#Grüner_E_Grad_4" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Im <a class="pagelink" href="Gr%c3%bcner-Grad.ashx" title="Grüner Grad">grünen Grad</a> geht es weiter mit der Automatisierung. Die ist einfach der Schlüssel zur Produktivität und Reaktionsfähigkeit. Nur wenn maximal viele Tätigkeiten in der Softwareentwicklung automatisiert sind, kann sich der CCD auf das Wesentliche konzentrieren: die Implementation von Kundenanforderungen. Ohne Automatisierung hängt die Entwicklung sonst oft an Kleinigkeiten - das kostet Zeit. Korrektheitsprüfungen und Releases sind dann mehr Strafe denn Mittel zum Erfolg. Nach der Automatisierung der Tests steht jetzt allerdings die Produktion auf dem Plan. Code am Entwicklerarbeitsplatz zu testen, ist eine Sache. Ihn auf einem unabhängigen Rechner erfolgreich zu übersetzen und zu testen, eine andere. Nur so lassen sich mehr oder weniger subtile Abhängigkeiten von den einzelnen Entwicklerarbeitsplätzen finden. Garniert wird diese Praxis dann noch mit weiteren Prinzipien zur Codestrukturierung und einem Werkzeug für bessere Architekturen.<br /><br /><h2 class="separator">Blauer 5. Grad<a class="headeranchor" id="Blauer_F_Grad_5" href="#Blauer_F_Grad_5" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Mit dem <a class="pagelink" href="Blauer-Grad.ashx" title="Blauer Grad">blauen Grad</a> geht es in die Zielgerade des CCD-Wertesystems. Die Automatisierung ist noch einen Schritt weiter zu treiben. Nach Übersetzung und Test steht jetzt das Deployment auf dem Programm. Vor allem geht es im blauen Grad aber nun um Aspekte der Softwareentwicklung jenseits von Code und Tools: CCD kümmern sich nicht nur um gute Strukturen im Kleinen, sondern planen sie von vornherein im Großen. Es geht also um Architektur. Da wir uns jedoch bewusst sind, dass keine Planung eine perfekte Lösung definieren kann, gehört nicht nur zur Architektur, sondern zur Softwareentwicklung insgesamt auch ein passendes Vorgehensmodell. Das ist iterativ und soll während der Arbeit am blauen Grad nun auch eingeübt werden.<br /><br /><h2 class="separator">Weißer 6. Grad<a class="headeranchor" id="Weißer_G_Grad_6" href="#Weißer_G_Grad_6" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Im <a class="pagelink" href="Wei%c3%9fer-Grad.ashx" title="Weißer Grad">weißen Grad</a> fließen alle Prinzipien, Regeln und Praktiken zusammen. So wie im weißen Licht alle Farben enthalten sind, so enthält der weiße Grad alle anderen Grade. Auf der Ebene des weißen Grades arbeitet ein CCD nur, wenn er ständig das ganze CcdWertesystem im Blick hat. Das macht klar, dass nur wirklich fortgeschrittene Softwareentwickler mit mehreren Jahren Erfahrung und in einer geeigneten Umgebung mit dem weißen Grad arbeiten können.<br /><br /><h2 class="separator">Bedeutung der Grade<a class="headeranchor" id="Bedeutung_der_Grade_7" href="#Bedeutung_der_Grade_7" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Die Grade drücken keinen Wert aus. Wer am blauen Grad arbeitet ist nicht "besser" oder "weiter" als jemand, der am orangen Grad arbeitet. Die Grade sind nur ein didaktisches Hilfsmittel, um die Gesamtheit des Wertesystems "einfacher verdaubar" zu machen. Die vielen Bausteine lassen sich schlicht in kleinen Happen besser aneignen, als in einem Anlauf.<br /><br />Deshalb ist es uns auch wichtig, dass jeder Interessent mit dem roten Grad beginnt. Aus didaktischen Gründen ist es der beste Einstieg - auch wenn man meint, man würde doch auch schon in der täglichen Arbeit andere Werte umsetzen. Denn unabhängig von der heutigen Projektpraxis ist es sicherlich neu, sich so bewusst mit Prinzipien und Praktiken auseinanderzusetzen. Insbesondere die tägliche Reflektion darüber ist wahrscheinlich noch nicht Gewohnheit. Um sie im Kontext "einfacher" Bausteine zu üben, eignet sich dann der rote Grad.<br /><br />Auch wenn wir verstehen, dass jeder, der das <a class="pagelink" href="Wertesystem.ashx" title="Wertesystem">Wertesystem</a> zum ersten Mal sieht, abhaken will, was er davon schon beherzigt, so ist das letztlich unerheblich. Die bewusste Praxis im Rahmen des Wertesystems ist immer neu - und sollte auch wer meint, er "verdiene" eigentlich den weißen Grad, beim roten Grad beginnen. Es geht eben nicht um "Verdienst", sondern um Iterationen und kleine Happen. Grade sind Gucklöcher auf das große Ganze.<br /><br />Wer das erste <a class="pagelink" href="Armb%c3%a4nder.ashx" title="Das Clean Code Developer Armband">Armband</a> bestellt, bestelle also am besten das rote Armband.<br /><br /><h2 class="separator">Fortbildung<a class="headeranchor" id="Fortbildung_8" href="#Fortbildung_8" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Das <a class="pagelink" href="Wertesystem.ashx" title="Wertesystem">Wertesystem</a> und die Bausteine mögen starr aussehen, wie in Stein gemeißelt. Das ist es aber nicht. Es ist immer nur vorläufig, bis wir bzw. die Community meint, dass etwas verändert werden sollte. Noch viel stärker im Fluss ist jedoch die Welt der Werkzeuge und Materialien, auf die das Wertesystem anzuwenden ist. Programmiersprachen, IDEs, Frameworks, Plattformen, Serverprodukte verändern sich ständig, kommen hinzu, fallen weg. Tendenziell wird das, was potenziell gewusst und gekonnt werden könnte immer nur mehr, viel mehr. Früher war man gut bedient mit einer Programmiersprache und deren Standardbibliothek. Heute reicht das schon lange nicht mehr.<br /><br />Da Professionalität bedeutet, informierte Entscheidungen zu treffen, kommt der CCD nicht umhin, sich ständig fortzubilden. Wahrscheinlich ist die Softwareentwicklung sogar die Branche mit der größten Notwendigkeit dazu. Aspekte der Fortbildung sind daher Bestandteile mehrerer Grade (<a class="pagelink" href="Oranger-Grad.ashx" title="Oranger Grad">Orange</a>, <a class="pagelink" href="Gelber-Grad.ashx" title="Gelber Grad">Gelb</a>, <a class="pagelink" href="Gr%c3%bcner-Grad.ashx" title="Grüner Grad">Grün</a>). Damit wollen wir deutlich machen, dass Fortbildung immer ein Thema ist, aber eben auch einer Entwicklung folgen muss. Von 0 auf 100 bei der Fortbildung in einem Grad ist nicht möglich. Nicht nur Softwareentwicklung braucht Übung, auch die Fortbildung will gelernt sein.<br /><br />In den Graden geht es aber nur um unterschiedliche Fortbildungsformen (Lesen, Networking, Veröffentlichen). Wieviel Zeit ein CCD für sie aufwenden sollte, geben sie nicht vor. Der Grund: das ist aus unserer Sicht nicht formspezifisch. Fortbildung sollte unabhängig von der Form mindestens 20% der Arbeitszeit ausmachen.<br /><br />Ja, das meinen wir ehrlich. 20% der Arbeitszeit sollte Fortbildungszeit sein. Pro 5-Tage-Woche also 1 Tag nur für die Fortbildung. Nicht weniger. Google macht vor, dass das funktioniert: "Das heißt, jeder Mitarbeiter darf 20 Prozent seiner Arbeitszeit mit Projekten verbringen, die nicht direkt mit seiner Aufgabe zu tun haben. Das wird nicht kontrolliert." (<a class="externallink" href="http://www.abendblatt.de/wirtschaft/article887630/Kostenloses-Essen-und-geschenkte-Arbeitszeit-fuer-die-Mitarbeiter.htm " title="Quelle" target="_blank">Quelle</a>: Interview mit Nordeuropa-Chef Phillip Schindler von Google im Hamburger Abendblatt, 7.11.2007)<br /><br />20% klingt dennoch sehr viel. Aber keine Angst, Fortbildung ist gar nicht so schlimm für den, der sie bezahlen soll. Denn Fortbildung ist einiges nicht, was man zunächst damit verbindet:<br /><br /><ul><li>Fortbildung ist kein Urlaub</li><li>Fortbildung ist keine Abwesenheit vom Arbeitsplatz</li><li>Fortbildung bedeutet nicht, dass kein Nutzen für Projekte gestiftet wird</li><li>Fortbildung braucht nicht zwangsläufig ein hohes Budget für Schulungen oder Software<br /></li></ul><br />Fortbildung bedeutet vor allem Spielraum für Fehler. Anders formuliert: Während 20% der Arbeitszeit sollte ein professioneller Softwareentwickler keine Angst vor Fehlern haben. Das bedeutet im Extremfall, dass die 20% ohne direkten Gewinn für ein Projekt sind. Vergleichen Sie die Fortbildung mit der Übungszeit eines Musikers. Auf der Bühne muss der Musiker performen, tunlichst ohne Fehler. Um sein Können auf gleichem Stand zu halten oder sogar zu verbessern, muss ein Musiker jedoch üben. Dabei sind Fehler ausdrücklich zugelassen, da sonst keine Weiterentwicklung möglich wäre. Es bedarf also zweier unterschiedlicher "Betriebsarten".<br /><br />Erst auf der Basis solchen Spielraums für Fehler geht es darum, wie der ausgefüllt werden könnte. Einziger Anspruch an mögliche Inhalte sollte sein, dass ein Bezug zur Arbeit erkennbar ist. Wer die 20% Spielraum für die private online Immobiliensuche oder Sport im unternehmenseigenen Fitnesscenter nutzt, bildet sich nicht wirklich fort.<br /><br />Beispiele für Fortbildungsinhalte sind:<br /><br /><ul><li>Studium von Fachpublikationen (online/offline, Blog/Zeitschrift/Buch/Video)</li><li>Ausprobieren von Gelesenem<ul><li>Technologien</li><li>Verfahren</li><li>Werkzeuge</li></ul></li><li>Besuch von Fachveranstaltungen (Schulung, Konferenz, Community-Event)</li><li>Publikation eigenen Fachwissens<ul><li>in unternehmenseigenen Medien (z.B. Projekt-Wiki)</li><li>auf öffentlichen Plattformen (Blog, Zeitschrift, Buch, Fachkonferenz)<br /></li></ul></li></ul><br />Ob Lektüre, Experimente oder Publikationen direkt mit einem Projekt im Zusammenhang stehen, ist nachrangig. Sie können, müssen aber nicht. Ein CCD kann eine Technologie mit Blick auf das Firmenprojekt evaluieren oder nur aus allgemeinem Interesse. Nutzen für das Projekt entsteht in beiden (!) Fällen. Einmal unmittelbar, einmal mittelbar. Denn jede Kenntnis einer Technologie oder eines Verfahrens, auch wenn der Einsatz im Projekt noch nicht absehbar ist, erweitert den Horizont, macht also erfahrener, optionenreicher.<br /><br />Hinweis für Entscheider: Entwickler, die sich kontinuierlich fortbilden, stellen einen Wert dar. Sie sind erfahrener, innovativer, flexibler. Das dient Ihren Produkten.<br /><br />Hinweis für Softwareentwickler: Wer sich fortbildet wird wertvoller. Er gewinnt an Erfahrung, ist nicht in einer Nische festgenagelt, gibt keine Angriffsfläche für Hype ab. Das dient der "Employability".<br /><br /><h2 class="separator">Übungspraxis<a class="headeranchor" id="Übungspraxis_9" href="#Übungspraxis_9" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Clean Code Developer zu werden braucht Zeit. Wir glauben, dass es pro Grad mit nicht weniger als 21 Tagen getan ist. Denn 21 Tage (oder 3 Wochen) - so sagt die Psychologie - brauchen Menschen, um Neues oder allgemein Veränderungen als Gewohnheiten in ihr Leben zu integrieren.<br /><br />Wer auf einer CCD-Stufe arbeitet, soll deshalb so vorgehen: Am Abend jedes Arbeitstages reflektiert der CCD darüber, ob er die Prinzipien seines Grades (und der darunter liegenden) eingehalten hat. Wenn ja, behält er das Armband an dem Arm, an dem es ist. Wenn nein, wechselt er das Armband jedoch zum anderen Arm! Das ist wichtig, denn durch den Akt des Wechselns macht sich der Entwickler bewusst, dass er und welche Prinzipien er noch besser verinnerlichen muss.<br /><br />Sobald ein Entwickler dann auf einer Stufe 21 Tage ohne Wechseln des Armbands gearbeitet hat, kann er den Grad als gemeistert ansehen, zum nächsten fortschreiten und dessen Armband überstreifen.<br /><br />Natürlich gibt es keine formale Kontrolle, ob während eines Tages wirklich alle Prinzipien beachtet worden sind. Wir stellen es also der Ehrlichkeit jedes Entwicklers sich und der CCD-Community gegenüber anheim, darüber nach bestem Wissen und Gewissen zu urteilen. Da kein Grad "besser" oder "schlechter" ist als ein anderer, lohnt sich Mogelei ohnehin nicht. Wir gehen davon aus, dass Entwickler, die den weißen Grad gemeistert haben, wieder beim roten Grad beginnen. So demonstrieren sie ihre Überzeugung, dass Softwareentwicklung ständiges Lernen ist.
]]></description><pubDate>Fri, 27 Jan 2012 10:00:20 GMT</pubDate><guid isPermaLink="false">FFBEA2ACF52FA0C3042E5ED2793CAA78</guid></item><item><title><![CDATA[Companies]]></title><link>http://clean-code-developer.de/Companies.ashx</link><author>Stefan Lieser (slieser)</author><description><![CDATA[<h1 class="separator">CCD-Firmen<a class="headeranchor" id="CCD-Firmen_2" href="#CCD-Firmen_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
Liste von Firmen, die bei ihrer Softwareentwicklung darum bemüht sind, die Clean Code Developer Prinzipien und Praktiken zu beachten.<br /><br /><b>Deutschland</b>
<ul><li><a class="externallink" href="http://www.2posiv.de/pages/Softwareentwicklung.aspx" title="2Iposiv Consulting I Software I Services" target="_blank">2Iposiv Consulting I Software I Services</a>, Berlin</li><li><a class="externallink" href="http://www.69grad.de/internetagentur/profil" title="69 Grad GmbH" target="_blank">69 Grad GmbH</a>, München</li><li><a class="externallink" href="http://www.accsone.com" title="accSone" target="_blank">accSone</a>, München</li><li><a class="externallink" href="http://www.avado.de/avado-group/avado-projects/service-technologien.html" title="avado Projects" target="_blank">avado Projects</a>, Strausberg</li><li><a class="externallink" href="http://www.capsoft.de/component/content/article/94" title="CAPSOFT UG" target="_blank">CAPSOFT UG</a>, Rust</li><li><a class="externallink" href="http://www.co-in.de/leistungen/individualsoftware.html" title="Cologne Intelligence" target="_blank">Cologne Intelligence</a>, Köln</li><li><a class="externallink" href="http://www.dennso.de/de/it-loesungen/" title="Dennso Management Consulting GmbH" target="_blank">Dennso Management Consulting GmbH</a>, Hamburg</li><li><a class="externallink" href="http://www.generic.de/de/company/profile/ccd.aspx" title="generic.de AG" target="_blank">generic.de AG</a>, Karlsruhe</li><li><a class="externallink" href="http://www.gutsch-online.de/show/german/about.aspx" title="GUTSCH-ONLINE Software GmbH" target="_blank">GUTSCH-ONLINE Software GmbH</a>, Engen</li><li><a class="externallink" href="http://www.xn--domainbrsen-xfb.biz/inhalt/cleancodedevelopment.aspx" title="INDECA GmbH" target="_blank">INDECA GmbH</a>, Heilbronn</li><li><a class="externallink" href="http://www.it-frankfurt.com/kompetenzen.html" title="IT Frankfurt GmbH" target="_blank">IT Frankfurt GmbH</a>, Frankfurt a.M.</li><li><a class="externallink" href="http://www.jastech-solutions.de/refactoring.html" title="Jastech UG" target="_blank">Jastech UG</a>, Münster</li><li><a class="externallink" href="http://www.neovelop.de/nlocalize" title="Neovelop" target="_blank">Neovelop</a>, Paderborn</li><li><a class="externallink" href="http://www.objectcode.de/metanavigation/aktuelles/artikel-view/article/objectcode-ist-jetzt-mitglied-der-clean-code-developer-inititative.html" title="ObjectCode GmbH" target="_blank">ObjectCode GmbH</a>, Lünen</li><li><a class="externallink" href="http://proserv-gmbh.de/datentechnik/index.php" title="proserv GmbH" target="_blank">proserv GmbH</a>, Remchingen-Singen</li><li><a class="externallink" href="http://www.raber-maercker.de/01_unternehmen/01_08_Zertifizierungen.html" title="Raber+Märcker GmbH" target="_blank">Raber+Märcker GmbH</a>, Stuttgart</li><li><a class="externallink" href="http://co-managed-print-service.de/?page_id=66" title="Software-Concept GmbH" target="_blank">Software-Concept GmbH</a>, Chemnitz</li><li><a class="externallink" href="http://www.sphenon.de/" title="Sphenon GmbH" target="_blank">Sphenon GmbH</a>, Hamburg</li><li><a class="externallink" href="http://consulting.wogra.com/dienstleistungen/softwareengineering" title="WOGRA Consulting GmbH" target="_blank">WOGRA Consulting GmbH</a>, Augsburg</li><li><a class="externallink" href="http://www.co-in.de/" title="Cologne Intelligence GmbH" target="_blank">Cologne Intelligence GmbH</a>, Köln<br /></li></ul><br /><b>Österreich</b><br /><br /><b>Schweiz</b>
<ul><li><a class="externallink" href="http://pcsupport.ch/de-de/softwareentwicklung.aspx" title="pcsupport.ch" target="_blank">pcsupport.ch</a>, St. Gallen</li><li><a class="externallink" href="http://www.gisler-informatik.ch/service_dev.html" title="Gisler Informatik" target="_blank">Gisler Informatik</a>, Luzern</li><li><a class="externallink" href="http://www.yooapps.com/?siteID=1369362EDAE9DAB1D4CE29B5B3A1E243" title="YooApplications AG" target="_blank">YooApplications AG</a>, Basel<br /></li></ul><br /><h2 class="separator">Aufnahme<a class="headeranchor" id="Aufnahme_0" href="#Aufnahme_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>Wer meint, eine Firma fehle in dieser Liste, wende sich einfach per Email an Ralf Westphal oder Stefan Lieser oder schreibe einen Eintrag in einer der Diskussionsgruppen. Dann nehmen wir die Firma gern in das Verzeichnis auf.<br /><br />Voraussetzung ist allerdings, dass die Firma auf ihrer Homepage ein verbales "Bekenntnis" zu Clean Code Developer unterstrichen mit dem <a class="pagelink" href="Stempel.ashx" title="Stempel">hier</a> herunterladbaren Logo abgibt und auf www.clean-code-developer.de verweist.<br /><br /><a href="Stempel.ashx" title="Stempel"><img src="GetFile.aspx?File=dotnetpro_ccd_stempel_half_size.gif" alt="CCD Stempel" /></a><br /><br /><h2 class="separator">Qualitätssicherung<a class="headeranchor" id="Qualitätssicherung_1" href="#Qualitätssicherung_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>Eine Qualitätssicherung jenseits der formalen Voraussetzung eines "CCD-Bekenntnisses" gibt es nicht. Ob und in welcher Form Firmen, die hier gelistet sind, tatsächlich nach Clean Code Developer Prinzipien und Praktiken arbeiten, wird nicht geprüft.<br /><br />Das soll aber nicht den Wert dieses Verzeichnisses schmälern. Dessen Zweck ist zunächst nämlich nur, sichtbar zu machen, dass es nicht nur Individuen, sondern auch Firmen gibt, die Wert auf innere Softwarequalität legen und sich um Weiterentwicklung bemühen. Zu einem späteren Zeitpunkt mag dann ein nächster Schritt sinnvoll sein durch eine echte Zertifizierung. Derzeit scheint ein solcher Formalismus aber noch nicht zielführend für einen möglichst breiten Einstieg in CCD.
]]></description><pubDate>Tue, 17 Jan 2012 08:35:13 GMT</pubDate><guid isPermaLink="false">FF2EA9641551A2FFE2D13DEEFB38F2B4</guid></item><item><title><![CDATA[Stempel]]></title><link>http://clean-code-developer.de/Stempel.ashx</link><author>Ralf Westphal (ralfw)</author><description><![CDATA[<h1 class="separator">Der Stempel für CCD-Beiträge<a class="headeranchor" id="Der_Stempel_für_CCD-Beiträge_0" href="#Der_Stempel_für_CCD-Beiträge_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
Die CCD-Initiative profitiert von jeder Sichtbarkeit. Ihre Berechtigung liegt geradezu darin, Prinzipien und Praktiken, die es schon vorher gab, deutlicher und breiter sichtbar zu machen. Die "Marke" CCD wird umso stärker und motiviert umso mehr Entwickler, je häufiger sie erwähnt wird.<br /><br />Ein Hilfsmittel für mehr Sichtbarkeit ist das <a class="pagelink" href="Armb%c3%a4nder.ashx" title="Das Clean Code Developer Armband">Armband</a>. Allerdings mag es nicht jeder CCDler tragen. Das ist natürlich völlig ok. Deshalb haben wir zusammen mit der <a class="externallink" href="http://www.dotnetpro.de" title="dotnetpro" target="_blank">dotnetpro</a> ein weiteres "Markenzeichen" entwickelt: einen Stempel.<br /><br />Hier die beiden Ausführungen:<br /><br /><img src="GetFile.aspx?File=dotnetpro_ccd_stempel_full_size.gif" alt="Full Size" />
<img src="GetFile.aspx?File=dotnetpro_ccd_stempel2_half_size.gif" alt="Half Size" /><br /><br />Diese Stempel kann jeder, der mag, auf seine Beiträge "drucken", die sich mit CCD-Themen beschäftigen. Woimmer CCD drin ist, da soll einer der Stempel auch drauf sein. Hier ein Beispiel aus der dotnetpro 8/2009:<br /><br /><img src="GetFile.aspx?File=abb1.jpg" alt=" " /><br /><br />Je häufiger der Stempel zu sehen ist, desto mehr Sichtbarkeit und Kohärenz bekommt die CCD-Botschaft. Der Wiedererkennwert ist hoch.<br /><br />Aber, wie gesagt, es geht bei diesem Stempel nicht um die Kennzeichnung einer generellen Bekenntnis zu CCD, sondern um konkrete Beiträge, die sich mit CCD-Werten oder -Bausteinen beschäftigen oder bewusst "CCD-konform" ausgelegt sind.<br /><br />Die Stempel können in höherer Auflösung <a class="internallink" href="GetFile.aspx?File=%2fdownload%2fccd-stempel-einzeilig.gif" title="hier">hier</a> und <a class="internallink" href="GetFile.aspx?File=%2fdownload%2fccd-stempel-zweizeilig.jpg" title="hier">hier</a> runtergeladen werden.<br /><br /><h1 class="separator">Das Banner für´s CCD-Committment<a class="headeranchor" id="Das_Banner_für´s_CCD-Committment_1" href="#Das_Banner_für´s_CCD-Committment_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>Wer sich insgesamt als CCDler "outen" möchte - z.B. in seinem Blog - oder seine Firma als "CCD-freundlich" kennzeichnen möchte, <a class="externallink" href="http://ralfw.blogspot.com/2009/05/willen-zur-softwarequalitat-bekunden.html" title="so wie es schon einige getan haben" target="_blank">so wie es schon einige getan haben</a>, der sollte ebenfalls den <a class="pagelink" href="Companies.ashx" title="Companies">Stempel benutzen</a>.<br /><br /><h1 class="separator">Desktop-Hintergründe<a class="headeranchor" id="Desktop-Hintergründe_2" href="#Desktop-Hintergründe_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>Neben Tetraedern und Pyramiden und Mindmaps gibt es jetzt auch Desktop-Hintergrundbilder mit den CCD-Bausteinen. Ralf hat schon darüber <a class="externallink" href="http://ralfw.blogspot.com/2009/09/clean-code-developer-bausteine-immer.html" title="in seinem Blog berichtet" target="_blank">in seinem Blog berichtet</a>.<br /><br /><img src="GetFile.aspx?File=ccdDesktopBackgroundImageSample.JPG" alt="Full Size" /><br /><br />Herunterladen kann man sich die Hintergrundbilder in verschiedenen Auflösungen <a class="externallink" href="http://www.ralfw.de/download/ccdDesktops.zip" title="von hier" target="_blank">von hier</a>. Sie liegen dort in einigen typischen Auflösungen vor - aber wer eine andere braucht, kann sie sich selbst herstellen. Dafür gibt es den Hintergrund als Vektor-PDF. Das kann man z.B. in Photoshop laden und dann skalieren.<br /><br /><h1 class="separator">Postkarten<a class="headeranchor" id="Postkarten_3" href="#Postkarten_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>Zunächst als Marketinginstrument für die gute CCD-Sache gedacht, haben sich inzwischen die CCD-Postkarten als Lernhilfsmittel nützlich erwiesen.<br /><br /><img src="GetFile.aspx?File=ccdPostkartenSample.jpg" alt="Postkarten" /><br /><br />Wir haben für jeden Grad eine Postkarten mit den "Sprechblasen" des Desktopbildes gestalten lassen. Wer mag, kann sie sich auf A4 oder A5 oder sogar noch kleiner als Spickzettel ausdrucken. Die Teilnehmer in CCD-Trainings tun das gern. <a class="externallink" href="http://www.ralfw.de/download/ccdPostkarten.zip" title="Hier die PDFs zum Download." target="_blank">Hier die PDFs zum Download.</a>
]]></description><pubDate>Thu, 12 Jan 2012 18:31:15 GMT</pubDate><guid isPermaLink="false">6DD17FB6A404F04F0B4D9C199BA01F32</guid></item><item><title><![CDATA[Berichte]]></title><link>http://clean-code-developer.de/Berichte.ashx</link><author>jr (jrueckert)</author><description><![CDATA[<h1 class="separator">Berichterstattung über CCD<a class="headeranchor" id="Berichterstattung_über_CCD_4" href="#Berichterstattung_über_CCD_4" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
Wo wird über das Clean Code Developer Wertesystem berichtet? Wer kommentiert es? Wer wendet es an? Hier Links zu Beiträgen, von denen wir Kenntnis erhalten haben.<br /><br /><h2 class="separator">Berichte über CCD<a class="headeranchor" id="Berichte_über_CCD_0" href="#Berichte_über_CCD_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><ul><li><a class="externallink" href="http://programm.froscon.org/2011/events/870.html" title="Clean Code muss sein, aber wie?" target="_blank">Clean Code muss sein, aber wie?</a>, Vortrag bei <a class="externallink" href="http://programm.froscon.org" title="FrOSCon" target="_blank">FrOSCon</a> August 2011</li><li><a class="externallink" href="http://it-republik.de/jaxenter/java-magazin-ausgaben/HTML-5-000422.html" title="Clean Code muss sein, aber wie?" target="_blank">Clean Code muss sein, aber wie?</a>, erschienen in Javamagazin Dezember 2010</li><li><a class="externallink" href="http://it-republik.de/jaxenter/artikel/Die-Clean-Code-Developer-Initiative-3157.html" title="Nicht lang´ schnacken, Kopf in´ Nacken" target="_blank">Nicht lang´ schnacken, Kopf in´ Nacken</a>, erschienen beim jaxenter im Juni 2010</li><li><a class="externallink" href="http://www.microsoft.com/germany/msdn/video/show.mspx?id=msdn_de_40000" title="Video-Interview mit Ralf Westphal" target="_blank">Video-Interview mit Ralf Westphal</a>, msdn tv 2.6.2010</li><li><a class="externallink" href="http://vksi.de/fileadmin/downloads/magazin/VKSIMagazin-1002m.pdf" title="Interview mit Stefan Lieser" target="_blank">Interview mit Stefan Lieser</a>, VKSI Magazin, S. 28ff</li><li><a class="externallink" href="http://scrumcenter.com/?q=node/40" title="Clean code and the Scrum roots" target="_blank">Clean code and the Scrum roots</a>, Christoph Mathis: Positive Erwähnung von CCD in der englischsprachigen Scrum-Community inkl. engl. CCD-Mindmap</li><li><a class="externallink" href="http://www.heise.de/developer/Ralf-Westphal-im-Gespraech-ueber-Clean-Code-Developer<strike>/artikel/143437" title="Interview mit Ralf Westphal zu CCD" target="_blank">Interview mit Ralf Westphal zu CCD</a>, heise Developer</li><li><a class="externallink" href="http://blogs.msdn.com/dparys/archive/2009/07/28/community-stefan-lieser-ber-clean-code-developer.aspx" title="Interview mit Stefan Lieser zu CCD" target="_blank">Interview mit Stefan Lieser zu CCD</a>, Video von Dariusz Parys</li><li><a class="externallink" href="http://www.heise.de/developer/JUGC-Event-Struts-2-Gradle-Rock-Star-Programmers-JSF-2-im-Fokus</strike>/artikel/136649" title="Heise Developer zum Lightning Talk bei der JUGC" target="_blank">Heise Developer zum Lightning Talk bei der JUGC</a></li><li><a class="externallink" href="http://www.sodthis.com/podcast/2009/03/13/the-first-sod-this-podcast-interview-wit" title="Sod This Podcast" target="_blank">Sod This Podcast</a>, Oliver Sturm und Gary Short</li><li>Erik Bollow<ul><li><a class="externallink" href="http://blog.bollow.name/2009/03/now-working-on-ccd-orange-degree/" title="Now working on CCD orange degree" target="_blank">Now working on CCD orange degree</a></li><li><a class="externallink" href="http://blog.bollow.name/2009/01/clean-code-as-fundament-for-professional-software-development/" title="Clean Code as fundament for professional software development" target="_blank">Clean Code as fundament for professional software development</a></li></ul></li><li><a class="externallink" href="http://www.heise.de/developer/Clean-Code-Developer-Forum-fuer-professionionelle-Softwareentwicklung--/news/meldung/133625" title="Meldung bei Heise Developer" target="_blank">Meldung bei Heise Developer</a></li><li><a class="externallink" href="http://baerlin.in-dsl.de/home/content/view/263/1/" title="http://baerlin.in-dsl.de/home/content/view/263/1/" target="_blank">http://baerlin.in-dsl.de/home/content/view/263/1/</a>, Michael Kovar</li><li><a class="externallink" href="http://www.altdotnet.de/OnlineMeeting_090209.ashx" title="3. Online Meeting ALT.NET DE: Clean Code Developer" target="_blank">3. Online Meeting ALT.NET DE: Clean Code Developer</a></li><li>Michael Minutillos Blog<ul><li><a class="externallink" href="http://wolfbyte-net.blogspot.com/2009/01/clean-code-developer-grades-black.html" title="Clean Code Developer Grades - Black Degree" target="_blank">Clean Code Developer Grades - Black Degree</a></li><li><a class="externallink" href="http://wolfbyte-net.blogspot.com/2009/01/ccd-red-degree-principle-staying-dry.html" title="CCD Red Degree Principle - Staying DRY" target="_blank">CCD Red Degree Principle - Staying DRY</a></li></ul></li><li><a class="externallink" href="http://groups.google.de/group/software_craftsmanship/browse_thread/thread/cf75a6d4c872a667" title="Diskussion im Software Craftsmanship Forum" target="_blank">Diskussion im Software Craftsmanship Forum</a></li><li>Alexander Schatten, <a class="externallink" href="http://best-practice-software-engineering.blogspot.com/2009/01/clean-code-developer.html" title="Clean Code Developer" target="_blank">Clean Code Developer</a>, Blog</li><li>Ralf Westphal, <a class="externallink" href="http://www.dotnetpro.de/articles/onlinearticle2870.aspx" title="Auf zu mehr Professionalität" target="_blank">Auf zu mehr Professionalität</a>, dotnetpro 2/09</li><li>dotnetpro, <a class="externallink" href="http://www.dotnetpro.de/newsgroups/newsgroupthread.aspx?id=7492" title="Online News" target="_blank">Online News</a></li><li>Stefan Lieser, <a class="externallink" href="http://www.lieser-online.de/blog/?p=145" title="http://www.lieser-online.de/blog/?p=145" target="_blank">http://www.lieser-online.de/blog/?p=145</a>, Blog</li><li>Ralf Westphal, <a class="externallink" href="http://ralfw.blogspot.com/2008/12/clean-code-developer-ein-weg-zu-mehr.html" title="Clean Code Developer - Ein Weg zu mehr Professionalität" target="_blank">Clean Code Developer - Ein Weg zu mehr Professionalität</a>, Blog</li><li>Jörg Rückert, <a class="externallink" href="http://java-ccd.blogspot.com" title="Java Blog für Clean Code Developer" target="_blank">Java Blog für Clean Code Developer</a>, Blog<br /></li></ul><br /><h2 class="separator">Anwendungen von CCD<a class="headeranchor" id="Anwendungen_von_CCD_1" href="#Anwendungen_von_CCD_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><ul><li>Dariusz Parisz´ Blog, <a class="externallink" href="http://blogs.msdn.com/dparys/archive/2009/01/20/clean-code-mein-versuch-daran-zu-arbeiten.aspx" title="Clean Code – Mein Versuch daran zu arbeiten" target="_blank">Clean Code – Mein Versuch daran zu arbeiten</a><br /></li></ul><br /><h2 class="separator">CCD in Usergroups<a class="headeranchor" id="CCD_in_Usergroups_2" href="#CCD_in_Usergroups_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><ul><li>.NET Developer Group Ulm <a class="externallink" href="http://www.dotnet-ulm.de/Cleancodedeveloper.aspx" title="http://www.dotnet-ulm.de/Cleancodedeveloper.aspx" target="_blank">http://www.dotnet-ulm.de/Cleancodedeveloper.aspx</a><ul><li><a class="externallink" href="http://www.artiso.com/ProBlog/PermaLink,guid,50e0823f-7eaa-45a3-86ae-66e2bdd6a795.aspx Anündigung" title="http://www.artiso.com/ProBlog/PermaLink,guid,50e0823f-7eaa-45a3-86ae-66e2bdd6a795.aspx Anündigung" target="_blank">http://www.artiso.com/ProBlog/PermaLink,guid,50e0823f-7eaa-45a3-86ae-66e2bdd6a795.aspx Anündigung</a></li></ul></li><li>.NET Usergroup Braunschweig, !BootCamp zum Thema CCD<ul><li><a class="externallink" href="http://blog.lars-keller.net/2009/08/20/Zweites+Bootcamp+Bei+Der+DNUG+Braunschweig+Software+Design+Principles+CCD.aspx" title="http://blog.lars-keller.net/2009/08/20/Zweites+Bootcamp+Bei+Der+DNUG+Braunschweig+Software+Design+Principles+CCD.aspx" target="_blank">http://blog.lars-keller.net/2009/08/20/Zweites+Bootcamp+Bei+Der+DNUG+Braunschweig+Software+Design+Principles+CCD.aspx</a><br /></li></ul></li></ul><br /><h2 class="separator">CCD Vorträge<a class="headeranchor" id="CCD_Vorträge_3" href="#CCD_Vorträge_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><ul><li><a class="externallink" href="http://www.loroma.com/loroma/movie.faces?movie=16300#Clean-Code-Developer-1236503339847" title="Video eines Vortrags von Stefan Lieser und Ralf Westphal" target="_blank">Video eines Vortrags von Stefan Lieser und Ralf Westphal</a> in der Fachbuchhandlung Lehmanns in Hamburg am 4.3.09</li><li><a class="externallink" href="http://www.loroma.com/loroma/movie.faces?movie=16600#Clean-Code-Developer-II-1245191816972" title="Video eines CCD-Vortrags von Ralf Westphal" target="_blank">Video eines CCD-Vortrags von Ralf Westphal</a> an der HAW Hamburg am 8.6.2009<br /></li></ul>
]]></description><pubDate>Fri, 09 Dec 2011 18:33:34 GMT</pubDate><guid isPermaLink="false">DEBC6C314B702B7CE70E9FF697C787FA</guid></item><item><title><![CDATA[Roter Grad]]></title><link>http://clean-code-developer.de/Roter-Grad.ashx</link><author>Stefan Lieser (slieser)</author><description><![CDATA[<h1 class="separator">Roter 1. Grad der Clean Code Developer Initiative<a class="headeranchor" id="Roter_B_Grad_der_Clean_Code_Developer_Initiative_11" href="#Roter_B_Grad_der_Clean_Code_Developer_Initiative_11" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>Mit dem roten Grad beginnt der Weg des Clean Code Developers. Ab hier gilt es, einen ersten Teil der Clean Code Developer Bausteine in die tägliche Arbeit einzubringen und immer wieder zu üben. Der rote Grad ist so gestaltet, dass jeder Entwickler hier mit minimalem Aufwand einsteigen kann. Veränderungen an den Projektverhältnissen sollten kaum nötig sein. Seinen Weg als Clean Code Developer kann also jeder auch "in aller Stille" beginnen.<br /><br /><table id="TocContainerTable"><tr><td><div id="TocContainer"><p class="small"><b>Inhaltsverzeichnis</b><span id="ExpandTocSpan"> [<a href="#" onclick="javascript:if(document.getElementById('Toc').style['display']=='none') document.getElementById('Toc').style['display']=''; else document.getElementById('Toc').style['display']='none'; return false;">Anzeigen/Verbergen</a>]</span></p><div id="Toc"><p><br /><b><a href="#Roter_B_Grad_der_Clean_Code_Developer_Initiative_11">Roter 1. Grad der Clean Code Developer Initiative</a></b><br />&nbsp;&nbsp;&nbsp;<a href="#Prinzipien_9">Prinzipien</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Don´t_Repeat_Yourself_DRY_0">Don´t Repeat Yourself (DRY)</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Keep_it_simple_stupid_KISS_1">Keep it simple, stupid (KISS)</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Vorsicht_vor_Optimierungen!_2">Vorsicht vor Optimierungen!</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Favour_Composition_over_Inheritance_FCoI_3">Favour Composition over Inheritance (FCoI)</a><br />&nbsp;&nbsp;&nbsp;<a href="#Praktiken_10">Praktiken</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Die_Pfadfinderregel_beachten_4">Die Pfadfinderregel beachten</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Root_Cause_Analysis_5">Root Cause Analysis</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Ein_Versionskontrollsystem_einsetzen_6">Ein Versionskontrollsystem einsetzen</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Einfache_Refaktorisierungsmuster_anwenden_7">Einfache Refaktorisierungsmuster anwenden</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Täglich_reflektieren_8">Täglich reflektieren</a><br /></p></div></div></td></tr></table><br /><h2 class="separator">Prinzipien<a class="headeranchor" id="Prinzipien_9" href="#Prinzipien_9" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Don´t Repeat Yourself (DRY)<a class="headeranchor" id="Don´t_Repeat_Yourself_DRY_0" href="#Don´t_Repeat_Yourself_DRY_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Jede Doppelung von Code oder auch nur Handgriffen leistet Inkonsistenzen und Fehlern Vorschub.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>++</td><td>+</td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Das DRY-Prinzip lautet: <i>Don't Repeat Yourself</i> – Wiederhole dich nicht. Es gilt seit den Anfängen der Softwareentwicklung – sonst gäbe es keine Unterprogramme und keine Datennormalisierung. Dennoch ist es wahrscheinlich das am meisten missachtete Prinzip. Denn nichts ist einfacher, als Code durch Copy&Paste zu wiederholen. Gerade dann, wenn es mal schnell gehen soll, passiert das allzuoft.<br /><br />Clean Code Developer üben sich im roten Grad daher darin, dieses Prinzip stets zu beachten. Sie sind sich bewusst, wann sie Code oder andere Artefakte wiederholen. Sie erkennen solche Wiederholungen, die sie selbst oder andere erzeugt haben. Sie bereinigen Wiederholungen durch Refaktorisierungen – wenn keine anderen Prinzipien oder Beschränkungen dagegen sprechen.
</div><br /><br /><h3 class="separator">Keep it simple, stupid (KISS)<a class="headeranchor" id="Keep_it_simple_stupid_KISS_1" href="#Keep_it_simple_stupid_KISS_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Wer mehr tut als das Einfachste, lässt den Kunden warten und macht die Lösung unnötig kompliziert.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>++</td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Oder um es mit Albert Einsteins Worten zu sagen: "Alles sollte so einfach wie möglich gemacht werden, aber nicht einfacher.". Für die Evolvierbarkeit des Codes ist zwingende Voraussetzung, dass der Code verständlich ist. Eine einfache, klare und leicht verständliche Lösung sollte daher immer bevorzugt werden. Wenn man seinen eigenen Code nach kurzer Zeit schon nicht mehr versteht, sollten die Alarmglocken klingen. Noch wichtiger aber ist, dass auch andere Entwickler den Code schnell verstehen können. Dabei helfen regelmäßige Reviews und Pair Programming. Sie dienen der Kontrolle, ob tatsächlich die einfachste Lösung verwendet wurde.<br /><br />Gerade in technischen Details steckt die Versuchung, eine komplizierte Lösung anzustreben. Das Bekannte, naheliegende ist manchmal zu "langweilig" – und schon hat sich eine komplizierte Lösung eingeschlichen. Wenn die einfache Lösung auch funktioniert, sollte ihr Vorrang gewährt werden. Das gleiche gilt für Datenstrukturen. Wenn ein IEnumerable reicht, sollte keine ICollection oder sogar IList verwendet werden.
</div><br /><br /><h3 class="separator">Vorsicht vor Optimierungen!<a class="headeranchor" id="Vorsicht_vor_Optimierungen!_2" href="#Vorsicht_vor_Optimierungen!_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Optimierungen kosten immer viel Aufwand. Wer Vorsicht walten lässt, spart oft wertvolle Ressourcen für das, was dem Kunden wirklich nützt.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td></td><td>++</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br /><a class="externallink" href="http://en.wikipedia.org/wiki/Michael_A._Jackson" title="M.A. Jackson" target="_blank">M.A. Jackson</a>:
<div class="box">Rules of Optimization:<br />
Rule 1: Don't do it.<br />
Rule 2 (for experts only): Don't do it yet.</div><br /><a class="externallink" href="http://en.wikipedia.org/wiki/William_Wulf" title="W.A. Wulf" target="_blank">W.A. Wulf</a>:
<div class="box">More computing sins are committed in the name of efficiency
(without necessarily achieving it)
than for any other single reason – including blind stupidity.</div><br />Im Vordergrund steht immer die Verständlichkeit von Code. Optimierter Code ist aber oft alles andere als lesbar. Indem er auf das absolut Notwendige in kürzester Form reduziert ist, mag er zwar die funktionalen und nicht funktionalen Anforderungen des Kunden erfüllen – doch er spiegelt sie meist nicht mehr verständlich wider. Das ist kontraproduktiv im Sinne der meist gewünschten Langlebigkeit einer Software.
Donald Knuth schrieb bereits 1974: "<i>We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.</i>" (Knuth, Donald. <a class="externallink" href="http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf" title="Structured Programming with go to Statements" target="_blank">Structured Programming with go to Statements</a>, ACM Journal Computing Surveys, Vol 6, No. 4, Dec. 1974. p.268.)<br /><br />Die Pfadfinderregel ist also nicht so gemeint, dass immer weiter nach Codeoptimierungen gestrebt werden sollte. Sie bezieht sich vielmehr auf deren Gegenteil: Verständlichkeit und Evolvierbarkeit.<br /><br />Wenn es dem Clean Code Developer also in den Fingern zuckt, weil er denkt, er könne doch noch ein Quäntchen Performance durch eine Optimierung herausholen, dann sollte er mindestens zweimal überlegen. Zum einen würde er dadurch die Verständlichkeit verschlechtern, zum anderen aber ist es wahrscheinlich, dass solche Optimierung aus mehreren Gründen gar nicht nötig ist.
Ist die Performanceschwäche nicht nur punktuell und ein Sonderfall, wird sich die nächste größere Refaktorisierung ihrer wahrscheinlich ohnehin annehmen, denn dann liegt ihr ein grundsätzliches Strukturproblem zugrunde. Oder die nächste Hardwaregeneration bügelt den Performanceknick aus. Oder der Kunde fühlt sich durch ihn gar nicht gestört. Ohnehin muss der Kunde die Forderung nach der Optimierung gestellt haben. Keine Codeveränderung ohne vom Kunden erwarteten Nutzen. Denn nur für ihn ist er bereit zu zahlen.<br /><br />Der Regel, sich im Zweifelsfall gegen Optimierungen zu entscheiden, liegt somit eine noch fundamentalere zugrunde: YAGNI - <i>You ain't gonna need it</i>. Sie ist in ihrer vollen Ausprägung allerdings erst Bestandteil des <a class="pagelink" href="Blauer-Grad.ashx" title="Blauer Grad">blauen Grades</a>.<br /><br />PS: Wenn denn entgegen allen Warnungen und Bedenken gerade eine Performanceoptimierung unumgänglich ist, dann sollte sie immer nur aufgrund einer detaillierten Analyse mit einem Profiler begonnen werden. Denn nur wer mit einem Profiler nachvollziehbar Performance-Engpässe lokalisiert hat, kann während und nach der Optimierung prüfen, ob und inwiefern er sie geweitet hat.
</div><br /><br /><h3 class="separator">Favour Composition over Inheritance (FCoI)<a class="headeranchor" id="Favour_Composition_over_Inheritance_FCoI_3" href="#Favour_Composition_over_Inheritance_FCoI_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Komposition fördert die lose Kopplung und die Testbarkeit eines Systems und ist oft flexibler.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td></td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Für die Wiederverwendung von Funktionalität kennt die Objektorientierte Programierung (OOP) zwei sehr bekannte Kandidaten: Die Vererbung (whitebox – reuse) und die Komposition (blackbox – reuse). Verwendet man Funktionalität wieder durch das Ableiten von einer Klasse, so ist die Subklasse abhängig von der Elternklasse. Dies macht ein System in vielen Fällen unnötig komplex, schlechter testbar und erschwert das Austauschen von Funktionalität zur Laufzeit. CCD hat für das korrekte Ableiten das Liskov Substitution Prinzip (LSP) bereit, das es dabei zu befolgen gilt.<br /><br />Bei der Komposition verwendet eine Klasse eine andere. Verwendet man dazu eine klar definierte Schnittstelle, fördert das die Entkopplung. Auch können verschiedene Implementationen einfach ausgetauscht werden. Bevor man sich also der Liskov Substitution stellt, fordert Favour Composition over Inheritance, sich die Frage zu stellen, ob man der Komposition nicht Vorrang geben kann.<br /><br />"<i>Because inheritance exposes a subclass to details of its parent's implementation, it's often said that 'inheritance breaks encapsulation</i>'". (Gang of Four 1995:19)
</div><br /><br /><h2 class="separator">Praktiken<a class="headeranchor" id="Praktiken_10" href="#Praktiken_10" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Die Pfadfinderregel beachten<a class="headeranchor" id="Die_Pfadfinderregel_beachten_4" href="#Die_Pfadfinderregel_beachten_4" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Jede Beschäftigung mit einem Gegenstand macht ihn zumindest ein klein wenig besser. Ganz ohne bürokratische Planung. Fundament und Graswurzelansatz für mehr Qualität.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td></td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Das Clean Code Developer Wertesystem lässt sich nicht mit einem Mal etablieren. Dafür braucht es Zeit. Vor allem, da ein Clean Code Developer selten auf einer grünen Wiese und auch noch allein arbeitet, ist es schwer, die Prinzipien auf eine gesamte Codebasis anzuwenden. Wir glauben daher, dass es wichtig ist, sich nicht zu hohe Ziele zu setzen. Viel realistischer und motivierender ist es, nur kleine Fortschritte anzustreben – dafür aber kontinuierliche.<br /><br />Zum Fundament des Clean Code Development gehört deshalb für uns die Pfadfinderregel. Sie findet sich auch in <a class="externallink" href="http://www.amazon.de/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" title="Clean Code" target="_blank">Clean Code</a> und lautet: <i>Hinterlasse einen Ort immer in einem besseren Zustand als du ihn vorgefunden hast.</i><br /><br />Auf die Softwareentwicklung angewandt bedeutet das: Clean Code Developer hinterlassen Code immer in einem "besseren Zustand" als sie ihn vorgefunden haben. Nach getaner Arbeit stimmt der Code also mit dem Clean Code Development Wertesystem mehr überein als vorher.<br /><br />Was ein Clean Code Developer an ihm dafür getan hat, ist situations-/codeabhängig - und wird natürlich auch durch den Grad bestimmt, an dem er arbeitet. Im roten Grad achtet ein Clean Code Developer z.B. darauf, dass Code, der noch nicht im Repository der Versionsverwaltung war, nun auch dort abgelegt ist. Und er achtet darauf, dass Wiederholungen jeder Art – also Verletzungen des DRY-Prinzips – "ausgebügelt" werden.<br /><br />Wo ein Clean Code Developer Suboptimalitäten im Sinne des CCD-Wertesystems feststellt, bemüht er sich also stetig darum, sie zu verbessern. In kleinen Schritten. Und natürlich bemüht er sich, Suboptimalitäten von vornherein zu vermeiden. Wie gesagt: immer auf der Stufe seiner Entwicklung.<br /><br />Diese Maxime steht am Anfang der Entwicklung des Clean Code Developers eingedenk der <a class="externallink" href="http://de.wikipedia.org/wiki/Broken-Windows-Theorie" title="Broken Windows Theorie" target="_blank">Broken Windows Theorie</a>. Nach ihr beginnt der Verfall von Qualität im allgemeinen Sinn mit Kleinigkeiten, die nur lange genug unbeachtet bleiben.<br /><br />Wenn Clean Code Developer jedoch nach der Pfadfinderregel arbeiten, kommt es gar nicht erst zu "Broken Windows" – vorhandene werden eines nach dem anderen repariert. "Risse und Unebenheiten" im Code schließt die Pfadfinderregel konsequent auf der Basis des CCD-Wertesystems, sodass sich keine weiteren "Ablagerungen" ansammeln können. Sie wirkt damit proaktiv einer Code-Erosion entgegen. Das halten wir für so fundamental, dass wir sie in den roten Grad aufgenommen haben.<br /><br /><h3 class="separator">Root Cause Analysis<a class="headeranchor" id="Root_Cause_Analysis_5" href="#Root_Cause_Analysis_5" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Symptome behandeln bringt vielleicht schnell eine Linderung – langfristig kostet es aber mehr Aufwand. Wer stattdessen unter die Oberfläche von Problemen schaut, arbeitet am Ende effizenter.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td></td><td></td><td>++</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Regel vom ersten Tag als Clean Code Developer an sollte sein, bei Problemen immer intensiv nach der wahren Wurzel des Übels zu suchen. Clean Code Developer geben sich nicht mit einer Symptomkur zufrieden.
Beispiel: Die Sortierung von Daten im Speicher ist zu langsam. Eine oberflächliche Kur würde jetzt daran gehen, einzelne Anweisungen oder Anweisungsblöcke zu beschleunigen. Vielleicht wird der Einsatz von unsafe Code probiert, vielleicht eine Parallelisierung. Eine nähere Problemanalyse jedoch hätte ergeben, dass ein suboptimaler Algorithmus die Wurzel des Übels ist. Schwer verständliche Optimierungen auf niedriger Abstraktionsebene können also vermieden werden. Ein besserer Algorithmus ist die saubere Lösung.<br /><br />Wurzelproblemanalyse ist also ein Dienst an der Verständlichkeit und am Aufwand. Denn bei Kenntnis des Wurzelproblems ist die Bereinigung meist weniger aufwändig als eine Symptomkur. Stößt der Clean Code Developer auf ein Problem, so hält er also als erstes inne, um sich eine Chance zu geben, hinter die Symptome zu schauen.<br /><br />Die Root Cause Analysis ist auch unter dem Begriff Five Why's bekannt. Dieser Begriff stammt aus der Terminologie des Toyota Produktions Systems (TPS). Die Grundidee: frage mindestens fünf mal "Warum?".<br /><br /><h3 class="separator">Ein Versionskontrollsystem einsetzen<a class="headeranchor" id="Ein_Versionskontrollsystem_einsetzen_6" href="#Ein_Versionskontrollsystem_einsetzen_6" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Angst vor Beschädigung eines "running system" lähmt die Softwareentwicklung. Mit einer Versionsverwaltung ist solche Angst unbegründet. Die Entwicklung kann schnell und mutig voranschreiten.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td></td><td></td><td>++</td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Unabdingbare Voraussetzung für jeden Clean Code Developer ist es, seinen Code unter den Schutz eines Versionskontrollsystems zu stellen. Ob das Mercurial, Git, Subversion, VSS, TFS oder Vault ist, spielt dabei keine Rolle. Wir meinen nur, dass heute keine Arbeit an Code mehr durchgeführt werden sollte, ohne ihn in einem Versionskontrollsystem zu pflegen. Der Grund dafür ist ganz simpel: Ein Versionskontrollsystem befreit von Angst. Und Angstfreiheit ist nötig, um mutig die Prinzipien und Praktiken des CCD-Wertesystems umzusetzen.<br /><br />Ein Versionskontrollsystem nimmt die Angst, etwas falsch und damit kaputt zu machen. Wenn Code in ihm gehalten wird, kann jeder CCD den Code nach Belieben verändern, ohne befürchten zu müssen, einen erreichten Stand zu zerstören. Nichts geht verloren. Das Versionskontrollsystem ist wie eine Zeitmaschine für Code.<br /><br />Damit ist ein Versionskontrollsystem die allerbeste Grundlage für alles Lernen. Denn Lernen bedeutet Fehler machen. Mit einem Versionkontrollsystem als Sicherheitsnetz können wir uns alle Fehler erlauben. Deshalb: Erste Voraussetzung für den Einstieg ins Clean Code Development ist der ständige Gebrauch eines Versionskontrollsystems.<br /><br />Wo das im Projekt nicht möglich ist, sehen wir das Fundament für Clean Code Development abwesend. Wir würden auch nicht verstehen, warum der Einsatz eines Versionskontrollwerkzeuges nicht möglich sein sollte. Kosten müssen dafür nicht anfallen und der Einarbeitungsaufwand in die einfachsten Funktionen ist minimal. CCD schreibt ja keine bestimmte Nutzung eines Versionskontrollsystems vor, sondern nur, dass eines benutzt werden muss.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Einfache Refaktorisierungsmuster anwenden<a class="headeranchor" id="Einfache_Refaktorisierungsmuster_anwenden_7" href="#Einfache_Refaktorisierungsmuster_anwenden_7" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Code verbessern ist leichter, wenn man typische Verbesserungshandgriffe kennt. Ihre Anwendungsszenarien machen sensibel für Schwachpunkte im eigenen Code. Als anerkannte Muster stärken sie den Mut, sie anzuwenden.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td></td><td></td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Um Code immer ein wenig besser zu hinterlassen, als man ihn vorgefunden hat, sind mehr oder weniger große Eingriffe nötig. Die kann ein Clean Code Developer dank des Versionskontrollsystems angstfrei vornehmen. Doch wie macht er sich die Arbeit möglichst einfach?<br /><br />Das Schlüsselwort lautet "Refaktorisierung". <a class="externallink" href="http://martinfowler.com/" title="Martin Fowler" target="_blank">Martin Fowler</a> hat das <a class="externallink" href="http://www.amazon.de/Refactoring-Studentenausgabe-vorhandener-verbessern-Programmers/dp/3827322782" title="Refaktorisieren/Refactoring" target="_blank">Refaktorisieren/Refactoring</a> in seinem gleichnamigen Buch als grundlegende Technik zur Erhöhung der Codequalität beschrieben. Er definiert darin eine Anzahl von Codeveränderungsmustern, um "code smells", d.h. suboptimale Strukturen oder allgemeiner Missachtungen von Prinzipien, zu bereinigen.<br /><br />Für den roten Grad ist darin vor allem die Refaktorisierung <a class="externallink" href="http://martinfowler.com/refactoring/catalog/extractMethod.html" title="Methode extrahieren" target="_blank">Methode extrahieren</a> relevant, um dem DRY-Prinzip zu genügen. Die wenden Clean Code Developer an, um mehrfach vorkommenden Code in eine Methode zu extrahieren, die statt seiner an den Wiederholungsorten aufgerufen wird.<br /><br />Als zweite Refaktorisierung sollte bei der Arbeit am roten Grad das <a class="externallink" href="http://martinfowler.com/refactoring/catalog/renameMethod.html" title="Umbenennen" target="_blank">Umbenennen</a> wo nötig eingesetzt werden. Sie passt zur Pfadfinderregel, denn eine oft anzutreffende "Unsauberkeit" im Quellcode sind kryptische Namen.<br /><br />Refaktorisierungen können von Hand angewandt werden, doch es gibt auch Werkzeugunterstützung. Moderne IDEs wie Visual Studio bieten einige Refactoringmuster, weitere Tools listet unsere <a class="pagelink" href="Tools.ashx" title="Tools">Werkzeugliste</a>.<br /><br />"Refactoring" wie "Clean Code" gehören zur <a class="pagelink" href="Literaturliste.ashx" title="Literaturliste">Pflichtlektüre</a> jedes Clean Code Developers ab dem roten Grad. <br /><br /><h3 class="separator">Täglich reflektieren<a class="headeranchor" id="Täglich_reflektieren_8" href="#Täglich_reflektieren_8" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Keine Verbesserung, kein Fortschritt, kein Lernen ohne Reflexion. Aber nur, wenn Reflexion auch eingeplant wird, findet sie unter dem Druck des Tagesgeschäftes auch statt.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td></td><td></td><td></td><td>++</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Im Zentrum von CCD steht die persönliche Entwicklung. Es geht also um Veränderung: Mit jedem Tag soll sich das CCD-Wertesystem ein klein wenig mehr im Projektalltag des Clean Code Developers manifestieren. Das ist die Pfadfinderregel des Clean Code Developers auf sich selbst angewandt.<br /><br />So ein Veränderungsweg geht sich allerdings gerade allein nicht leicht. Wie also auf Kurs bleiben? Wie Fortschritt messen?<br /><br />Ohne ein "Kontrollsystem" etablieren zu wollen, glauben wir, dass dazu zweierlei gehört:
<ol><li>Kleinschrittige Planung</li><li>Reflexion nach jedem Schritt<br /></li></ol><br />Unabhängig von Vorgaben durch eine Projektleitung sollten Clean Code Developer ihre Arbeit so einteilen, dass sie aus Aufgaben besteht, die an einem Arbeitstag zu bewältigen sind. Nur so kann am Abend jedes Tages eine Bilanz gezogen werden. Das halten wir für wichtig, um jeden Tag die Arbeit nicht mit in den Feierabend zu tragen. Da hat sie nichts zu suchen; der dient der Entspannung.<br /><br />Durch solche kleinen Planungsschritte wird der Arbeitsalltag allerdings nicht nur befriedigender, weil sich jeden Tag über Erfolg oder Misserfolg entscheiden lässt. Die schiere Möglichkeit der Entscheidung am Abend – <i>Habe ich alle meine Aufgaben erledigt? Wie habe ich meine Aufgaben erledigt?</i> – erlaubt auch die Reflexion über die Einhaltung des Clean Code Developer Wertesystems.<br /><br />Um sich konsequent zu einem Clean Code Developer zu entwickeln, soll der Entwickler sich auf jedem Grad nach jedem Arbeitstag darüber Rechenschaft ablegen, ob er alle für ihn nach Grad relevanten Aspekte des Wertesystems berücksichtigt hat. Für den roten Grad bedeutet das z.B. Fragen wie: Verwalte ich wirklich alle Codefragmente im Versionskontrollsystem? Habe ich das DRY-Prinzip konsequent angewandt? Habe ich ganz allgemein Code in einem besseren Zustand hinterlassen als vorgefunden?<br /><br />Wenn er auf eine dieser Fragen nur zögerlich mit Ja oder gar mit einem Nein antworten muss, dann ist das natürlich kein Beinbruch. Bei allem Bemühen klappt es eben nicht immer, dass man den guten Willen auch in die Tat umsetzen kann.<br /><br />Dennoch oder gerade deshalb ist dann allerdings Folgendes zu tun:
<ul><li>Entweder bessert der Clean Code Developer jetzt solange nach, bis er in Bezug auf seines Tages Arbeit keine Prinzipienverletzung mehr wahrnimmt.</li><li>Oder er nimmt die erkannten Prinzipienverletzungen für den nächsten Tag auf seinen Aufgabenzettel.<br /></li></ul><br />Eine Hilfe bei der Reflexion kann das Clean Code Developer <a class="pagelink" href="Armb%c3%a4nder.ashx" title="Das Clean Code Developer Armband">Armband</a> sein. Uns ist bewusst, dass es nicht jedermanns Sache ist, ein buntes Silikonarmband zu tragen. Wer damit kein Problem hat, kann das Armband im Rahmen der persönlichen Reflexion nutzen. Kann oder will der Clean Code Developer die Prinzipienverletzung nicht bereinigen oder auf seinen Arbeitszettel nehmen, sollte er das Armband, das er trägt, vom einen auf den anderen Arm wechseln. So macht er deutlich, dass er eine Differenz zwischen dem Soll seines Grades und dem Geschafften anerkennt. Das ist nicht als Niederlage misszuverstehen oder gar als "Buße". Es geht vielmehr um eine haptische Unterstützung des Lernvorgangs.<br /><br />Wenn ein Clean Code Developer 21 Tage lang nach getaner Arbeit das Armband nicht mehr wechseln musste, kann er zur Arbeit am nächsten Grad übergehen. Für den roten Grad ist das der <a class="pagelink" href="Oranger-Grad.ashx" title="Oranger Grad">orange Grad</a>.
]]></description><pubDate>Fri, 02 Dec 2011 09:06:31 GMT</pubDate><guid isPermaLink="false">ADD8AC0F1431A04F125EABBCCC8742A2</guid></item><item><title><![CDATA[Wertesystem]]></title><link>http://clean-code-developer.de/Wertesystem.ashx</link><author>Stefan Lieser (slieser)</author><description><![CDATA[<h1 class="separator">Das Wertesystem<a class="headeranchor" id="Das_Wertesystem_6" href="#Das_Wertesystem_6" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
<table id="TocContainerTable"><tr><td><div id="TocContainer"><p class="small"><b>Inhaltsverzeichnis</b><span id="ExpandTocSpan"> [<a href="#" onclick="javascript:if(document.getElementById('Toc').style['display']=='none') document.getElementById('Toc').style['display']=''; else document.getElementById('Toc').style['display']='none'; return false;">Anzeigen/Verbergen</a>]</span></p><div id="Toc"><p><br /><b><a href="#Das_Wertesystem_6">Das Wertesystem</a></b><br />&nbsp;&nbsp;&nbsp;<a href="#Evolvierbarkeit_0">Evolvierbarkeit</a><br />&nbsp;&nbsp;&nbsp;<a href="#Korrektheit_1">Korrektheit</a><br />&nbsp;&nbsp;&nbsp;<a href="#Produktionseffizienz_2">Produktionseffizienz</a><br />&nbsp;&nbsp;&nbsp;<a href="#Reflexion_3">Reflexion</a><br /><b><a href="#Prinzipien_und_Praktiken_7">Prinzipien und Praktiken</a></b><br />&nbsp;&nbsp;&nbsp;<a href="#Prinzipien_4">Prinzipien</a><br />&nbsp;&nbsp;&nbsp;<a href="#Praktiken_5">Praktiken</a><br /></p></div></div></td></tr></table><br />Clean Code Developer haben ein Wertesystem. Es besteht aus den im Folgenden beschriebenen vier Werten
<ul><li>Evolvierbarkeit</li><li>Korrektheit</li><li>Produktionseffizienz</li><li>Reflexion<br /></li></ul><br /><h2 class="separator">Evolvierbarkeit<a class="headeranchor" id="Evolvierbarkeit_0" href="#Evolvierbarkeit_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>Wir möchten diesen Abschnitt mit einer provokant anmutenden These beginnen:<br /><br /><b>Es gibt keine Softwarewartung!</b><br /><br />Wartung ist ein pro-aktiver Vorgang. In Fertigungsanlagen werden regelmäßig Teile getauscht, bevor diese kaputt sind. Sie werden getauscht, weil Erfahrungswerte zeigen, dass die Zuverlässigkeit beim Weiterbetrieb unter einen kritischen Wert sinken würde. Bevor also die ganze Anlage zum Stillstand kommt, werden die kritischen Teile rechtzeitig vorher getauscht. Jeder Autobesitzer weiß, dass er regelmäßig einen Ölwechsel vornehmen lassen muss. Nicht etwa, weil das Öl zu dem Zeitpunkt aufgebraucht wäre, nicht einmal deshalb, weil das Öl zu dem Zeitpunkt bereits völlig wirkungslos wäre. Nein, es wird getauscht, weil Erfahrungswerte des Herstellers zeigen, dass der Motor durch den rechtzeitigen Ölwechsel geschont wird und somit länger hält.<br /><br />All das gibt es bei Software nicht. Software ist so, wie sie ist. Meist enthält sie Fehler. Doch auch diese Fehler sind so, wie sie sind. Man kann nichts pro-aktiv unternehmen, um den Zustand der Software zu verbessern.<br /><br />Natürlich gibt es beim Betrieb der Software pro-aktive Handlungen. So sollte vielleicht regelmäßig geprüft werden, ob die Logdateien noch ausreichend freien Platz auf der Festplatte lassen, ob eine Datenbank überläuft oder der Speicher sich zunehmend füllt. Aber die Software an sich kann nicht pro-aktiv gewartet werden. Jegliche Änderung oder Erweiterung findet statt, um einen Fehler zu beseitigen oder neue bzw. geänderte Anforderungen umzusetzen.<br /><br />Damit Änderungen möglich sind, muss die Software eine innere Struktur haben, die solche Änderungen begünstigt. Dies bezeichnen wir als <i>Evolvierbarkeit</i>. Software wird in der Regel über lange Zeiträume betrieben. Während dieser Zeit ändern sich die Rahmenbedingungen, müssen Features ergänzt werden. Im Idealfall kostet die Implementierung eines Features einen festen Betrag, der unabhängig davon ist, wann das Feature realisiert wird.<br /><br />In der Praxis steigt der Preis allerdings für ein Feature, je später es realisiert wird. Am Anfang sind Features preiswert, am Ende ist es gar nicht mehr möglich Features zu ergänzen, weil niemand mehr durchblickt. Die Software wird weggeworfen und neu entwickelt. Bis man an diesem Punkt ankommt, steigen die Kosten exponentiell. Das gemeine an exponentiellem Wachstum sind zwei Dinge:
1.) Anfangs erkennt man kaum, dass die Kosten anwachsen. Die Steigerungen sind moderat.
2.) Wenn man dann erkennt, dass die Kosten steigen, ist es zu spät. Die Steigerung schreitet dann plötzlich so schnell voran, dass ein Gegensteuern nicht mehr möglich ist.<br /><br />Je einfacher die Software an geänderte Rahmenbedingungen angepasst werden kann, desto höher ist ihre Evolvierbarkeit. Doch Evolvierbarkeit erhält man nicht nachträglich. Sie muss von vorneherein berücksichtigt werden. Die Software muss darauf ausgelegt sein.<br /><br />Dazu ein Beispiel: Klassen sollten genau eine Verantwortlichkeit haben. Ist eine Klasse für mehr als eine Sache zuständig, ist es schwerer sie zu überblicken. Das behindert Änderungen, denn diese bedingen, dass man den Quellcode versteht, der geändert werden soll. Des weiteren steigt die Kopplung zwischen den Klassen. Plötzlich hängt alles mit allem zusammen. Dies kann nur verhindert werden, indem Funktionseinheiten eine klar definierte Verantwortlichkeit haben und man die Kopplung im Blick behält. Hat man in einem Softwaresystem eine Reihe von Klassen angesammelt, die jeweils für mehrere Dinge verantwortlich sind, ist es im Nachhinein nur schwer möglich, diesen Zustand zu beseitigen. Die Kopplung ist so groß, dass es schwer fällt, einzelne Funktionseinheiten heraus zu lösen. Sollen in diesem Dickicht neue Features realisiert werden, ist das sehr aufwändig. Wenn nicht rechtzeitig begonnen wird, das Dickicht zu lichten, wird die Situation mit jedem mal schlimmer. Ab einem gewissen Punkt ist es dann kaum noch möglich, neue Features zu ergänzen. Der Super-GAU der Softwareentwicklung.<br /><br />Wir meinen, dass es soweit nicht kommen muss. Berücksichtigt man Evolvierbarkeit von vorne herein, kann Software über lange Zeiträume weiter entwickelt werden. Die Kosten pro Feature mögen dabei im Laufe der Zeit leicht ansteigen. Aber keinesfalls exponentiell!<br /><br /><h2 class="separator">Korrektheit<a class="headeranchor" id="Korrektheit_1" href="#Korrektheit_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>Software muss funktional korrekt sein. Ein Buchhaltungsprogramm muss die Buchungen ordnungsgemäß verbuchen, eine Tabellenkalkulation muss richtig rechnen. Und auch die nicht-funktionalen Anforderungen müssen erfüllt sein. Das Programm muss schonend mit Ressourcen wie Speicher, Prozessorzeit, Plattenplatz,  etc. umgehen, die Antwortzeiten müssen in einem definierten Rahmen liegen. Erst wenn alle Anforderungen erfüllt sind, ist die erstellte Software korrekt.<br /><br />Dass Korrektheit erforderlich ist, wird niemand bestreiten. Doch die Frage ist, was konkret dafür getan wird. Es reicht unserer Ansicht nach nicht aus, Software nach deren Erstellung durch eine Testabteilung zu leiten, deren Aufgabe es ist, Fehler zu finden. Wir meinen, Korrektheit muss bereits während der Entwicklung berücksichtigt werden. Bereits die Entwickler müssen sich mit der Frage der Korrektheit auseinandersetzen. Und damit sie das überhaupt können, muss ihnen klar sein, was die Anforderungen sind. Schon daran mangelt es zu oft. Entwickler werden beauftragt, ein Feature zu implementieren, ohne ihnen präzise zu sagen, was die Abnahmekriterien für das Feature sind. Doch hier geht es nicht darum, Schwarzer Peter zu spielen und einen Schuldigen außerhalb der Entwicklungsabteilungen zu suchen. Schließlich ist es die Aufgabe der Entwickler, bei unklaren Anforderungen nachzufragen, statt in ihre Glaskugel zu schauen.<br /><br />Verglichen mit dem Automobilbau steht die Softwareenwicklung beim Thema Korrektheit schlecht da. Ein Auto besteht aus vielen Teilen, deren Korrektheit jeweils einzeln nachgewiesen und überprüft werden kann. Stellen Sie sich vor, Sie müssten zur Fehlersuche mit einem Meßgerät in der Hand auf der Motorhaube des Autos sitzen, um dort verfolgen zu können, was sich in der Maschine abspielt. Mit Tempo 200 auf der Autobahn. Kommt Ihnen komisch vor? Ein Debugger wird in vielen Fällen genau so eingesetzt. Das halten wir für falsch.<br /><br /><h2 class="separator">Produktionseffizienz<a class="headeranchor" id="Produktionseffizienz_2" href="#Produktionseffizienz_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>Am Ende spielen natürlich auch die Entwicklungszeit und der Preis der Software eine Rolle. Und der ist höher, wenn die Produktion der Software nicht effizient erfolgt. Das beginnt bei manuellen Arbeitsschritten, die nicht automatisiert werden und endet bei hohen Fehlerraten die mehrmaliges Nachbessern erfordern. In letzter Konsequenz bedeutet Produktionseffizienz, dass die Software über Jahre oder gar Jahrzehnte weiterentwickelt werden kann, statt irgendwann wieder von vorne beginnen zu müssen. Gleichzeitig reduziert eine hohe Produktionseffizienz die Anfälligkeit für Fehler.<br /><br />Die Produktionseffizienz als Wert ist ferner wichtig, um die anderen Werte in ein maßvolles Verhältnis zu setzen. Wer unendlich viel Aufwand für die Korrektheit treibt, macht am Ende auch etwas falsch.<br /><br /><h2 class="separator">Reflexion<a class="headeranchor" id="Reflexion_3" href="#Reflexion_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>Ohne Rückschau ist keine Weiterentwicklung möglich. Nur wer reflektiert, wie er eine Aufgabenstellung gelöst hat, kann feststellen, ob der gewählte Weg einfach oder beschwerlich war. Lernen basiert auf Reflexion.<br /><br />In einer jungen Wissenschaft wie der Informatik ist es wichtig, stets neue Erkenntnisse zu berücksichtigen. Dazu ist Reflexion auf allen Ebenen erforderlich. Angefangen beim Reflektieren über die Implementation beim Pair Programming oder Code Review, das tägliche Reflektieren des Teams, die Reflexion nach jeder Iteration, bis hin zur Reflexion der gesamten Branche über ihr Tun. Ohne Reflexion keine Weiterentwicklung.<br /><br /><h1 class="separator">Prinzipien und Praktiken<a class="headeranchor" id="Prinzipien_und_Praktiken_7" href="#Prinzipien_und_Praktiken_7" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>Das Wertesystem leitet Clean Code Developer in ihrer täglichen Arbeit. Es enthält keine Problemlösungen, sondern definiert Rahmenbedingungen für Problemlösungen. Die vier Werte sind für eine konkrete alltägliche Umsetzung jedoch zu abstrakt. Daher haben wir Bausteine zusammengetragen, die jeweils mindestens einen der Werte befördern.
Diese konkreten Bausteine teilen wir in zwei Kategorien: Prinzipien und Praktiken.<br /><br /><h2 class="separator">Prinzipien<a class="headeranchor" id="Prinzipien_4" href="#Prinzipien_4" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>Die Clean Code Developer Prinzipien sind die grundlegenden Gesetzmäßigkeiten für die Strukturierung von Software. Sie sind entweder zu anderen Rahmenbedingungen orthogonal oder ihnen übergeordnet. Code sollte immer im Einklang mit einer maximalen Zahl von Prinzipien sein. Natürlich haben sie nicht "die Macht" von Naturgesetzen, denen niemand zuwiderhandeln kann. Aber sie sind mit ihnen in Bezug auf die Softwareentwicklung gleichauf in ihrer Fundamentalität. Wo ein Prinzip nicht eingehalten wird, tritt also nicht unbedingt sofort ein negativer Effekt ein, aber kurz- bis mittelfristig bleiben Zuwiderhandlungen nicht ohne Schmerz. Der drückt sich in Mühe beim Codeverständnis aus oder im hohen Aufwand, um Änderungen einzubringen. Ultimativ ist er, wenn Software nicht mehr evolvierbar ist. Ob ein Prinzip eingehalten wurde, kann man dem Code immer ansehen.
<h2 class="separator">Praktiken<a class="headeranchor" id="Praktiken_5" href="#Praktiken_5" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>Praktiken sind Techniken und Methoden, die ständig zum Einsatz kommen. Sie beschreiben, was Clean Code Developer praktisch tun. Motto der Praktiken: "Tue es immer so. Jeden Tag, jederzeit." Es sind handfeste Handlungsanweisungen, die manchmal des Einsatzes von Werkzeugen bedürfen. Ob einer Praktik gefolgt wird, kann man dem Code nicht immer ansehen.
]]></description><pubDate>Fri, 25 Nov 2011 09:51:36 GMT</pubDate><guid isPermaLink="false">B821D81A2F4664C05EE457635288874A</guid></item><item><title><![CDATA[Clean Code Developer]]></title><link>http://clean-code-developer.de/MainPage.ashx</link><author>Stefan Lieser (slieser)</author><description><![CDATA[<h1 class="separator">Professionalität = Bewusstheit + Prinzipien<a class="headeranchor" id="Professionalität_=_Bewusstheit_+_Prinzipien_2" href="#Professionalität_=_Bewusstheit_+_Prinzipien_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>Softwareentwicklung braucht Profis. Was aber sind Profis? Menschen die mit der Softwareentwicklung Geld verdienen? Nein, wir meinen, es gehört mehr und anderes dazu. Professionalität in der Softwareentwicklung hat nichts mit Geld zu tun. Sie hat auch nur bedingt mit einem bestimmten Ausbildungsweg zu tun. Wir kennen professionelle Softwareentwickler, die wenig oder gar kein Geld mit ihrer Software verdienen und wir kennen professionelle Softwareentwickler, die weder Diplom noch Doktortitel haben.<br /><br />Unterstützt durch:
<br />
<div class="imageleft"><a href="http://dotnetpro.de" title="http://dotnetpro.de" target="_blank"><img class="image" src="GetFile.aspx?Page=MainPage&amp;File=dotnetpro.jpg" alt="http://dotnetpro.de" /></a><p class="imagedescription">http://dotnetpro.de</p></div>
<div class="imageleft"><a href="http://www.prodevcollege.de" title="http://www.prodevcollege.de" target="_blank"><img class="image" src="GetFile.aspx?Page=MainPage&amp;File=prodevcollege.jpg" alt="http://www.prodevcollege.de" /></a><p class="imagedescription">http://www.prodevcollege.de</p></div>
<div class="imageleft"><a href="http://www.visualstudio1.de" title="http://www.visualstudio1.de" target="_blank"><img class="image" src="GetFile.aspx?Page=MainPage&amp;File=VS1-CCD.jpg" alt="http://www.visualstudio1.de" /></a><p class="imagedescription">http://www.visualstudio1.de</p></div>
<br />
<br />
<br />
<br /><br /><br /><h2 class="separator">Minimale Anforderungen an Professionalität<a class="headeranchor" id="Minimale_Anforderungen_an_Professionalität_0" href="#Minimale_Anforderungen_an_Professionalität_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
Für uns macht Professionalität vielmehr zweierlei aus:<br /><br /><ul><li>Ein professioneller Softwareentwickler setzt sich mit dem Metier bewusst auseinander.<br />D.h. er reflektiert über sein Produkt, seine Arbeitsweise, seine Materialien und Werkzeuge. Ein professioneller Softwareentwickler ist nicht einfach zufrieden, wenn sein Chef oder Kunde zufrieden sind. Er ist auch nicht einfach mit dem zufrieden, was ein Hersteller ihm empfiehlt. Stattdessen beobachtet und prüft er ständig seine Ergebnisse und bemüht sich um die Weiterentwicklung seiner selbst wie auch des Metiers.&nbsp;<br /></li></ul><br /><ul><li>Ein professioneller Softwareentwickler hat ein inneres Wertesystem.<br />Gegen dieses Wertesystem prüft er seine Ergebnisse und Handlungen. Nur, wenn seine Arbeit diesem Wertesystem entspricht, empfindet er sie als gut getan, als professionell. Sein Streben ist es daher, auch unter widrigen Umständen, unter Druck von Kunden oder Herstellern, diesem Wertesystem treu zu sein.<br /></li></ul><br />Das mag sich nun in der Kürze etwas antiquiert oder sektiererisch anhören. Sollen Softwareentwickler sich eine Zunftordnung geben oder gar einen Treueeid schwören? Nein, so meinen wir es natürlich nicht. Dennoch: In Ermangelung eines Konsenses darüber, was denn genau "gute Softwareentwicklung" sei, glauben wir, dass ein "kleinster gemeinsamer Nenner" Not tut. Die Branche - wobei wir hier zunächst nur die .NET Softwareentwicklung meinen - braucht einen Qualitätsmaßstab oder zumindest einen Erwartungshorizont für Professionalität. Die Zeiten, in denen jeder, der schon mal etwas in BASIC programmiert hatte, ausreichend qualifiziert war, um in einem Team mitzuarbeiten, sind vorbei. Genauso ist aber noch nicht die Zeit gekommen, in der die Vorlage eines Informatik Diploms wirklich etwas über die Befähigung zur Softwareentwicklung aussagen würde. (Disclaimer: Nichts gegen Diplominformatikstudiengänge! Aber wer kennt denn keinen Dipl. Inf., der durch sein Studium gekommen ist, ohne mehr als einige Zeilen zu programmieren?)&nbsp;<br /><br /><h2 class="separator">Clean Code als Fundament<a class="headeranchor" id="Clean_Code_als_Fundament_1" href="#Clean_Code_als_Fundament_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>Was also tun für mehr (sichtbare) Professionalität in der Softwareentwicklung? Wir glauben, die Branche sollte nach Anerkenntnis des Problems einfach mal nur einen kleinen Schritt machen. Weder müssen die Curricula von Masters-Studiengängen neu definiert werden noch ist die Gründung eines Verbandes zwingend. Viel einfacher glauben wir, dass "es" schon besser würde, wenn wir alle auch nur ein Buch gemeinsam gelesen hätten. Schon die vereinte Zustimmung zu den Aussagen in nur einem Buch würde einen Konsens herstellen, der viel bewirken könnte.<br /><br />Wir meinen, mit <a class="externallink" href="http://www.amazon.de/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" title="Clean Code" target="_blank">Clean Code</a> von <a class="externallink" href="http://www.objectmentor.com/omTeam/martin_r.html" title="Robert C. Martin" target="_blank">Robert C. Martin</a> solch ein Buch gefunden zu haben, das der gemeinsamen Lektüre würdig ist. Es ist kein perfektes Buch und auch wir stimmen nicht allem darin vorbehaltlos zu - aber es ist ein Buch "im rechten Geist": es ist ein Ausdruck profunder Reflexion und hat den Mut, ein fundamentales Wertesystem zu formulieren.<br /><br />In Clean Code geht es nicht um Plattform oder Technologie oder ein Programmierparadigma. Man muss also kein Freund von .NET oder Java oder ASP.NET oder SVN oder OOP sein, um aus ihm Gewinn zu ziehen. Es dreht sich vielmehr um das unter all dem liegende Substrat: Code als Quelltext und Code als strukturierter Ausdruck von Funktionalität. Für Code als kleinsten gemeinsamen Nenner zwischen Softwareentwicklern aller Coleur beschreibt Clean Code eine Menge von Prinzipien und Best Practices als kleinsten gemeinsamen Nenner.<br /><br />Nicht, dass es nicht auch andere Bücher gäbe, die ähnliches tun. <a class="pagelink" href="Team.ashx" title="Team">Uns</a> hat aber zufällig Clean Code so angesprochen, dass wir es als Kristallisationskeim für unsere Idee des Clean Code Developer nutzen wollen.<br /><br />Letztlich ist aber auch das nicht in Stein gemeißelt. Morgen erscheint vielleicht ein noch besseres Buch. Gut so! Aber an dem, was wir meinen, das Professionalität ausmacht, ändert das nichts. Deshalb fangen wir einfach mal an. "Nicht lang schnacken, Kopf in Nacken" - so sagen die Hamburger, wenn sie einen Korn (norddeutscher Schnaps) in der Hand haben. Und so wollen wir es auch halten: Ganz im Sinne der Agilitätsbewegung nicht planen bis zur Bewusstlosigkeit, sondern etwas tun. Einen kleinen Schritt machen in Richtung mehr Professionalität.<br /><br />Wer hat Lust mitzumachen? <a class="pagelink" href="Schwarzer-Grad.ashx" title="Schwarzer Grad">Hier</a> geht's los...
]]></description><pubDate>Fri, 25 Nov 2011 09:50:41 GMT</pubDate><guid isPermaLink="false">E24DD9B20126657B9C7973DD917D204C</guid></item><item><title><![CDATA[Literaturliste]]></title><link>http://clean-code-developer.de/Literaturliste.ashx</link><author>cmenzi (cmenzi)</author><description><![CDATA[<h1 class="separator">Literaturliste<a class="headeranchor" id="Literaturliste_3" href="#Literaturliste_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
<iframe src="http://astore.amazon.de/ralfwestphalh-21" width="65%" height="1010" frameborder="0" scrolling="yes"></iframe><br /><br /><h2 class="separator">Lesenswerte online Artikel<a class="headeranchor" id="Lesenswerte_online_Artikel_0" href="#Lesenswerte_online_Artikel_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><ul><li><a class="externallink" href="http://www.shmula.com/382/ask-why-five-times-about-every-matter" title="Ask 'Why' Five Times About Every Matter" target="_blank">Ask 'Why' Five Times About Every Matter</a> zur Praktik der Root Cause Analysis</li><li><a class="externallink" href="http://tdwi.org/Blogs/WayneEckerson/2010/04/Effective-Metrics.aspx" title="12 Characteristics of Effective Metrics" target="_blank">12 Characteristics of Effective Metrics</a>, Wayne W. Eckerson; lesenswert, auch wenn CCD nur die Erhebung einer Metrik empfiehlt</li><li><a class="externallink" href="http://www.heise.de/developer/artikel/Herausforderung-Brownfield-Teil-4-Komplexitaet-bewaeltigen-durch-Differenzierung-1031414.html" title="http://www.heise.de/developer/artikel/Herausforderung-Brownfield-Teil-4-Komplexitaet-bewaeltigen-durch-Differenzierung-1031414.html" target="_blank">http://www.heise.de/developer/artikel/Herausforderung-Brownfield-Teil-4-Komplexitaet-bewaeltigen-durch-Differenzierung-1031414.html</a>, 4. Teil der heise Developer Serie über CCD</li><li><a class="externallink" href="http://www.heise.de/developer/artikel/Herausforderung-Brownfield-Teil-3-Das-Sicherheitsnetz-erweitern-956969.html" title="http://www.heise.de/developer/artikel/Herausforderung-Brownfield-Teil-3-Das-Sicherheitsnetz-erweitern-956969.html" target="_blank">http://www.heise.de/developer/artikel/Herausforderung-Brownfield-Teil-3-Das-Sicherheitsnetz-erweitern-956969.html</a>, 3. Teil der heise Developer Serie über CCD</li><li><a class="externallink" href="http://www.heise.de/developer/artikel/Herausforderung-Brownfield-Teil-2-Das-Sicherheitsnetz-aufspannen-888901.html" title="http://www.heise.de/developer/artikel/Herausforderung-Brownfield-Teil-2-Das-Sicherheitsnetz-aufspannen-888901.html" target="_blank">http://www.heise.de/developer/artikel/Herausforderung-Brownfield-Teil-2-Das-Sicherheitsnetz-aufspannen-888901.html</a>, 2. Teil der heise Developer Serie über CCD</li><li><a class="externallink" href="http://www.heise.de/developer/artikel/Clean-Code-Developer-in-Brownfield-Projekten-855114.html" title="http://www.heise.de/developer/artikel/Clean-Code-Developer-in-Brownfield-Projekten-855114.html" target="_blank">http://www.heise.de/developer/artikel/Clean-Code-Developer-in-Brownfield-Projekten-855114.html</a>, 1. Teil einer Serie über CCD in Brownfield-Projekten bei heise Developer</li><li><a class="externallink" href="http://www.lostechies.com/blogs/sean_chambers/archive/2009/08/01/31-days-of-refactoring.aspx" title="31 Days of Refactoring" target="_blank">31 Days of Refactoring</a>, !LosTechies.com, <a class="externallink" href="http://www.lostechies.com/media/p/27197/download.aspx" title="als eBook" target="_blank">als eBook</a></li><li><a class="externallink" href="http://martinfowler.com/bliki/TechnicalDebtQuadrant.html" title="Technical Debt Quadrant" target="_blank">Technical Debt Quadrant</a>, Martin Fowler: Die vier Wege in die technische Schuldenlast</li><li><a class="externallink" href="http://stevesmithblog.com/blog/principles-patterns-and-practices-of-mediocre-programming/" title="Principles, Patterns, and Practices of Mediocre Programming" target="_blank">Principles, Patterns, and Practices of Mediocre Programming</a>, Steve Smith</li><li>Ein Klassiker: <a class="externallink" href="http://www.developerdotstar.com/mag/articles/PDF/DevDotStar_Reeves_CodeAsDesign.pdf" title="Code as Design" target="_blank">Code as Design</a>, Jack W. Reeves</li><li><a class="externallink" href="http://ralfw.blogspot.com/2009/07/partial-classes-helfen-dem-single-level.html" title="Partial Classes helfen dem Single Level of Abstraction Prinzip" target="_blank">Partial Classes helfen dem Single Level of Abstraction Prinzip</a>, Ralf Westphal</li><li><a class="externallink" href="http://blog.scottbellware.com/2009/07/relearning-productivity-problem-that-we.html" title="Relearning: The Productivity Problem that We're Not Supposed To Talk About" target="_blank">Relearning: The Productivity Problem that We're Not Supposed To Talk About</a>, Scott Bellware bricht eine Lanze für lesbaren Code</li><li><a class="externallink" href="http://www.codeproject.com/KB/architecture/Design_Principles.aspx" title="Is Code Complete?" target="_blank">Is Code Complete?</a>, Saurabh_Saxena</li><li><a class="externallink" href="http://www.cmcrossroads.com/bradapp/docs/demeter-intro.html" title="Law of Demeter" target="_blank">Law of Demeter</a>, Brad Appleton</li><li><a class="externallink" href="http://www.codinghorror.com/blog/archives/001230.html" title="Paying Down Your Technical Debt" target="_blank">Paying Down Your Technical Debt</a>, Jeff Atwood: Was passiert, wenn Projekte das CCD-Wertesystem nicht berüchsichtigen? Sie akkumulieren "technische Schulden". Jeff Atwood zieht in seinem Beitrag grundlegende Artikel zu dem Begriff zusammen und kommentiert.</li><li><a class="externallink" href="http://www.joelonsoftware.com/articles/fog0000000043.html" title="The Joel Test: 12 Steps to Better Code" target="_blank">The Joel Test: 12 Steps to Better Code</a>, Joel Spolsky: Einige seiner Schritte beziehen sich auf CCD Bausteine</li><li><a class="externallink" href="http://www.ericsink.com/scm/source_control.html" title="Source Control HOWTO" target="_blank">Source Control HOWTO</a>, Eric Sink (Entwickler des Versionskontrollwerkzeugs <a class="externallink" href="http://www.sourcegear.com/vault/index.html Vault" title="http://www.sourcegear.com/vault/index.html Vault" target="_blank">http://www.sourcegear.com/vault/index.html Vault</a>)</li><li><a class="externallink" href="http://openbook.galileocomputing.de/oo/oo_03_prinzipien_000.htm#Xxx999144" title="Die Prinzipien des objektorientierten Entwurfs" target="_blank">Die Prinzipien des objektorientierten Entwurfs</a> in <a class="externallink" href="http://www.galileocomputing.de/966?GPP=oppy "Praxisbuch Objektorientierung"" title="http://www.galileocomputing.de/966?GPP=oppy "Praxisbuch Objektorientierung"" target="_blank">http://www.galileocomputing.de/966?GPP=oppy "Praxisbuch Objektorientierung"</a> von Bernhard Lahres, Gregor Rayman, Galileo 2006</li><li><a class="externallink" href="http://www.lostechies.com/blogs/derickbailey/archive/2009/02/11/solid-development-principles-in-motivational-pictures.aspx" title="SOLID Development Principles – In Motivational Pictures" target="_blank">SOLID Development Principles – In Motivational Pictures</a>, blog</li><li><a class="externallink" href="http://blog.objectmentor.com/articles/2009/01/31/quality-doesnt-matter-that-much-jeff-and-joel" title="Robert C. Martin bricht eine Lanze für Qualität" target="_blank">Robert C. Martin bricht eine Lanze für Qualität</a>, blog</li><li><a class="externallink" href="http://www.infoq.com/minibooks/domain-driven-design-quickly" title="Domain Driven Design Quickly" target="_blank">Domain Driven Design Quickly</a>, eBook</li><li><a class="externallink" href="http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx" title="Pablo's Topic of the Month - March: SOLID Principles" target="_blank">Pablo's Topic of the Month - March: SOLID Principles</a>, Links zu SOLID-Artikeln</li><li><a class="externallink" href="http://www.lostechies.com/blogs/gabrielschenker/archive/2009/01/21/real-swiss-don-t-need-srp-do-they.aspx" title="Real Swiss don´t need SRP, do they?" target="_blank">Real Swiss don´t need SRP, do they?</a>, Gabriel Schenker</li><li><a class="externallink" href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod" title="The Principles of OOD" target="_blank">The Principles of OOD</a>, Robert C. Martin</li><li><a class="externallink" href="http://msdn.microsoft.com/en-us/magazine/cc546578.aspx" title="Open Closed Principle" target="_blank">Open Closed Principle</a>, Jeremy Miller, MSDN Magazine</li><li><a class="externallink" href="http://msdn.microsoft.com/en-us/magazine/cc947917.aspx" title="Cohesion and Coupling" target="_blank">Cohesion and Coupling</a>, Jeremy Miller, MSDN Magazine</li><li><a class="externallink" href="http://softwarecreation.org/" title="Software Creation Mystery" target="_blank">Software Creation Mystery</a>, Andriy Solovey, Blog<br /></li></ul><br /><h2 class="separator">Hörenswerte Podcasts<a class="headeranchor" id="Hörenswerte_Podcasts_1" href="#Hörenswerte_Podcasts_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><ul><li>.NET Rocks !#388, <a class="externallink" href="http://www.dotnetrocks.com/default.aspx?showNum=388" title="Bob Martin (Uncle Bob) on Being a Professional!" target="_blank">Bob Martin (Uncle Bob) on Being a Professional!</a></li><li>.NET Rocks !#410, <a class="externallink" href="http://www.dotnetrocks.com/default.aspx?showNum=410" title="Uncle Bob at Oredev" target="_blank">Uncle Bob at Oredev</a></li><li>Hanselminutes Podcast 145, <a class="externallink" href="http://www.hanselman.com/blog/HanselminutesPodcast145SOLIDPrinciplesWithUncleBobRobertCMartin.aspx" title="SOLID Principles with Uncle Bob - Robert C. Martin" target="_blank">SOLID Principles with Uncle Bob - Robert C. Martin</a></li><li>Elegant Code Cast 15, <a class="externallink" href="http://elegantcode.com/2008/09/30/cast-cast-15-uncle-bob-martin/" title="Uncle Bob Martin" target="_blank">Uncle Bob Martin</a></li><li>Pragmatic Programmers, <a class="externallink" href="http://podcasts.pragprog.com/2008-05/andy-hunt-on-pragmatic-wetware.mp3" title="Andy Hunt on pragmatic wetware" target="_blank">Andy Hunt on pragmatic wetware</a> Obacht, Link zu einem MP3!<br /></li></ul><br /><h2 class="separator">Sehenswerte Videos<a class="headeranchor" id="Sehenswerte_Videos_2" href="#Sehenswerte_Videos_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><ul><li><a class="externallink" href="http://weblogs.asp.net/rosherove/archive/2009/08/19/ndc-video-robert-martin-craftsmanship-and-ethics.aspx" title="Craftsmanship and Ethics" target="_blank">Craftsmanship and Ethics</a>, Robert C. Martin</li><li><a class="externallink" href="http://www.infoq.com/presentations/Agile-Trends-Kent-Beck;jsessionid=8362EC980F121B6DC337BC0CC238AD67" title="Trends in Agile Development" target="_blank">Trends in Agile Development</a>, Kent Beck</li><li><a class="externallink" href="http://www.infoq.com/presentations/principles-agile-oo-design" title="Principle of Agile Design" target="_blank">Principle of Agile Design</a>, Robert C. Martin</li><li><a class="externallink" href="http://www.infoq.com/presentations/strategic-design-evans" title="Strategic Desing" target="_blank">Strategic Desing</a>, Eric Evans</li><li><a class="externallink" href="http://www.infoq.com/presentations/model-to-work-evans" title="Putting the Model to Work" target="_blank">Putting the Model to Work</a>, Eric Evans</li><li><a class="externallink" href="http://www.infoq.com/interviews/domain-driven-design-eric-evans" title="Eric Evans on DDD" target="_blank">Eric Evans on DDD</a></li><li><a class="externallink" href="http://www.oredev.com/topmenu/video/agile/robertcmartincleancodeiiifunctions.4.5a2d30d411ee6ffd2888000779.html" title="Uncle Bob über Clean Code Functions" target="_blank">Uncle Bob über Clean Code Functions</a><br /></li></ul>
]]></description><pubDate>Fri, 18 Nov 2011 09:30:55 GMT</pubDate><guid isPermaLink="false">AFB7720593C24CFA2738DEEF03AC1DB9</guid></item><item><title><![CDATA[Oranger Grad]]></title><link>http://clean-code-developer.de/Oranger-Grad.ashx</link><author>SMoni (SMoni)</author><description><![CDATA[<h1 class="separator">Oranger 2. Grad der Clean Code Developer<a class="headeranchor" id="Oranger_C_Grad_der_Clean_Code_Developer_10" href="#Oranger_C_Grad_der_Clean_Code_Developer_10" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
<table id="TocContainerTable"><tr><td><div id="TocContainer"><p class="small"><b>Inhaltsverzeichnis</b><span id="ExpandTocSpan"> [<a href="#" onclick="javascript:if(document.getElementById('Toc').style['display']=='none') document.getElementById('Toc').style['display']=''; else document.getElementById('Toc').style['display']='none'; return false;">Anzeigen/Verbergen</a>]</span></p><div id="Toc"><p><br /><b><a href="#Oranger_C_Grad_der_Clean_Code_Developer_10">Oranger 2. Grad der Clean Code Developer</a></b><br />&nbsp;&nbsp;&nbsp;<a href="#Prinzipien_8">Prinzipien</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Single_Level_of_Abstraction_SLA_0">Single Level of Abstraction (SLA)</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Single_Responsibility_Principle_SRP_1">Single Responsibility Principle (SRP)</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Separation_of_Concerns_SoC_2">Separation of Concerns (SoC)</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Source_Code_Konventionen_3">Source Code Konventionen</a><br />&nbsp;&nbsp;&nbsp;<a href="#Praktiken_9">Praktiken</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Issue_Tracking_4">Issue Tracking</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Automatisierte_Integrationstests_5">Automatisierte Integrationstests</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Lesen_Lesen_Lesen_6">Lesen, Lesen, Lesen</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Reviews_7">Reviews</a><br /></p></div></div></td></tr></table><br /><h2 class="separator">Prinzipien<a class="headeranchor" id="Prinzipien_8" href="#Prinzipien_8" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Single Level of Abstraction (SLA)<a class="headeranchor" id="Single_Level_of_Abstraction_SLA_0" href="#Single_Level_of_Abstraction_SLA_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Die Einhaltung eines Abstraktionsniveaus fördert die Lesbarkeit.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Eine Codezeile kann auf verschiedenen Abstraktionsniveaus liegen. Die Zuweisung eines Wertes an eine Variable liegt auf einem niedrigeren Abstraktionsniveau als etwa ein Methodenaufruf. Schließlich kann sich hinter dem Methodenaufruf weit mehr Logik befinden als in der Zuweisung einer Variable. Selbst Methodenaufrufe können auf unterschiedlichen Abstraktionsniveaus stehen. Der Aufruf einer Methode aus einem Framework steht auf einem anderen Niveau, als der Aufruf einer Methode der Anwendung.<br /><br />Damit Code gut zu lesen und zu verstehen ist, sollte in einer Methode nur ein Abstraktionsniveau verwendet werden. Andernfalls fällt es dem Leser schwer, Essentielles von Details zu unterscheiden. Wenn Bitpfriemeleien erforderlich sind, sollten diese nicht mit dem Aufruf von Methoden vermischt werden.<br /><br />Hilfreich als Analogie ist der Blick auf Artikel in der Tageszeitung: dort steht zu oberst das Allerwichtigste, die Überschrift. Aus ihr sollte in groben Zügen hervorgehen, wovon der Artikel handelt. Im ersten Satz des Artikels wird dies auf einem hohen Abstraktionsniveau beschrieben. Je weiter man im Artikel fortschreitet, desto mehr Details tauchen auf. So können wir auch unseren Code strukturieren. Der Name der Klasse ist die Überschrift. Dann folgen die öffentlichen Methoden auf hohem Abstraktionsniveau. Diese rufen möglicherweise Methoden auf niedrigerem Niveau auf, bis zuletzt die "Bitpfriemelmethoden" übrig bleiben. Durch diese Einteilung kann ich als Leser der Klasse entscheiden, welchen Detaillierungsgrad ich mir ansehen möchte. Interessiert mich nur grob, wie die Klasse arbeitet, brauche ich mir nur die öffentlichen Methoden anzuschauen. In ihnen wird die Funktionalität auf einem hohen Abstraktionsniveau gelöst. Interessieren mich weitere Details, kann ich tiefer einsteigen und mir die privaten Methoden ansehen.<br /><br />Literaturquellen: Clean Code, Seite 36ff.
</div><br /><br /><h3 class="separator">Single Responsibility Principle (SRP)<a class="headeranchor" id="Single_Responsibility_Principle_SRP_1" href="#Single_Responsibility_Principle_SRP_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Fokus erleichtert das Verständnis. Eine Klasse mit genau einer Aufgabe ist verständlicher als ein Gemischtwarenladen.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Das Single Responsibility Principle (<a class="externallink" href="http://www.objectmentor.com/resources/articles/srp.pdf" title="SRP" target="_blank">SRP</a>) ist eines der <a class="pagelink" href="SOLID.ashx" title="SOLID">SOLID</a> Prinzipien. Es lautet: Eine Klasse sollte nur <b>eine</b> Verantwortlichkeit haben.<br /><br />Hintergrund des Single Responsibility Principle ist die Überlegung, dass Änderungen oder Erweiterungen der Funktionalität einer Anwendung sich auf wenige Klassen beschränken sollen. Je mehr Klassen angepasst werden müssen, desto größer ist das Risiko, dass sich durch die erforderlichen Änderungen Probleme an Stellen ergeben, die im Kern nichts mit der Erweiterung zu tun haben.
Eine Verletzung des Single Responsibility Principle führt zu Kopplung und damit zu erhöhter Komplexität, es wird schwieriger den Code zu verstehen. 
</div><br /><br /><h3 class="separator">Separation of Concerns (SoC)<a class="headeranchor" id="Separation_of_Concerns_SoC_2" href="#Separation_of_Concerns_SoC_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Wenn eine Codeeinheit keine klare Aufgabe hat ist es schwer sie zu verstehen, sie anzuwenden und sie ggf. zu korrigieren oder zu erweitern.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Team</td></tr></tbody></table><br />Übersetzt mit Trennung der Belange bedeutet dieses Prinzip, dass man nicht mehrere Belange in einer Klasse zusammenfassen soll. Was sind Belange? Belange sind "komplett verschiedene" Zwecke. Man sagt auch, Belange seien orthogonal zu einander und vor allem orthogonal zur Hauptfunktionalität einer Funktionseinheit. Beispiele für typische Belange sind: Tracing, Logging, Transaktionalität, Caching. Diese Belange sollen nach dem Prinzip der Separation of Concerns in spezialisierte Funktionseinheiten ausgelagert werden.<br /><br />Das Separation of Concerns Prinzip hängt eng mit dem Single Responsibility Prinzip zusammen. Dabei sind Concerns eine Übermenge von Responsibilities. Jede Responsibility besteht im Idealfall aus genau einem Concern, nämlich ihrer Kernfunktionalität. Oft sind in einer Responsibility jedoch mehrere Concerns vermischt. Da sich dies technisch meist nicht ganz vermeiden läßt, besagt das Prinzip nicht etwa, dass eine Responsibility nur aus einem Concern bestehen darf, sondern dass die Concerns getrennt sein sollten. Innerhalb einer Methode sollte beispielsweise klar erkennbar sein, dass es mehrere Concerns gibt. Ferner sollten die Concerns nicht irgendwie über die Methode verstreut sein, sondern so gruppiert, dass klar ist, was zu einem Concern gehört.<br /><br />Im Domain Driven Design versucht man beispielsweise die Business Domain von der Infrastruktur strikt zu trennen. So darf dort eine Klasse aus der Business Domain keinerlei Infrastruktur, etwa für Datenbankzugriffe, enthalten, sondern soll ausschließlich die Geschäftslogik abbilden. Persistenz ist ein "Concern" der nichts mit der Business Logik zu tun hat.
Separation of Concerns führt zu loser Kopplung und hoher Kohäsion. Die einzelnen Komponenten sind jeweils auf eine Aufgabe, einen Concern, fokussiert und dadurch leicht verständlich. Alle Teile aus denen die Komponente besteht, sind auf diese eine Aufgabe ausgerichtet, dadurch hängen die Teile eng zusammen (hohe Kohäsion). Separation of Concerns führt darüber hinaus auch zu gut testbaren Komponenten. Denn wenn der Zweck einer Codeeinheit fokussiert ist, muss weniger breit getestet werden. In Bezug auf die zu testende Codeeinheit sind weniger Testparameterkombinationen zu prüfen.
Soll die Trennung der Belange konsequent betrieben werden, muss die Objektorientierung um das Konzept der Aspektorientierten Programmierung (AOP) erweitert werden. Dadurch wird es möglich, Aspekte wie etwa Transaktionalität, Tracing oder Caching vollständig aus einer Methode herauszuziehen. 
</div><br /><br /><h3 class="separator">Source Code Konventionen<a class="headeranchor" id="Source_Code_Konventionen_3" href="#Source_Code_Konventionen_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Code wird häufiger gelesen als geschrieben. Daher sind Konventionen wichtig, die ein schnelles Lesen und Erfassen des Codes unterstützen.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td>+</td><td></td><td></td></tr><tr><td>Team</td></tr></tbody></table><br />Wir betrachten die folgenden Aspekte als wichtig:
<ul><li>Namensregeln</li><li>Richtig Kommentieren<br /></li></ul><br />Damit wollen wir nicht zum Ausdruck bringen, dass andere Konventionen unwichtig sind, wir wollen nur mit diesen beiden beginnen, weil sie uns elementar erscheinen. Bei allen Code Konventionen ist uns nämlich eines ganz wichtig: es geht weniger um die konkrete Ausgestaltung, sondern um konsequentes Einhalten der Konvention. Und es geht um das Bewusstsein, dass Konventionen notwendig sind.<br /><br /><h4 class="separator">Namensregeln<a class="headeranchor" id="Namensregeln_0" href="#Namensregeln_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<div class="box">Warum?<br />
Ohne Namensregeln muss man sich wieder und wieder auf den Stil einzelner Entwickler einstimmen.</div><br />Namensregeln sollen den Leser des Codes dabei unterstützen den Code zu verstehen. Da es z.B. hilfreich ist, Felder von lokalen Variablen zu unterscheiden, könnte dies durch eine Namensregel unterstützt werden. Wie eine solche Konvention im Einzelfall aussieht ist Geschmacksache. Manche bevorzugen "this.xyz" andere "_xyz". Welche Variante man wählt ist uns nicht wichtig. Uns kommt es darauf an, dass die Konvention konsequent eingehalten wird. Die Notwendigkeit einer Namensregel für z.B. Felder hängt ferner vom Kontext ab. In einer Klasse mit 400 Zeilen wäre uns eine Namensregel, die Felder gegenüber Variablen hervorhebt, sehr wichtig, in überschaubaren Klassen tritt sie dagegen eher in den Hintergrund.
Mit Hilfe der Root Cause Analysis geht der Clean Code Developer der eigentlichen Ursache für die Notwendigkeit einer Namensregel auf den Grund.<br /><br /><h4 class="separator">Richtig kommentieren<a class="headeranchor" id="Richtig_kommentieren_1" href="#Richtig_kommentieren_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<div class="box">Warum?<br />
Unnötige oder gar falsche Kommentare halten beim Lesen auf. Der Code sollte so klar und deutlich sein, dass er möglichst ohne Kommentare auskommt.</div><br />Salopp gesagt ist ein Kommentar im Code ein Hinweis darauf, dass der Code noch verbessert werden kann. Typisch für solche Fälle sind 3 Zeilen Code, die mit einem Kommentar überschrieben sind. An der Stelle hilft es wahrscheinlich, die drei Zeilen als Methode zu extrahieren (Refactoring: Extract Method) und den Kommentar als Name der Methode zu verwenden. Ganz allgemein kann der Bedarf an Kommentaren reduziert werden, in dem man gute Namen verwendet für Variablen, Methoden, Klassen, etc.<br /><br />Statt
<pre>    int laenge; // in mm
</pre>
besser
<pre>    int laengeInMM; 
</pre><br />
Statt
<pre>    public double Preis() &#123;
        // Berechnet den Bruttopreis ...
    &#125;
</pre>
besser
<pre>    public Money BruttoPreis() &#123;
        ...
    &#125; 
</pre><br />Kommentiert werden sollte nicht was man tut, sondern, wenn überhaupt, wieso man etwas tut.
</div><br /><br /><h2 class="separator">Praktiken<a class="headeranchor" id="Praktiken_9" href="#Praktiken_9" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Issue Tracking<a class="headeranchor" id="Issue_Tracking_4" href="#Issue_Tracking_4" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Nur, was man aufschreibt, vergisst man nicht und kann man effektiv delegieren und verfolgen.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td>+</td><td>++</td><td>+</td></tr><tr><td>Team</td></tr></tbody></table><br />Eine strukturierte Verwaltung aller "Issues" ist schon deshalb erforderlich, damit nichts verloren geht. Und nur wenn ein Überblick über alle offenen Punkte möglich ist, können die Punkte priorisiert und in eine Reihenfolge gebracht werden. Dazu bedarf es nicht zwangsläufig ausgeklügelter Tools, ein Board mit Pappkarten kann den Zweck auch erfüllen. Vor allem sollte hier nicht das Tool im Vordergrund stehen, sondern die Tätigkeit.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Automatisierte Integrationstests<a class="headeranchor" id="Automatisierte_Integrationstests_5" href="#Automatisierte_Integrationstests_5" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Integrationstests stellen sicher dass der Code tut was er soll. Diese wiederkehrende Tätigkeit nicht zu automatisieren wäre Zeitverschwendung.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>++</td><td>++</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Die fundamentale Voraussetzung für jegliche Änderungen am Code haben wir bereits im <a class="pagelink" href="Roter-Grad.ashx" title="Roter Grad">roten Grad</a> durch den Einsatz eines Versionskontrollsystems gelegt. Wir können ohne Sorge Änderungen am Code vornehmen, ganze Dateien und Verzeichnisse löschen, durch das Versionskontrollsystem ist alles wieder abrufbar.<br /><br />Wenn wir nun Änderungen am Code vornehmen, sollten wir uns sicher sein, dass wir dabei nichts kaputt machen. Und diese Sicherheit können wir nur erlangen, wenn wir nach der Änderung testen, ob die Anwendung sich noch so verhält wie zuvor. Diese Tests nach jeder Änderung per Hand durchzuführen wäre nicht praktikabel, wir müssen sie automatisieren.
Ein großes Übel der Softwareentwicklung ist die Angst, bei Änderungen am Code etwas zu übersehen, ein Detail nicht zu berücksichtigen, und dadurch einen Fehler zu verursachen in Code der vorher funktionierte. Dabei spielt es in der Regel sogar nicht mal eine Rolle, ob die Änderungen dazu führen sollen, dass der Code verbessert wird (Refaktorisieren) oder zusätzliche Anforderungen umgesetzt werden sollen. Solange wir nach Durchführen einer Änderung nicht sicher sind, dass alles noch so funktioniert wie zuvor, bleibt die Angst. Diese führt dazu, dass wir Code im Zweifelsfall so belassen, wie er ist, denn er funktioniert ja. Notwendige Refaktorisierungen werden unterlassen, aus Angst Fehler zu machen.<br /><br />Damit wir uns auch in schon laufenden Projekten (sogenannte <i>Brownfield</i> Projekte, im Gegensatz zu <i>Greenfield</i> "auf der grünen Wiese") dieses Sicherheitsnetz schaffen können, benötigen wir Verfahren, die auf vorhandenen Code angewendet werden können. Dazu eignen sich automatisierte Integrationstests. Sie setzen entweder ganz oben auf der Benutzerschnittstelle auf und testen die Anwendung durch alle Layer oder setzen weiter unten auf. In jedem Fall werden mehrere Funktionseinheiten im Zusammenspiel getestet.<br /><br />Bevor wir also Änderungen oder Erweiterungen am Code vornehmen, erstellen wir für die betroffenen Codebereiche Integrationstests. Dabei können Tools und Techniken wie WatiN, UI Automation, etc. verwendet werden. Wünschenswert sind natürlich auch Unit Tests, welche einzelne Funktionseinheiten isoliert testen. Dazu muss der Code allerdings Voraussetzungen erfüllen, die vermutlich nicht immer gegeben sind: der Code muss bereits das <i>Single Responsibility Prinzip</i> berücksichtigen. Andernfalls sind die Abhängigkeiten zwischen den Funktionseinhieten (Komponenten, Klassen oder Methoden) so groß, dass sie nicht isoliert getestet werden können. Das Fernziel ist natürlich eine Codebasis, bei der Unit Tests möglich sind. Mehr noch: wir werden in Zukunft die Tests vor der Implementierung erstellen (<i>Test first</i>). Aber um durch Refaktorisierungen dorthin zu gelangen, bedarf es erst der Integrationstests, um sicherzustellen, dass die Anwendung sich noch so verhält wie vor der Refaktorisierung.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Lesen, Lesen, Lesen<a class="headeranchor" id="Lesen_Lesen_Lesen_6" href="#Lesen_Lesen_Lesen_6" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Lesen bildet!</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td></td><td></td><td></td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Lesen bildet - wir sind jedenfalls fest davon überzeugt, dass dies auch für Software-Entwickler gilt. Die Softwaretechnik entwickelt sich nach wie vor weiter. Neben den großen Entwicklungsschritten wie Prozedurale Programmierung, Objektorientierte Programmierung, Funktionale Programmierung, Aspektorientierte Programmierung, etc. gibt es ständig Entwicklungen im Kleinen mit denen sich ein professioneller Software-Entwickler auseinandersetzen muss. Da wären zum einen Techniken wie etwa <i>Dependency Injection</i> oder <i>Object Relational Mapper</i>. Aber auch innerhalb dieser Techniken gibt es Entwicklungsschritte wie etwa <i>Domain Specific Languages (DSLs)</i> zur Konfiguration vs. XML basierende Konfiguration. Neben den technischen Aspekten der Softwareentwicklung wird auch der Prozess ständig weiterentwickelt. So hat sich die Erkenntnis durchgesetzt, dass Wasserfallmodelle nicht funktionieren, verschiedene agile Prozesse werden entwickelt. All dies muss der Clean Code Developer im Blick haben. <br /><br />Wir schlagen daher vor, pro Jahr wenigstens 6 Fachbücher zu lesen. Ferner sollten Periodika regelmäßig gelesen werden und darunter verstehen wir neben Fachzeitschriften auch Blogs.<br /><br />Anregungen finden Sie in der <a class="pagelink" href="Literaturliste.ashx" title="Literaturliste">Literaturliste</a>.<br /><br /><h3 class="separator">Reviews<a class="headeranchor" id="Reviews_7" href="#Reviews_7" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="transcludedpage"><div class="box">Warum?<br />
Vier Augen sehen mehr als zwei. Wenn der eine Entwickler dem anderen seinen Code erklärt, tauchen meist Details auf, die bislang nicht bedacht wurden.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>++</td><td></td><td>++</td></tr><tr><td>Team</td></tr></tbody></table><br />Reviews kommen vereinfacht in zwei Spielarten daher: als kontinuierlicher Prozess beim Pair Programming, als eigenständiger Prozessschritt beim Code Review. Das Ziel ist in beiden Fällen das gleiche: der Code soll von einem zweiten Entwickler begutachtet werden. Dies beugt der "Betriebsblindheit" vor. Schon die Tatsache dass ein Entwickler seinen Code einem anderen Entwickler vorstellt und beschreibt, führt zu Aha Erlebnissen.<br /><br />In der Regel wird erst durch die Diskussion mit anderen Entwicklern deutlich, wo die Stärken und Schwächen einer Codebasis liegen. Gerade der Prozess der ständigen Verbesserung bedingt es, sich mit der Sichtweise anderer Entwickler auseinander zu setzen.<br /><br />Selbstverständlich ist nicht nur der Quellcode eine geeignete Basis für Reviews. Sie bieten eine günstige Möglichkeit, die Ergebnisse jeder Entwicklungstätigkeit zu überprüfen, sofern sie in einem "lesbaren" Ergebnis münden. Neben rein informellen Reviews, wie dem Pair Programming oder der Begutachtung durch eine zweite Person gibt es auch das formale Review mit einem Reviewprozess sowie entsprechenden Rollen. Weitere bekannte Arten des Review sind z.B. Walkthrough, Technisches Review, Peer Review und Inspektion.<br /><br />Reviews ergänzen dynamische Tests, wie z.B. den automatischen Unit-Test oder den automatischen Integrationstest aus dem <a class="pagelink" href="Gelber-Grad.ashx" title="Gelber Grad">gelben Grad</a> bzw. <a class="pagelink" href="Oranger-Grad.ashx" title="Oranger Grad">orangen Grad</a>. Im Gegensatz zu diesen Tests, sind Reviews auch sehr gut geeignet, Fehler in den Anforderungen zu finden. Auch können sie bereits sehr früh im Entwicklungsprozess eingesetzt und Fehler dadurch auch sehr früh gefunden werden. Und um so früher Fehler gefunden werden, um so günstiger ist auch deren Beseitigung.<br /><br /><h4 class="separator">Quellen<a class="headeranchor" id="Quellen_0" href="#Quellen_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<table><thead><tr><th>Quelle</th><th>Autor</th><th>Kurzbeschreibung</th></tr></thead><tbody><tr><td><a class="externallink" href="http://www.german-testing-board.info/de/downloads.shtm" title="http://www.german-testing-board.info/de/downloads.shtm" target="_blank">http://www.german-testing-board.info/de/downloads.shtm</a></td><td>German Testing Board</td><td>Lehrplan Certified Tester - Advanced Level</td></tr><tr><td>Basiswissen Softwaretest, Aus- und Weiterbildung zum </td><td>T. Linz und A. Spillner</td><td>Das Lehrbuch zum Certified Tester Foundation Level nach ISTQB</td></tr><tr><td>Certified Tester Foundation Level nach ISTQB-Standard</td></tr></tbody></table>
</div><br /><br />An den orangen Grad schließt sich der <a class="pagelink" href="Gelber-Grad.ashx" title="Gelber Grad">gelbe Grad</a> an.<br /><br />]]></description><pubDate>Sun, 18 Sep 2011 13:26:44 GMT</pubDate><guid isPermaLink="false">C258592A3A84C73170657F1E3F690D56</guid></item><item><title><![CDATA[Спайс]]></title><link>http://clean-code-developer.de/</link><author>Stefan Lieser (slieser)</author><description><![CDATA[Die Seite wurde gelöscht von slieser.]]></description><pubDate>Thu, 12 May 2011 14:24:51 GMT</pubDate><guid isPermaLink="false">75A5C9165124FFD83A2C086C3B239A81</guid></item><item><title><![CDATA[Reviews]]></title><link>http://clean-code-developer.de/Reviews.ashx</link><author>Robert Niemann (Robert Niemann)</author><description><![CDATA[<div class="box">Warum?<br />
Vier Augen sehen mehr als zwei. Wenn der eine Entwickler dem anderen seinen Code erklärt, tauchen meist Details auf, die bislang nicht bedacht wurden.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>++</td><td></td><td>++</td></tr><tr><td>Team</td></tr></tbody></table><br />Reviews kommen vereinfacht in zwei Spielarten daher: als kontinuierlicher Prozess beim Pair Programming, als eigenständiger Prozessschritt beim Code Review. Das Ziel ist in beiden Fällen das gleiche: der Code soll von einem zweiten Entwickler begutachtet werden. Dies beugt der "Betriebsblindheit" vor. Schon die Tatsache dass ein Entwickler seinen Code einem anderen Entwickler vorstellt und beschreibt, führt zu Aha Erlebnissen.<br /><br />In der Regel wird erst durch die Diskussion mit anderen Entwicklern deutlich, wo die Stärken und Schwächen einer Codebasis liegen. Gerade der Prozess der ständigen Verbesserung bedingt es, sich mit der Sichtweise anderer Entwickler auseinander zu setzen.<br /><br />Selbstverständlich ist nicht nur der Quellcode eine geeignete Basis für Reviews. Sie bieten eine günstige Möglichkeit, die Ergebnisse jeder Entwicklungstätigkeit zu überprüfen, sofern sie in einem "lesbaren" Ergebnis münden. Neben rein informellen Reviews, wie dem Pair Programming oder der Begutachtung durch eine zweite Person gibt es auch das formale Review mit einem Reviewprozess sowie entsprechenden Rollen. Weitere bekannte Arten des Review sind z.B. Walkthrough, Technisches Review, Peer Review und Inspektion.<br /><br />Reviews ergänzen dynamische Tests, wie z.B. den automatischen Unit-Test oder den automatischen Integrationstest aus dem <a class="pagelink" href="Gelber-Grad.ashx" title="Gelber Grad">gelben Grad</a> bzw. <a class="pagelink" href="Oranger-Grad.ashx" title="Oranger Grad">orangen Grad</a>. Im Gegensatz zu diesen Tests, sind Reviews auch sehr gut geeignet, Fehler in den Anforderungen zu finden. Auch können sie bereits sehr früh im Entwicklungsprozess eingesetzt und Fehler dadurch auch sehr früh gefunden werden. Und um so früher Fehler gefunden werden, um so günstiger ist auch deren Beseitigung.<br /><br /><h4 class="separator">Quellen<a class="headeranchor" id="Quellen_0" href="#Quellen_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<table><thead><tr><th>Quelle</th><th>Autor</th><th>Kurzbeschreibung</th></tr></thead><tbody><tr><td><a class="externallink" href="http://www.german-testing-board.info/de/downloads.shtm" title="http://www.german-testing-board.info/de/downloads.shtm" target="_blank">http://www.german-testing-board.info/de/downloads.shtm</a></td><td>German Testing Board</td><td>Lehrplan Certified Tester - Advanced Level</td></tr><tr><td>Basiswissen Softwaretest, Aus- und Weiterbildung zum </td><td>T. Linz und A. Spillner</td><td>Das Lehrbuch zum Certified Tester Foundation Level nach ISTQB</td></tr><tr><td>Certified Tester Foundation Level nach ISTQB-Standard</td></tr></tbody></table>
]]></description><pubDate>Sun, 20 Feb 2011 19:32:19 GMT</pubDate><guid isPermaLink="false">ED7CDFFD8256893AE6A3EB4285E968B6</guid></item><item><title><![CDATA[Prinzipien]]></title><link>http://clean-code-developer.de/Prinzipien.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[Alphabetische Liste der CCD-Prinzipien<br /><br /><ul><li><a class="pagelink" href="Dependency-Inversion-Principle.ashx" title="Dependency Inversion Principle">Dependency Inversion Principle</a></li><li><a class="pagelink" href="Don-t-Repeat-Yourself-DRY.ashx" title="Don´t Repeat Yourself (DRY)">Don´t Repeat Yourself (DRY)</a></li><li><a class="pagelink" href="Entwurf-und-Implementation-uberlappen-nicht.ashx" title="Entwurf und Implementation überlappen nicht">Entwurf und Implementation überlappen nicht</a></li><li><a class="pagelink" href="Favour-Composition-over-Inheritance-FCoI.ashx" title="Favour Composition over Inheritance (FCoI)">Favour Composition over Inheritance (FCoI)</a></li><li><a class="pagelink" href="Implementation-spiegelt-Entwurf.ashx" title="Implementation spiegelt Entwurf">Implementation spiegelt Entwurf</a></li><li><a class="pagelink" href="Information-Hiding-Principle.ashx" title="Information Hiding Principle">Information Hiding Principle</a></li><li><a class="pagelink" href="Interface-Segregation-Principle-ISP.ashx" title="Interface Segregation Principle (ISP)">Interface Segregation Principle (ISP)</a></li><li><a class="pagelink" href="Keep-it-simple-stupid-KISS.ashx" title="Keep it simple, stupid (KISS)">Keep it simple, stupid (KISS)</a></li><li><a class="pagelink" href="Law-of-Demeter.ashx" title="Law of Demeter">Law of Demeter</a></li><li><a class="pagelink" href="Liskov-Substitution-Principle.ashx" title="Liskov Substitution Principle">Liskov Substitution Principle</a></li><li><a class="pagelink" href="Open-Closed-Principle.ashx" title="Open Closed Principle">Open Closed Principle</a></li><li><a class="pagelink" href="Principle-of-Least-Astonishment.ashx" title="Principle of Least Astonishment">Principle of Least Astonishment</a></li><li><a class="pagelink" href="Separation-of-Concerns-SoC.ashx" title="Separation of Concerns (SoC)">Separation of Concerns (SoC)</a></li><li><a class="pagelink" href="Single-Level-of-Abstraction-SLA.ashx" title="Single Level of Abstraction (SLA)">Single Level of Abstraction (SLA)</a></li><li><a class="pagelink" href="Single-Responsibility-Principle-SRP.ashx" title="Single Responsibility Principle (SRP)">Single Responsibility Principle (SRP)</a></li><li><a class="pagelink" href="Source-Code-Konventionen.ashx" title="Source Code Konventionen">Source Code Konventionen</a></li><li><a class="pagelink" href="Tell-don-t-ask.ashx" title="Tell, don´t ask">Tell, don´t ask</a></li><li><a class="pagelink" href="Vorsicht-vor-Optimierungen.ashx" title="Vorsicht vor Optimierungen!">Vorsicht vor Optimierungen!</a></li><li><a class="pagelink" href="You-Ain-t-Gonna-Need-It-YAGNI.ashx" title="You Ain´t Gonna Need It (YAGNI)">You Ain´t Gonna Need It (YAGNI)</a><br /></li></ul>
]]></description><pubDate>Sun, 20 Feb 2011 18:24:34 GMT</pubDate><guid isPermaLink="false">A5BDAD7A436234CC4A32994F8188AB04</guid></item><item><title><![CDATA[Blauer Grad]]></title><link>http://clean-code-developer.de/Blauer-Grad.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<h1 class="separator">Der blaue Grad<a class="headeranchor" id="Der_blaue_Grad_9" href="#Der_blaue_Grad_9" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
<table id="TocContainerTable"><tr><td><div id="TocContainer"><p class="small"><b>Inhaltsverzeichnis</b><span id="ExpandTocSpan"> [<a href="#" onclick="javascript:if(document.getElementById('Toc').style['display']=='none') document.getElementById('Toc').style['display']=''; else document.getElementById('Toc').style['display']='none'; return false;">Anzeigen/Verbergen</a>]</span></p><div id="Toc"><p><br /><b><a href="#Der_blaue_Grad_9">Der blaue Grad</a></b><br />&nbsp;&nbsp;&nbsp;<a href="#Prinzipien_7">Prinzipien</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Entwurf_und_Implementation_überlappen_nicht_0">Entwurf und Implementation überlappen nicht</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Implementation_spiegelt_Entwurf_1">Implementation spiegelt Entwurf</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#You_Ain´t_Gonna_Need_It_YAGNI_2">You Ain´t Gonna Need It (YAGNI)</a><br />&nbsp;&nbsp;&nbsp;<a href="#Praktiken_8">Praktiken</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Continuous_Delivery_3">Continuous Delivery</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Iterative_Entwicklung_4">Iterative Entwicklung</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Komponentenorientierung_5">Komponentenorientierung</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Test_first_6">Test first</a><br /></p></div></div></td></tr></table><br /><h2 class="separator">Prinzipien<a class="headeranchor" id="Prinzipien_7" href="#Prinzipien_7" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Entwurf und Implementation überlappen nicht<a class="headeranchor" id="Entwurf_und_Implementation_überlappen_nicht_0" href="#Entwurf_und_Implementation_überlappen_nicht_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Planungsunterlagen, die mit der Umsetzung nichts mehr gemein haben, schaden mehr, als dass sie nützen. Deshalb nicht die Planung aufgeben, sondern die Chance auf Inkonsistenz minimieren.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td>+</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Eines der grundlegenden Probleme der Softwareentwicklung sind Implementationen, denen ein vorausgegangene Planung nicht mehr anzusehen ist. Da hängen dann Entwurfsdiagramme an der Wand, die kaum noch etwas mit der Coderealität zu tun haben. Die Ursache dafür ist eine Verletzung des fundamentalen DRY-Prinzips: Entwurf und Implementation sind Wiederholungen desselben, der Struktur einer Software. Da Implementation auf Entwurf folgt und den Löwenanteil der Arbeit ausmacht, geraten beide schnell aus dem Tritt, wenn Strukturänderungen während der Implementation nicht immer wieder in den Entwurf eingearbeitet werden. Entwurfsdiagramme sind nach Beginn der Implementation sonst bald nichts mehr wert.<br /><br />Wie kann die Situation verbessert werden? Sollte vielleicht auf Entwurf verzichtet werden, wenn letztlich in der Implementation die "Strukturwahrheit" liegt? Nein, sicher nicht. Entwurf muss sein. Ohne Planung gibt es keine Zielvorstellung. Aber Entwurf und Implementation müssen dem DRY-Prinzip gerecht werden. Deshalb sollten Entwurf und Implementation sich so wenig überlappen wie möglich. Ihre Schnittstelle sollte dünn sein. Wenn das der Fall ist, stellen sie keine Wiederholungen mehr dar, sondern beschreiben unterschiedliches. Das bedeutet: Entwurf/Architektur kümmert sich nicht um die Implementation und Implementation kümmert sich nicht um Architektur.<br /><br />Und wo verläuft diese Trennlinie? Bei den so genannten Komponenten (s.u. Praktiken). Architekten kümmern sich nicht um den internen Aufbau von Komponenten. Für sie sind es Black Boxes, deren Klassenstruktur nicht architekturrelevant ist. Umgekehrt ist für einen Komponentenimplementierer die Architektur irrelevant. Was er zu implementieren hat, ergibt sich aus den Komponentenkontrakten, die seine Komponente importiert und exportiert. Einen größeren Zusammenhang muss er nicht kennen.<br /><br />Die Aufgabe der Architektur ist es mithin, Software in Komponenten zu zerlegen, deren Abhängigkeiten zu definieren und Leistungen in Kontrakten zu beschreiben. Diese Strukturen werden dann auch einzig durch Architekten gepflegt. Und die Aufgabe der Implementation ist es, die von der Architektur definierten Komponenten zu realisieren. Wie sie das tun, ist nicht architekturrelevant. Ihre innere Struktur ist für die Architektur unsichtbar.
</div><br /><br /><h3 class="separator">Implementation spiegelt Entwurf<a class="headeranchor" id="Implementation_spiegelt_Entwurf_1" href="#Implementation_spiegelt_Entwurf_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Umsetzung, die von der Planung beliebig abweichen kann, führt direkt in die Unwartbarkeit. Umsetzung braucht daher einen durch die Planung vorgegebenen physischen Rahmen.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Architektur und Implementation sollen nicht überlappen, damit sie das DRY-Prinzip nicht verletzten. So werden Inkonsistenzen vermieden, die dadurch entstehen können, dass auf der einen Seite etwas geändert wird, ohne diese Änderung auf der anderen Seite nachzuführen.<br /><br />Nichtsdestotrotz macht die Architektur aber ja Aussagen über die Implementation. Nicht ihre Details, aber ihre grundsätzliche Form. Architektur definiert die Strukturelemente und deren Beziehungen innerhalb eines Codesystems. Implementation existiert also bei auch bei Abwesenheit von Überlappungen nicht unabhängig von Architektur, sondern sozusagen in ihr.<br /><br />Genau das sollte sich dann aber auch in der Implementation ausdrücken. So wird die leichter verständlich, so kann besser sichergestellt werden, dass die Implementation tatsächlich der Architektur folgt. Die von der Architektur auf verschiedenen Abstraktionsebenen definierten Strukturelemente sollten deshalb nicht in einem großen "Codetopf" (z.b. eine große Visual Studio Solution) "zusammengerührt werden". Viel besser auch im Sinne hoher Produktivität und einfacher Testbarkeit ist es, die logischen Strukturen der Architektur so physisch wie möglich zu manifestieren.<br /><br /><ol><li>Die von der Architektur geplanten Strukturen auf verschiedenen Abstraktionsebenen sollten sich so weitgehend wie möglich in der Codeorganisation widerspiegeln. Das bedeutet zum einen, dass die Architektur als Strukturelemente vor allem physische Codeeinheiten benutzt. Und zum anderen sollen diese Strukturelemente dann aber auch im Quellcode bzw. in der Codeorganisation im Repository klar sichtbar sein.</li><li>Bei der Arbeit an der Implementation der Strukturelemente und insbesondere innerhalb von Komponenten sollen Architekturänderungen "im Vorbeigehen" unmöglich sein. Wer in bzw. an einem Strukturelement arbeitet, also an einem Teil, darf nicht ad hoc die umliegende Struktur, d.h. das Ganze, ändern können. Nur wenn das gewährleistet ist, wächst die Entropie einer Software nicht unkontrolliert. Das ist wichtig, da das Hauptziel von Architektur ist, die Entropie und damit die Komplexität von Software zu minimieren.<br /></li></ol><br />Planung muss sein. Implementation darf Planung nicht torpedieren. (Wenn auch Erkenntnisse während der Implementation natürlich auf die Planung zurückwirken dürfen.) Deshalb sind Planung und Implementation zu entkoppeln. Und wo das nicht möglich ist, da sollte die Planung mit Mitteln der Implementation arbeiten und die Implementation physisch die Planung widerspiegeln.
</div><br /><br /><h3 class="separator">You Ain´t Gonna Need It (YAGNI)<a class="headeranchor" id="You_Ain´t_Gonna_Need_It_YAGNI_2" href="#You_Ain´t_Gonna_Need_It_YAGNI_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Dinge die niemand braucht, haben keinen Wert. Verschwende an sie also keine Zeit.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td>++</td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Das YAGNI-Prinzip (<i>You Ain´t Gonna Need It</i>) ist eines der einfachsten in der Softwareentwicklung - und doch wohl das nach dem DRY-Prinzip am häufigsten verletzte Prinzip. Deshalb steht YAGNI nicht nur am Anfang des <a class="pagelink" href="Roter-Grad.ashx" title="Roter Grad">roten Grads</a>, sondern auch hier gegen Ende des Weges durch das <a class="pagelink" href="Wertesystem.ashx" title="Wertesystem">Wertesystem</a>.<br /><br />Geschuldet ist die YAGNI-Regel dem in der Softwareentwicklung besonderen Verhältnis von Anforderungsgenauigkeit und Produktmaterialität. Anforderungen sind notorisch ungenau oder wechselnd und das Produkt, in dem sie umgesetzt werden sollen, immateriell. Im Vergleich zum Maschinen- oder Gebäudebau ist das Material also unendlich flexibel und kann sich prinzipiell mit vergleichsweise wenig Aufwand an quasi jede Anforderung anpassen lassen. Hohe Volatiliät bzw. Ungenauigkeit trifft also auf hohe Flexibilität. Das scheint zunächst einmal ideal.<br /><br />Die Praxis zeigt jedoch, dass gerade in diesem Verhältnis der Keim des Misserfolges vieler Projekte liegt. Kurzfristig betrachtet, versuchen die Projekte mit dem Naheliegenden auch das Richtige zu tun:
<ul><li>Ungenaue Anforderungen werden oft kompensiert durch Produkte, die versuchen, die Ungenauigkeit zu kompensieren. Die Immaterialität von Software wird dazu genutzt, so breit und flexibel zu implementieren, dass auch noch unbekannte oder schwammige Anforderungen quasi schon im vorauseilenden Gehorsam erfüllt werden.</li><li>Ständig wechselnde Anforderungen werden im Produkt möglichst schnell nachgeführt, weil das dank seiner Immaterialität möglich ist.<br /></li></ul><br />Langfristig ist solches Verhalten allerdings kontraproduktiv:
<ul><li>Der vorauseilende Gehorsam führt zu Breite und Flexibilität, die nicht wirklich gebraucht werden. Er realisiert Features, die keine Anwendung finden.</li><li>Schnelle Umbauten an Software aufgrund wechselnder Anforderungen führen zu Qualitätserosionen im Code. Software ist zwar immateriell und flexibel - aber nicht jede Softwarestruktur ist evolvierbar oder auch nur verständlich.<br /></li></ul><br />Unklare und wechselnde Anforderungssituationen vor dem Hintergrund der hohen grundsätzlichen Flexibilität von Software führen schnell zu unnötigen Aufwänden und sprödem Code. Eine große Anzahl von Projekten, die ihre Budgetgrenzen gesprengt haben, und eine noch größere Zahl von Projekten, die schon nach wenigen Jahren unwartbar geworden sind, sind dafür beredtes Zeugnis.<br /><br />CCD als professionelle Softwareentwickler sehen es als ihre Pflicht, sich solcher Entwicklung jeden Tag entgegen zu stemmen. Angesichts der nicht zu leugnenden Natur von Software - sie ist und bleibt immateriell -, liegt der Ansatz dafür beim Umgang mit den Anforderungen. Das ist der Ursprung der YAGNI-Regel.<br /><br />Die YAGNI-Regel ist wie ein scharfes Messer: Wer sie anwendet, schneidet ein Problem in kleine Würfel des unmittelbar Nötigen. Nach der YAGNI-Regel wird nur das unzweifelhaft und unmittelbar Nutzbringende implementiert. Alles andere... nun, das kommt später. Insofern geht YAGNI Hand in Hand mit der Regel "Entscheide so spät wie möglich" des <a class="externallink" href="http://en.wikipedia.org/wiki/Lean_software_development#Decide_as_late_as_possible" title="Lean Software Development" target="_blank">Lean Software Development</a>.<br /><br />Die YAGNI-Regel ist relevant auf allen Ebenen der Softwareentwicklung und in allen Phasen. Wann immer Sie sich Fragen "Sollte ich diesen Aufwand wirklich treiben?" oder "Brauchen wir das wirklich?" - und sei es auch nur ganz verschämt und leise im Hinterkopf -, dann ist das ein Anwendungsfall für die YAGNI-Regel. Sie besagt: Wenn im Zweifel, entscheide dich gegen den Aufwand.<br /><br />Das klingt leicht, ist aber schwer. Daher auch die häufigen Zuwiderhandlungen. Es gibt viele Kräfte, die der Entscheidung gegen einen Aufwand widersprechen. "Ach, das ist doch gar nicht soviel Aufwand" oder "Wenn wir jetzt nicht vorausschauen, dann können wir in Zukunft nicht mehr anders" sind nur zwei naheliegende Begründungen für Aufwand, auch wenn Zweifel an seinem Nutzen bestehen. Das betrifft architektonische Entscheidungen (z.B. Soll schon mit einer verteilten Architektur begonnen werden, auch wenn die heutige Last sie noch nicht bräuchte?) wie lokale Entscheidungen (z.B. Soll der Algorithmus schon jetzt optimiert werden, auch wenn er im Augenblick noch keine Performanceprobleme macht?).<br /><br />Der Kunde bezahlt nur für unmittelbaren Nutzen. Was er heute nicht klar spezifizieren kann, nutzt ihm nicht. Es in der Implementation voraussehen zu wollen, investiert also Aufwand ohne Nutzen zu generieren. Wenn der Kunde später einmal genauer weiß, was er will, dann - und nicht früher! - ist es Zeit, seinem Willen nachzukommen. Wo immer aber ein Projekt versucht, diesen Willen vorwegzunehmen riskiert es, von der morgigen Willensrealität des Kunden widerlegt zu werden. Ein Feature - funktional oder nicht-funktional -, das heute ohne klare Anforderung implementiert wird, interessiert den Kunden morgen vielleicht schon nicht mehr. Oder es ist ihm nicht mehr so wichtig wie ein anderes Feature.<br /><br />Das bedeutet für die Softwareentwicklung:
<ul><li>Ausschließlich klare Anforderungen implementieren.</li><li>Der Kunde priorisiert seine klaren Anforderungen.</li><li>Die klaren Anforderungen in der Reihenfolge ihrer Priorisierung umsetzen.</li><li>Entwicklungsprozess und Codestruktur im Großen und Kleinen so aufsetzen, dass keine Angst aufkommt, sich ändernde und neue Anforderungen zu realisieren.<br /></li></ul><br />CCD als professionelle Entwickler kommunizieren diese Vorgehensweise unmissverständlich dem Kunden gegenüber. Dadurch werden sie:
<ul><li>servicewillig, denn sie müssen dem Kunden keine klare Anforderung abschlagen</li><li>verantwortungsbewusst, weil sie das Budget nur für klar formulierten Nutzen einsetzen</li><li>beschützend dem Code gegenüber, weil sie ihn gegen Überladung mit letztlich Unnötigem bewahren<br /></li></ul><br />YAGNI ist deshalb nicht nur eine Regel, die jeder Entwickler befolgen soll, sondern auch eine Regel für Projekte und Teams, also auf Organisationsebene. YAGNI ist immer in Anschlag zu bringen, genauso wie DRY. Wenn im Zweifel, dann verschiebe die Entscheidung falls möglich. Ansonsten entscheide dich gegen den Aufwand. Das entspannt und entschlackt und führt schneller zum Erfolg. 
</div><br /><br /><h2 class="separator">Praktiken<a class="headeranchor" id="Praktiken_8" href="#Praktiken_8" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Continuous Delivery<a class="headeranchor" id="Continuous_Delivery_3" href="#Continuous_Delivery_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Als Clean Code Developer möchte ich sicher sein, dass ein Setup das Produkt korrekt installiert. Wenn ich das erst beim Kunden herausfinde, ist es zu spät.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td></td><td>+</td><td>++</td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Im <a class="pagelink" href="Gr%c3%bcner-Grad.ashx" title="Grüner Grad">grünen Grad</a> haben wir den Continuous Integration Prozess für Build und Test aufgesetzt. Damit sorgt der Continuous Integration Prozess dafür, dass Fehler während der Build- und Testphase schnell entdeckt werden. Wenn z.B. eine Änderung am Code dazu führt, dass eine andere Komponente nicht mehr übersetzt werden kann, weist der Continuous Integration Prozess kurze Zeit nach dem Commit der Änderung auf den Fehler hin. Wenn am Ende jedoch ein Setup Programm produziert wird, welches sich aufgrund von Fehlern nicht installieren lässt, haben wir unser Ziel trotzdem nicht erreicht: funktionierende Software die bei unseren Kunden installiert werden kann.<br /><br />Folglich müssen wir auch die Phasen Setup und Deployment automatisieren, um sie per Knopfdruck ausführen zu können. Nur so können wir sicher sein, dass wir installierbare Software produzieren. Und durch die Automatisierung ist sichergestellt, dass niemand einen wichtigen Schritt, der "zu Fuß" ausgeführt werden muss, vergisst. So kann jeder im Team zu jedem Zeitpunkt den aktuellen Stand des Produktes installationsfertig produzieren und installieren.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Iterative Entwicklung<a class="headeranchor" id="Iterative_Entwicklung_4" href="#Iterative_Entwicklung_4" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Warum? Frei nach von Clausewitz: Kein Entwurf, keine Implementation überlebt den Kontakt mit dem Kunden. Softwareentwicklung tut daher gut daran, ihren Kurs korrigieren zu können.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td>+</td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Natürlich schreitet Softwareentwicklung immer von einer Planung über die Implementation zu einem Test durch den Kunden voran. Irrig ist allerdings die Annahme, ein Projekt käme mit einer Planungsphase und einer Implementationsphase und einer Kundentestphase aus. Das funktioniert - wenn überhaupt - nur in trivialen Szenarien, wo in der Planungsphase alle Anforderungen bekannt sind. In realen Projekten jedoch liefert jede Phase Erkenntnisse für vorhergehende Phasen. Allemal durch den Kundentest ergeben sich Konsequenzen für die Planung und Implementation.<br /><br />Solche Erkenntnisse können allerdings nur Einfluss auf ein Projekt nehmen, wenn das Vorgehen nicht linear ist. Wenn es von einer späteren Phase keinen Weg zurück zu einer früheren Phase gibt, ist Feedback nutzlos.<br /><br />Um Feedback in ein Softwareprodukt einfließen lassen zu können, muss der Entwicklungsprozess Schleifen enthalten. Allemal die Schleife von der Kundentestphase zurück zur Planung ist nötig. Das heißt, Softwareentwicklung kann nur iterativ, also in mehreren Durchläufen, über den Anforderungskatalog des Kunden stattfinden. Wer versucht, "mit einem Mal" (big bang) auszuliefern, handelt dieser Erkenntnis zuwider. Der Softwareentwicklungsprozes ist vielmehr so zu planen, dass er sich durch die Anforderungen "in kleinen Happen durchbeißt". Jeder dieser Happen sollte nicht größer sein, als dass der Durchlauf von Planung bis Kundentest mehr als 2-4 Wochen dauert. Nur dann kommt das Feedback vom Kunden häufig genug, um nicht allzu lange in der Umsetzung in die Irre zu laufen.<br /><br />Softwareentwicklung ist damit ein Lernprozess. In seinem Verlauf lernt das Projektteam etwas über die Anforderungen des Kunden. Es hört ihm zu, plant, implementiert, und händigt eine Softwareversion aus, die das Verständnis des Gehörten widerspiegelt. Dann hört das Team wieder zu, plant weiter/erneut nach den aktuellen Erkenntnissen usw. usf. immer im Kreis. Iteration für Iteration. Manchmal wird etwas aus einer früheren Iteration verfeinert, manchmal Neues hinzugefügt.<br /><br />Doch nicht nur die Entwicklung einer Software ist ein Lernprozess. Lernen sollte auch auf organisatorischer Ebene stattfinden. Das Team sollte nicht nur über den Kunden etwas lernen, sondern auch über sich selbst. Deshalb sollte es auch immer wieder "Haltepunkte" geben, an denen das Team über sein Vorgehen reflektiert. Die Erkenntnisse aus solcher Retrospektive fließen dann ein in die nächste Iteration der organisatorischen Entwicklung. Hier schließt der blaue Grad an den roten Grad an, zu dem die tägliche persönliche Reflexion gehört.<br /><br />Natürlich muss jede Iteration auch ein Ende haben. Und damit man weiß ob man fertig ist, muss vorher klar definiert sein, was in der Iteration erreicht werden soll. Die Erreichbarkeit von Zielen kann immer nur geschätzt werden, auch dabei hilft die Reflexion, um die Schätzungen schrittweise soweit zu verbessern, dass sie für die Planung ausreichend genau sind. Doch wann ist das vorher definierte Ziel erreicht? <a class="externallink" href="http://www.hanselminutes.com/default.aspx?showID=137" title="'What is done?'" target="_blank">'What is done?'</a> Oberstes Ziel ist die Lieferung funktionsfähiger Software an unsere Kunden. Folglich kann das Ziel nur erreicht sein wenn wir auslieferungsfertige Software produziert haben. Das bedeutet insbesondere, dass die Software getestet ist und dass sie per Setup installiert werden kann. Durch Continuous Integration stellen wir dies kontinuierlich sicher. Keinesfalls dürfen wir kurz vor Ende einer Iteration entscheiden, dass ein Ziel erreicht ist, obwohl noch nicht alle Tests abgeschlossen sind.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Komponentenorientierung<a class="headeranchor" id="Komponentenorientierung_5" href="#Komponentenorientierung_5" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Software braucht Black-Box-Bausteine, die sich parallel entwickeln und testen lassen. Das fördert Evolvierbarkeit, Produktivität und Korrektheit.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td>+</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Die Prinzipien des <a class="pagelink" href="Wertesystem.ashx" title="Wertesystem">CCD-Wertesystems</a> haben sich bisher vor allem auf kleinere Codeausschnitte bezogen. Was sollte in einer Methode stehen, was sollte über mehrere verteilt werden? Welche Methoden sollte eine Klasse veröffentlichen? Woher sollte ein Client-Objekt zu einem Service-Objekt kommen? Bisher ging es um Prinzipien für die Softwareentwicklung im Kleinen.<br /><br />Hat das CCD-Wertesystem denn aber nichts zu größeren Strukturen, zur Softwareentwicklung im Großen zu sagen? Wie steht es mit der Softwarearchitektur? Genau hier setzt das Prinzip der Komponentenorientierung an. Bisher haben wir zwar auch schon das Wort "Komponente" gebraucht, doch eher lax und in einem umgangssprachlichen Sinn. Von nun an jedoch soll <i>Komponente</i> etwas sehr spezifisches beschreiben, das wir für grundlegend für evolvierbare Software halten.<br /><br />Solange wir Software letztlich nur aus Klassen mit Methoden aufgebaut denken, versuchen wir sozusagen Computer auf Transistorebene zu beschreiben. Das funktioniert letztlich aber nicht, weil wir im Detailreichtum ersticken. Selbst die Klassen in Schichten zusammenzufassen hilft da nicht viel. Wir brauchen vielmehr sowohl ein Beschreibungsmittel für größere Softwarestrukturen. Aber nicht nur das: das Beschreibungsmittel sollte auch ein Implementationsmittel sein - so wie Klassen -, damit das Modell, der Plan, die Beschreibung sich im Code widerspiegelt.<br /><br />Betriebssystemprozesse sind zwar solche architektonischen Mittel, letztlich sind auch sie jedoch zu groß. Solange die EXE eines Prozesses einer Applikation aus mehreren Hundert oder Tausend Klassen besteht, gewinnen wir nichts.<br /><br />Hilfe bringt allerdings das Prinzip der Komponentenorientierung. Es besagt, dass ein Anwendungsprozess zunächst einmal aus Komponenten besteht und nicht aus Klassen. Erst die Bausteine der Komponenten sind dann Klassen. Und was ist eine Komponente? Es gibt einige Definitionen für Komponenten, von denen im Kern zwei Kriterien unverbrüchlich erscheinen:
<ul><li>Komponenten sind binäre Funktionseinheiten. (Eine Klasse hingegen ist eine Funktionseinheit auf Quellcodeebene.)</li><li>Die Leistung von Komponenten wird durch einen separaten (!) Kontrakt beschrieben. (Die Leistungsbeschreibung einer Klasse liegt hingegen in ihr. Es ist die Summe ihrer Methodensignaturen.)<br /></li></ul><br />Ein CCD sucht beim Entwurf einer Software nach der Definition der Prozesse also zunächst nach den Komponenten, aus denen die Prozesse bestehen sollten. Er fragt sich, welche "Dienstleistungsblöcke" machen die Anwendung aus? Und diese Blöcke sieht der CCD als Black Boxes in Bezug auf ihren Aufbau aus Klassen an. Diese Blöcke sind Assemblies mit wohldefinierter Dienstleistung, aber unbekannter Struktur.<br /><br />Eine Client-Komponente C weiß daher nichts über die Klassenstruktur ihrer Service-Komponente S. C kennt nur den Kontrakt von S, der unabhängig von der Implementaton von S ist. Kontrakte sind insofern für Komponenten das, was Interfaces für Klassen sind. Nicht zufällig bestehen Kontrakte zu einem guten Teil oder gar vollständig aus Interfaces.<br /><br />Komponenten sind also Elemente der Planung wie auch der Implementation. Um das zu unterstreichen, werden Komponenten physisch unabhängig voneinander implementiert; ein probates Mittel dafür sind <i>Komponentenwerkbänke</i>, d.h. separate Visual Studio Solutions je Komponentenimplementation. Das fördert nicht nur die Konzentration auf eine Aufgabe, weil man während der Arbeit an einer Komponente in der IDE nur deren Code sieht. Darüber hinaus fördert es auch konsequente Unit Tests unter Einsatz von Attrappen, da Quellcode anderer Komponenten nicht sichtbar ist. Außerdem steigert solche Codeorganisation die Produktivität, weil Komponenten dank ihrer separaten Kontrakte parallel implementiert werden können. Und schließlich stellt sich eine physische Isolation gegen den schleichenden Zuwachs an Entropie im Code. Denn wo Bindungen zwischen Komponenten nur via Kontrakt aufgebaut werden können, ist die Kopplung lose und kontrolliert.<br /><br />Zur Komponentenorientierung gehören deshalb nicht nur binäre, größere Codeeinheiten mit separaten Kontrakten, sondern auch die Entwicklung der Kontrakte vor der Implementation (<i>Contract-first Design</i>). Denn sobald die Kontrakte definiert sind, die eine Komponente importiert und exportiert, kann die Arbeit an der Komponente unabhängig von allen anderen beginnen.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Test first<a class="headeranchor" id="Test_first_6" href="#Test_first_6" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Der Kunde ist König und bestimmt die Form einer Dienstleistung. Service-Implementationen sind also nur passgenau, wenn sie durch einen Client getrieben werden.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td>+</td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Wenn Komponentenorientierung fordert, die Kontrakte für Komponenten unabhängig von ihrer Implementation zu definieren, stellt sich die Frage, wie das denn geschehen soll. Durch Diskussion am runden Tisch? Das ist sicherlich ein Weg. Ein besserer ist jedoch, Kontrakte nicht erst lange an einer Tafel zu entwerfen, sondern sie sofort in Code zu gießen. Komponentenkontrakte - oder allgemeiner: jede Codeschnittstelle - dient letztlich anderem Code als API. Es ist daher konsequent und effektiv, von diesem Code ausgehend Schnittstellen zu spezifizieren.<br /><br />Das ist das Anliegen von <i>Test first</i>. Test first basiert auf dem Gedanken, dass Funktionseinheiten (Methoden, Klassen, usw.) durch Client-Service-Verhältnisse charakterisiert sind. Diese Verhältnisse drehen sich um die Schnittstelle zwischen Client und Service. Und diese Schnittstelle sollte durch den Client bestimmt werden. Der Client ist als Kunde des Service König. Ihm soll der Service dienen, nach ihm soll sich deshalb die Schnittstelle des Service richten.<br /><br />Die Definition der Schnittstellen der Codeeinheiten einer Software erfolgt aus diesem Grund von außen nach innen. Außen, an der Benutzeroberfläche, sitzt der ultimative Client, der Anwender. Er definiert die visuelle/haptische Schnittstelle der UI-Codeeinheiten. Die wiederum sind die Clients von darunterliegenden Codeschichten. Die sind dann Clients von tieferliegenden Schichten usw. Die Leistungen und Schnittstellen der tiefsten Codeschichten kann somit nur bestimmt werden, wenn die der darüberliegenden schon bestimmt sind usw.<br /><br />Das widerspricht dem häufigen Ansatz der bottom-up Definition von Codeeinheiten. Gern fangen Projekte an, eine Datenzugriffsschicht zu definieren und zu implementieren. Das ist verständlich, weil solch fundamentale Funktionalität doch scheinbar die Voraussetzung für alles weitere ist. Aber dieses Vorgehen ist problematisch, wie viele gescheiterte Projekte zeigen:
<ul><li>Wer von unten nach oben, von innen nach außen spezifiziert und implementiert, bietet dem Kunden erst sehr spät einen Wert an. Das ist zumindest frustrierend, wenn nicht gar kontraproduktiv.</li><li>Wer bottom-up in der Spezifikation vorgeht, der spezifiziert ohne genaue Anforderungen des ultimativen Clients, des Benutzers. Was er also spezifiziert läuft Gefahr, am Ende zu allgemein und damit unhandlich zu sein - oder schlicht nicht gebraucht zu werden (eine Verletzung der YAGNI-Regel, s.o. und im <a class="pagelink" href="Roter-Grad.ashx" title="Roter Grad">roten Grad</a>).</li><li>Wer von unten nach oben implementiert, läuft Gefahr, nicht wirklich zu entkoppeln. Denn wenn tiefere Schichten nötig sind, um darüberliegende zu implementieren, dann werden wahrscheinlich keine wirklich isolierten Unit Tests mit Attrappen eingesetzt und auch keine Inversion of Control.<br /></li></ul><br />Clean Code Developer vermeiden diese Probleme jedoch. Sie spezifizieren Schnittstelle nicht nur vor den Implementationen (Contract-first, s.o. Komponentenorientierung), sondern auch von außen nach innen und ganz praktisch durch Codierung. Mit den Mitteln des automatisierten Testens ist es nämlich sehr einfach, Schnittstellen in kleinen Schritten in Form von Tests zu definieren.<br /><br />Test first fügt dadurch syntaktischen Kontrakten (z.B. Interfaces) eine semantische Seite hinzu. In Ermangelung anderer, formaler Methoden, um Semantik zu spezifizieren, sind Tests der einzige Weg, um Anforderungen zu formalisieren. Wer einem Entwickler eine Komponente zur Implementierung zuweisen will, der tut daher gut daran, nicht nur ihre "Oberfläche" (API) syntaktisch vorzugeben, sondern auch das gewünschte Verhalten in Form von Tests.<br /><br />Das hat viele Vorteile:
<ul><li>Die Form einer Schnittstelle ist unmittelbar Client-getrieben und damit maximal relevant. YAGNI hat keine Chance.</li><li>Die Tests sind nicht nur Tests, sondern auch Spezifikationsdokumentation. Nutzer einer Schnittstelle und Implementierer können sie gleichermaßen studieren. Eine separate Dokumentation erübrigt sich weitgehend. Das tut dem DRY-Prinzip genüge.</li><li>Die Spezifikationen sind nicht nur passive Texte, sondern ausführbarer Code. Wenn dann eine Implementation vorliegt, kann sie gegen diese Tests geprüft werden. Spezifikation und Test sind damit nicht zeitraubend aufeinanderfolgende Phasen. Das erhöht die Produktivität. Qualitätssicherung ist so der Implementation schon vorgeschaltet.<br /></li></ul><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br />Weiter geht's mit dem <a class="pagelink" href="Wei%c3%9fer-Grad.ashx" title="Weißer Grad">weißen Grad</a><br /><br />]]></description><pubDate>Sun, 20 Feb 2011 17:50:12 GMT</pubDate><guid isPermaLink="false">AE08D4AC9AAC8E4B7283814C1B6569A9</guid></item><item><title><![CDATA[YAGNI]]></title><link>http://clean-code-developer.de/YAGNI.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[
]]></description><pubDate>Sun, 20 Feb 2011 17:49:42 GMT</pubDate><guid isPermaLink="false">9E02700AA5321DA9A45343823D8C60D8</guid></item><item><title><![CDATA[You Ain´t Gonna Need It (YAGNI)]]></title><link>http://clean-code-developer.de/You-Ain-t-Gonna-Need-It-YAGNI.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Dinge die niemand braucht, haben keinen Wert. Verschwende an sie also keine Zeit.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td>++</td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Das YAGNI-Prinzip (<i>You Ain´t Gonna Need It</i>) ist eines der einfachsten in der Softwareentwicklung - und doch wohl das nach dem DRY-Prinzip am häufigsten verletzte Prinzip. Deshalb steht YAGNI nicht nur am Anfang des <a class="pagelink" href="Roter-Grad.ashx" title="Roter Grad">roten Grads</a>, sondern auch hier gegen Ende des Weges durch das <a class="pagelink" href="Wertesystem.ashx" title="Wertesystem">Wertesystem</a>.<br /><br />Geschuldet ist die YAGNI-Regel dem in der Softwareentwicklung besonderen Verhältnis von Anforderungsgenauigkeit und Produktmaterialität. Anforderungen sind notorisch ungenau oder wechselnd und das Produkt, in dem sie umgesetzt werden sollen, immateriell. Im Vergleich zum Maschinen- oder Gebäudebau ist das Material also unendlich flexibel und kann sich prinzipiell mit vergleichsweise wenig Aufwand an quasi jede Anforderung anpassen lassen. Hohe Volatiliät bzw. Ungenauigkeit trifft also auf hohe Flexibilität. Das scheint zunächst einmal ideal.<br /><br />Die Praxis zeigt jedoch, dass gerade in diesem Verhältnis der Keim des Misserfolges vieler Projekte liegt. Kurzfristig betrachtet, versuchen die Projekte mit dem Naheliegenden auch das Richtige zu tun:
<ul><li>Ungenaue Anforderungen werden oft kompensiert durch Produkte, die versuchen, die Ungenauigkeit zu kompensieren. Die Immaterialität von Software wird dazu genutzt, so breit und flexibel zu implementieren, dass auch noch unbekannte oder schwammige Anforderungen quasi schon im vorauseilenden Gehorsam erfüllt werden.</li><li>Ständig wechselnde Anforderungen werden im Produkt möglichst schnell nachgeführt, weil das dank seiner Immaterialität möglich ist.<br /></li></ul><br />Langfristig ist solches Verhalten allerdings kontraproduktiv:
<ul><li>Der vorauseilende Gehorsam führt zu Breite und Flexibilität, die nicht wirklich gebraucht werden. Er realisiert Features, die keine Anwendung finden.</li><li>Schnelle Umbauten an Software aufgrund wechselnder Anforderungen führen zu Qualitätserosionen im Code. Software ist zwar immateriell und flexibel - aber nicht jede Softwarestruktur ist evolvierbar oder auch nur verständlich.<br /></li></ul><br />Unklare und wechselnde Anforderungssituationen vor dem Hintergrund der hohen grundsätzlichen Flexibilität von Software führen schnell zu unnötigen Aufwänden und sprödem Code. Eine große Anzahl von Projekten, die ihre Budgetgrenzen gesprengt haben, und eine noch größere Zahl von Projekten, die schon nach wenigen Jahren unwartbar geworden sind, sind dafür beredtes Zeugnis.<br /><br />CCD als professionelle Softwareentwickler sehen es als ihre Pflicht, sich solcher Entwicklung jeden Tag entgegen zu stemmen. Angesichts der nicht zu leugnenden Natur von Software - sie ist und bleibt immateriell -, liegt der Ansatz dafür beim Umgang mit den Anforderungen. Das ist der Ursprung der YAGNI-Regel.<br /><br />Die YAGNI-Regel ist wie ein scharfes Messer: Wer sie anwendet, schneidet ein Problem in kleine Würfel des unmittelbar Nötigen. Nach der YAGNI-Regel wird nur das unzweifelhaft und unmittelbar Nutzbringende implementiert. Alles andere... nun, das kommt später. Insofern geht YAGNI Hand in Hand mit der Regel "Entscheide so spät wie möglich" des <a class="externallink" href="http://en.wikipedia.org/wiki/Lean_software_development#Decide_as_late_as_possible" title="Lean Software Development" target="_blank">Lean Software Development</a>.<br /><br />Die YAGNI-Regel ist relevant auf allen Ebenen der Softwareentwicklung und in allen Phasen. Wann immer Sie sich Fragen "Sollte ich diesen Aufwand wirklich treiben?" oder "Brauchen wir das wirklich?" - und sei es auch nur ganz verschämt und leise im Hinterkopf -, dann ist das ein Anwendungsfall für die YAGNI-Regel. Sie besagt: Wenn im Zweifel, entscheide dich gegen den Aufwand.<br /><br />Das klingt leicht, ist aber schwer. Daher auch die häufigen Zuwiderhandlungen. Es gibt viele Kräfte, die der Entscheidung gegen einen Aufwand widersprechen. "Ach, das ist doch gar nicht soviel Aufwand" oder "Wenn wir jetzt nicht vorausschauen, dann können wir in Zukunft nicht mehr anders" sind nur zwei naheliegende Begründungen für Aufwand, auch wenn Zweifel an seinem Nutzen bestehen. Das betrifft architektonische Entscheidungen (z.B. Soll schon mit einer verteilten Architektur begonnen werden, auch wenn die heutige Last sie noch nicht bräuchte?) wie lokale Entscheidungen (z.B. Soll der Algorithmus schon jetzt optimiert werden, auch wenn er im Augenblick noch keine Performanceprobleme macht?).<br /><br />Der Kunde bezahlt nur für unmittelbaren Nutzen. Was er heute nicht klar spezifizieren kann, nutzt ihm nicht. Es in der Implementation voraussehen zu wollen, investiert also Aufwand ohne Nutzen zu generieren. Wenn der Kunde später einmal genauer weiß, was er will, dann - und nicht früher! - ist es Zeit, seinem Willen nachzukommen. Wo immer aber ein Projekt versucht, diesen Willen vorwegzunehmen riskiert es, von der morgigen Willensrealität des Kunden widerlegt zu werden. Ein Feature - funktional oder nicht-funktional -, das heute ohne klare Anforderung implementiert wird, interessiert den Kunden morgen vielleicht schon nicht mehr. Oder es ist ihm nicht mehr so wichtig wie ein anderes Feature.<br /><br />Das bedeutet für die Softwareentwicklung:
<ul><li>Ausschließlich klare Anforderungen implementieren.</li><li>Der Kunde priorisiert seine klaren Anforderungen.</li><li>Die klaren Anforderungen in der Reihenfolge ihrer Priorisierung umsetzen.</li><li>Entwicklungsprozess und Codestruktur im Großen und Kleinen so aufsetzen, dass keine Angst aufkommt, sich ändernde und neue Anforderungen zu realisieren.<br /></li></ul><br />CCD als professionelle Entwickler kommunizieren diese Vorgehensweise unmissverständlich dem Kunden gegenüber. Dadurch werden sie:
<ul><li>servicewillig, denn sie müssen dem Kunden keine klare Anforderung abschlagen</li><li>verantwortungsbewusst, weil sie das Budget nur für klar formulierten Nutzen einsetzen</li><li>beschützend dem Code gegenüber, weil sie ihn gegen Überladung mit letztlich Unnötigem bewahren<br /></li></ul><br />YAGNI ist deshalb nicht nur eine Regel, die jeder Entwickler befolgen soll, sondern auch eine Regel für Projekte und Teams, also auf Organisationsebene. YAGNI ist immer in Anschlag zu bringen, genauso wie DRY. Wenn im Zweifel, dann verschiebe die Entscheidung falls möglich. Ansonsten entscheide dich gegen den Aufwand. Das entspannt und entschlackt und führt schneller zum Erfolg. 
]]></description><pubDate>Sun, 20 Feb 2011 17:49:21 GMT</pubDate><guid isPermaLink="false">132299257DD242A5102CC03C495AE9EA</guid></item><item><title><![CDATA[Implementation spiegelt Entwurf]]></title><link>http://clean-code-developer.de/Implementation-spiegelt-Entwurf.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Umsetzung, die von der Planung beliebig abweichen kann, führt direkt in die Unwartbarkeit. Umsetzung braucht daher einen durch die Planung vorgegebenen physischen Rahmen.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Architektur und Implementation sollen nicht überlappen, damit sie das DRY-Prinzip nicht verletzten. So werden Inkonsistenzen vermieden, die dadurch entstehen können, dass auf der einen Seite etwas geändert wird, ohne diese Änderung auf der anderen Seite nachzuführen.<br /><br />Nichtsdestotrotz macht die Architektur aber ja Aussagen über die Implementation. Nicht ihre Details, aber ihre grundsätzliche Form. Architektur definiert die Strukturelemente und deren Beziehungen innerhalb eines Codesystems. Implementation existiert also bei auch bei Abwesenheit von Überlappungen nicht unabhängig von Architektur, sondern sozusagen in ihr.<br /><br />Genau das sollte sich dann aber auch in der Implementation ausdrücken. So wird die leichter verständlich, so kann besser sichergestellt werden, dass die Implementation tatsächlich der Architektur folgt. Die von der Architektur auf verschiedenen Abstraktionsebenen definierten Strukturelemente sollten deshalb nicht in einem großen "Codetopf" (z.b. eine große Visual Studio Solution) "zusammengerührt werden". Viel besser auch im Sinne hoher Produktivität und einfacher Testbarkeit ist es, die logischen Strukturen der Architektur so physisch wie möglich zu manifestieren.<br /><br /><ol><li>Die von der Architektur geplanten Strukturen auf verschiedenen Abstraktionsebenen sollten sich so weitgehend wie möglich in der Codeorganisation widerspiegeln. Das bedeutet zum einen, dass die Architektur als Strukturelemente vor allem physische Codeeinheiten benutzt. Und zum anderen sollen diese Strukturelemente dann aber auch im Quellcode bzw. in der Codeorganisation im Repository klar sichtbar sein.</li><li>Bei der Arbeit an der Implementation der Strukturelemente und insbesondere innerhalb von Komponenten sollen Architekturänderungen "im Vorbeigehen" unmöglich sein. Wer in bzw. an einem Strukturelement arbeitet, also an einem Teil, darf nicht ad hoc die umliegende Struktur, d.h. das Ganze, ändern können. Nur wenn das gewährleistet ist, wächst die Entropie einer Software nicht unkontrolliert. Das ist wichtig, da das Hauptziel von Architektur ist, die Entropie und damit die Komplexität von Software zu minimieren.<br /></li></ol><br />Planung muss sein. Implementation darf Planung nicht torpedieren. (Wenn auch Erkenntnisse während der Implementation natürlich auf die Planung zurückwirken dürfen.) Deshalb sind Planung und Implementation zu entkoppeln. Und wo das nicht möglich ist, da sollte die Planung mit Mitteln der Implementation arbeiten und die Implementation physisch die Planung widerspiegeln.
]]></description><pubDate>Sun, 20 Feb 2011 17:48:34 GMT</pubDate><guid isPermaLink="false">5F5662C04CD53B7D6B0336C648768BCE</guid></item><item><title><![CDATA[Entwurf und Implementation überlappen nicht]]></title><link>http://clean-code-developer.de/Entwurf-und-Implementation-uberlappen-nicht.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Planungsunterlagen, die mit der Umsetzung nichts mehr gemein haben, schaden mehr, als dass sie nützen. Deshalb nicht die Planung aufgeben, sondern die Chance auf Inkonsistenz minimieren.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td>+</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Eines der grundlegenden Probleme der Softwareentwicklung sind Implementationen, denen ein vorausgegangene Planung nicht mehr anzusehen ist. Da hängen dann Entwurfsdiagramme an der Wand, die kaum noch etwas mit der Coderealität zu tun haben. Die Ursache dafür ist eine Verletzung des fundamentalen DRY-Prinzips: Entwurf und Implementation sind Wiederholungen desselben, der Struktur einer Software. Da Implementation auf Entwurf folgt und den Löwenanteil der Arbeit ausmacht, geraten beide schnell aus dem Tritt, wenn Strukturänderungen während der Implementation nicht immer wieder in den Entwurf eingearbeitet werden. Entwurfsdiagramme sind nach Beginn der Implementation sonst bald nichts mehr wert.<br /><br />Wie kann die Situation verbessert werden? Sollte vielleicht auf Entwurf verzichtet werden, wenn letztlich in der Implementation die "Strukturwahrheit" liegt? Nein, sicher nicht. Entwurf muss sein. Ohne Planung gibt es keine Zielvorstellung. Aber Entwurf und Implementation müssen dem DRY-Prinzip gerecht werden. Deshalb sollten Entwurf und Implementation sich so wenig überlappen wie möglich. Ihre Schnittstelle sollte dünn sein. Wenn das der Fall ist, stellen sie keine Wiederholungen mehr dar, sondern beschreiben unterschiedliches. Das bedeutet: Entwurf/Architektur kümmert sich nicht um die Implementation und Implementation kümmert sich nicht um Architektur.<br /><br />Und wo verläuft diese Trennlinie? Bei den so genannten Komponenten (s.u. Praktiken). Architekten kümmern sich nicht um den internen Aufbau von Komponenten. Für sie sind es Black Boxes, deren Klassenstruktur nicht architekturrelevant ist. Umgekehrt ist für einen Komponentenimplementierer die Architektur irrelevant. Was er zu implementieren hat, ergibt sich aus den Komponentenkontrakten, die seine Komponente importiert und exportiert. Einen größeren Zusammenhang muss er nicht kennen.<br /><br />Die Aufgabe der Architektur ist es mithin, Software in Komponenten zu zerlegen, deren Abhängigkeiten zu definieren und Leistungen in Kontrakten zu beschreiben. Diese Strukturen werden dann auch einzig durch Architekten gepflegt. Und die Aufgabe der Implementation ist es, die von der Architektur definierten Komponenten zu realisieren. Wie sie das tun, ist nicht architekturrelevant. Ihre innere Struktur ist für die Architektur unsichtbar.
]]></description><pubDate>Sun, 20 Feb 2011 17:47:43 GMT</pubDate><guid isPermaLink="false">A35F9C374671BD21B57A60D964BC6015</guid></item><item><title><![CDATA[Grüner Grad]]></title><link>http://clean-code-developer.de/Grüner-Grad.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<h1 class="separator">Der grüne Grad<a class="headeranchor" id="Der_grüne_Grad_10" href="#Der_grüne_Grad_10" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
<table id="TocContainerTable"><tr><td><div id="TocContainer"><p class="small"><b>Inhaltsverzeichnis</b><span id="ExpandTocSpan"> [<a href="#" onclick="javascript:if(document.getElementById('Toc').style['display']=='none') document.getElementById('Toc').style['display']=''; else document.getElementById('Toc').style['display']='none'; return false;">Anzeigen/Verbergen</a>]</span></p><div id="Toc"><p><br /><b><a href="#Der_grüne_Grad_10">Der grüne Grad</a></b><br />&nbsp;&nbsp;&nbsp;<a href="#Prinzipien_8">Prinzipien</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Open_Closed_Principle_0">Open Closed Principle</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Tell_don´t_ask_1">Tell, don´t ask</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Law_of_Demeter_2">Law of Demeter</a><br />&nbsp;&nbsp;&nbsp;<a href="#Praktiken_9">Praktiken</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Continuous_Integration_3">Continuous Integration</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Statische_Codeanalyse_Metriken_4">Statische Codeanalyse (Metriken)</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Inversion_of_Control_Container_5">Inversion of Control Container</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Erfahrung_weitergeben_6">Erfahrung weitergeben</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Messen_von_Fehlern_7">Messen von Fehlern</a><br /></p></div></div></td></tr></table><br /><h2 class="separator">Prinzipien<a class="headeranchor" id="Prinzipien_8" href="#Prinzipien_8" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2><h3 class="separator">Open Closed Principle<a class="headeranchor" id="Open_Closed_Principle_0" href="#Open_Closed_Principle_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Weil das Risiko, durch neue Features ein bisher fehlerfreies System zu instabilisieren, so gering wie möglich gehalten werden sollte.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td>+</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Das <i>Open Closed Principle</i> (<a class="externallink" href="http://www.objectmentor.com/resources/articles/ocp.pdf" title="OCP" target="_blank">OCP</a>) besagt, dass eine Klasse offen für Erweiterungen sein muss, jedoch geschlossen gegenüber Modifikationen. Es ist ein weiteres der <a class="pagelink" href="SOLID.ashx" title="SOLID">SOLID</a> Prinzipien. Folgendes Codebeispiel soll verdeutlichen, wo das Problem liegt, wenn das Prinzip nicht befolgt wird:<br /><br /><pre>
public double Preis() &#123;
    const decimal StammkundenRabatt = 0.95m;
    switch(kundenart) &#123;
        case Kundenart.Einmalkunde&#58;
            return menge &#42; einzelpreis;
        case Kundenart.Stammkunde&#58;
            return menge &#42; einzelpreis &#42; StammkundenRabatt;
        default&#58;
            throw new ArgumentOutOfRangeException();
    &#125;
&#125;
</pre>
                    
Das problematische an dieser Form der Implementierung ist, dass die Klasse modifiziert werden muss, wenn eine weitere Art der Preisberechnung erforderlich wird. Die Gefahr dabei ist, dass bei dieser Modifikation Fehler gemacht werden und die bisher schon vorhandenen Funktionen nicht mehr ordnungsgemäß funktionieren. Auch wenn automatisierte Unit Tests und Integrationstests vorhanden sind besteht das Risiko, neue Bugs zu hinterlassen, weil man keine hundertprozentige Testabdeckung erreichen kann. Gesucht ist also generell ein Verfahren, welches die Klasse erweiterbar macht, ohne dass dazu die Klasse selbst modifiziert werden muss. Dies kann z.B. mit Hilfe des <i>Strategy Patterns</i> erreicht werden:<br /><br /><pre>
public interface IPreisRechner &#123;
    double Preis(int menge, double einzelpreis);
&#125;

private IPreisRechner preisRechner;

public double Preis() &#123;
    return preisRechner.Preis(menge, einzelpreis);
&#125;

public class Einmalkunde &#58; IPreisRechner &#123;
    public double Preis(int menge, double einzelpreis) &#123;
        return menge &#42; einzelpreis;
    &#125;
&#125;

public class Stammkunde &#58; IPreisRechner &#123;
    const decimal StammkundenRabatt = 0.95m;
    
    public double Preis(int menge, double einzelpreis) &#123;
        return menge &#42; einzelpreis &#42; StammkundenRabatt;
    &#125;
&#125;
</pre>      
              
Die konkrete Berechnung des Preises wird über ein Interface in andere Klassen ausgelagert. Dadurch ist es möglich, jederzeit neue Implementierungen des Interfaces zu ergänzen. Damit ist die Klasse offen für Erweiterungen, gleichzeitig aber geschlossen gegenüber Modifikationen. Bestehender Code kann z.B. mit dem Refactoring <a class="externallink" href="http://www.industriallogic.com/xp/refactoring/conditionalWithStrategy.html" title="Replace Conditional with Strategy" target="_blank">Replace Conditional with Strategy</a> so umgestaltet werden, dass das Open Closed Principle eingehalten wird.<br /><br /><h4 class="separator">Quellen<a class="headeranchor" id="Quellen_0" href="#Quellen_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<table><thead><tr><th>Quelle</th><th>Autor</th><th>Kurzbeschreibung</th></tr></thead><tbody><tr><td><a class="externallink" href="http://www.objectmentor.com/resources/articles/ocp.pdf" title="http://www.objectmentor.com/resources/articles/ocp.pdf" target="_blank">http://www.objectmentor.com/resources/articles/ocp.pdf</a></td><td>Robert C. Martin</td><td>Artikel zum Open Closed Principle von 1996 veröffentlicht für The C++ Report</td></tr></tbody></table>
</div><br /><br /><h3 class="separator">Tell, don´t ask<a class="headeranchor" id="Tell_don´t_ask_1" href="#Tell_don´t_ask_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Hohe Kohäsion und lose Kopplung sind Tugenden. Öffentliche Zustandsdetails einer Klasse widersprechen dem.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td></td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Etwas provokant formuliert, sollten Klassen keine Property Getter haben. Diese verführen den Verwender einer Klasse dazu, anhand von Werten, die ein Objekt liefert, Entscheidungen zu treffen. Statt also dem Objekt mitzuteilen, was es tun soll, wird es befragt, um dann von außen Betrachtungen über den internen Zustand des Objektes anzustellen.<br /><br />Eines der Kernprinzipien der Objektorientierten Programmierung lautet <i>Information Hiding</i> (siehe dazu auch im <a class="pagelink" href="Gelber-Grad.ashx" title="Gelber Grad">gelben Grad</a>). Keine Klasse soll Details nach außen tragen, aus denen hervorgeht, wie sie intern implementiert ist. Benötigt eine Klasse für ihre Arbeit einen internen Zustand, wird dieser typischerweise in einem internen Feld abgelegt. Wenn nun dieser Wert auch nach außen sichtbar ist, werden Verwender verleitet, diesen eigentlich internen Zustand des Objektes für eigene Entscheidungen heranzuziehen. Dadurch wird die Klasse schnell zur reinen Datenhaltung degradiert. Eine Implementierung, bei der einem Objekt mitgeteilt wird, was es tun soll, ist in jedem Fall vorzuziehen. Dadurch muss es den Verwender nicht mehr interessieren, wie die Klasse die Aufgabe intern bewerkstelligt.<br /><br />Als Ergebnis des <a class="externallink" href="http://www.pragprog.com/articles/tell-dont-ask" title="Tell don't ask" target="_blank">Tell don't ask</a> Prinzips entstehen Objekte mit Verhalten statt "dummer" Datenhaltungsobjekte. Das Zusammenspiel der Objekte ist lose gekoppelt, da die Objekte keine Annahmen über die kollaborierenden Objekte machen müssen. Aber nicht nur das! Wenn Objekte ihren Zustand nicht veröffentlichen, behalten sie die Entscheidungshoheit. Die Kohäsion des entscheidenden Codes wächst damit, weil er an einem Ort zusammengelegt wird.
</div><br /><br /><h3 class="separator">Law of Demeter<a class="headeranchor" id="Law_of_Demeter_2" href="#Law_of_Demeter_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Abhängigkeiten von Objekten über mehrere Glieder einer Dienstleistungskette hinweg führen zu unschön enger Kopplung.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Beim <a class="externallink" href="http://www.lieser-online.de/blog/?p=124" title="Law of Demeter" target="_blank">Law of Demeter</a> geht es darum, das Zusammenspiel von Objekten auf ein gesundes Maß zu beschränken. Man kann es vereinfacht umschreiben mit "Don't talk to strangers". Nach dem Law of Demeter soll eine Methode nur folgende andere Methoden verwenden:
<ul><li>Methoden der eigenen Klasse</li><li>Methoden der Parameter</li><li>Methoden assoziierter Klassen</li><li>Methoden selbst erzeugter Objekte<br /></li></ul><br />Allerdings: Es ist zu berücksichtigen, dass ab und zu auch reine Datenhaltungsklassen Sinn ergeben. Auf diese muss man das Law of Demeter natürlich nicht anwenden. Es kann z.B. durchaus sinnvoll sein, die Konfigurationsdaten in mehrere Klassen hierarchisch zu verteilen, so dass sich am Ende folgender Zugriff auf einen Wert ergeben könnte:<br /><br /><pre>
int margin = config.Pages.Margins.Left;
</pre><br />Würde man hier das Law of Demeter anwenden, wäre nur der Zugriff auf config.Pages gestattet.
</div><br /><br /><h2 class="separator">Praktiken<a class="headeranchor" id="Praktiken_9" href="#Praktiken_9" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Continuous Integration<a class="headeranchor" id="Continuous_Integration_3" href="#Continuous_Integration_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Automatisierung und Zentralisierung der Softwareproduktion machen produktiver und reduzieren das Risiko von Fehlern bei der Auslieferung.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td>+</td><td>++</td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Oft wird die Integration der Softwarekomponenten zeitlich nach hinten geschoben und erfolgt aufwendig und fehleranfällig "per Hand". Eigentlich sollte die Software aber zu jedem Zeitpunkt vollständig lauffähig sein. Mit Continuous Integration bezeichnet man einen Prozess, der dafür sorgt dass der gesamte Code nach der Übermittlung von Änderungen übersetzt und getestet wird.<br /><br />Der Continuous Integration Prozess ist vor allem für Teams wichtig, denn er sorgt dafür, dass nach der Übermittlung von Änderungen der gesamte Code übersetzt und getestet wird, nicht nur der Teil an dem ein Entwickler gerade gearbeitet hat. Die automatisierten Tests sollten von jedem Entwickler ausgeführt werden bevor er Änderungen in die zentrale Versionskontrolle übermittelt. Daran ändert sich durch Continuous Integration nichts. Um sicherzustellen, dass die Tests tatsächlich ausgeführt werden und Fehler frühzeitig erkannt werden, laufen sie in jedem Fall auf dem Continuous Integration Server. Dies entbindet den Entwickler nicht davon die Tests vor dem Commit auszuführen, schließlich behindert fehlerhafter Code der in die Versionskontrolle eingecheckt wurde das gesamte Team, möglicherweise sogar weitere Teams. So sorgt der Continuous Integration Prozess dafür dass teamübergreifend sichergestellt wird dass Fehler so früh wie möglich erkannt werden.<br /><br />Für den Continuous Integration Prozess stehen zahlreiche <a class="pagelink" href="Tools.ashx" title="Tools">Softwaretools</a> zur Verfügung. Neben dem kontinuierlichen Build und Test, der sofort erfolgt, wenn Änderungen in die Versionskontrolle übertragen werden, können durch Continuous Integration auch länger laufende Prozesse, wie z.B. Datenbanktests, automatisiert werden. Diese werden dann z.B. nur nachts ausgeführt. Im grünen Grad wird lediglich der Build- und Testprozess berücksichtigt. Das kontinuierliche Setup und Deployment der Software folgt erst später im <a class="pagelink" href="Blauer-Grad.ashx" title="Blauer Grad">blauen Grad</a>.<br /><br />Martin Fowler hat einen sehr guten Artikel zu diesem Thema verfasst, nachzulesen unter <a class="externallink" href="http://www.martinfowler.com/articles/continuousIntegration.html" title="http://www.martinfowler.com/articles/continuousIntegration.html" target="_blank">http://www.martinfowler.com/articles/continuousIntegration.html</a><br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Statische Codeanalyse (Metriken)<a class="headeranchor" id="Statische_Codeanalyse_Metriken_4" href="#Statische_Codeanalyse_Metriken_4" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Vertrauen ist gut, Kontrolle ist besser - und je automatischer, desto leichter ist sie.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Wie definiert sich eigentlich die Qualität einer Codeeinheit, z.B. einer Klasse oder Komponente? Reicht es, dass sie funktional die Anforderungen des Kunden erfüllt? Reicht es, dass er schnell genug und skalierbar genug ist? Automatische Tests und schließlich Tests durch den Kunden geben darüber ja Auskunft. Ohne solche Anforderungskonformität hat Software natürlich keine relevante Qualität. Wenn sie dem Kunden nicht nützt, erübrigt sich jede weitere Frage.<br /><br />Auf der anderen Seite reicht es, entgegen immer noch weit verbreiteter Annahme, allerdings auch nicht, anforderungskonform zu sein. Hohe Qualität ergibt sich nicht allein aus Funktionalität und z.B. Performance. Denn neben den funktionalen und nicht funktionalen Anforderungen gibt es auch noch eine meist unausgesprochene verborgene Anforderung: Kunden wollen auch immer, dass Software nicht nur heute ihre Anforderungen erfüllt, sondern auch noch morgen und übermorgen. Kunden wollen Investitionsschutz durch Evolvierbarkeit.<br /><br />Für Kunden ist diese Anforderung meist implizit. Sie glauben, es sei selbstverständlich, dass ein immaterielles Produkt wie Software sich quasi unendlich und auf Knopfdruck an neue Anforderungen anpassen ließe. Auch Führungskräfte, die nicht aus der Softwareentwicklung stammen, glauben das oft. Und sogar Softwareentwickler selbst!<br /><br />Größer könnte das Missverständnis über Software jedoch kaum sein. Evolvierbarkeit ist weder selbstverständlich im Sinne eines von jedem Softwareentwickler ohnehin verfolgten Zieles, noch ergibt sie sich durch irgendetwas quasi von selbst. Evolvierbarkeit ist vielmehr harte Arbeit und muss ständig gegen andere Werte abgewogen werden.<br /><br />Wenn sonstige Anforderungskonformität sich nun durch (automatisierte) Tests feststellen lässt, wie steht es dann mit der Evolvierbarkeit? Lässt sich die Qualität von Code im Hinblick auf seine (Über)Lebensfähigkeit auch automatisch messen? Zum Teil. Nicht alle Aspekte, die Software evolvierbar machen, sind automatisch prüfbar. Ob zum Beispiel Software offen für Erweiterungen durch ein Add-In-Konzept gehalten wird, ist nicht automatisiert erkennbar.<br /><br />Dennoch gibt es <a class="externallink" href="http://en.wikipedia.org/wiki/Software_metric" title="Metriken" target="_blank">Metriken</a>, deren Wert für eine Software sich "ausrechnen" lässt. <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a> helfen dabei. Diese Tools sollten daher in jedem Softwareprojekt zum Einsatz kommen.
<ul><li>Für Legacy Code können die Tools den Status Quo erheben und somit eine Grundlinie definieren, mit der die weitere Entwicklung des Codes (zum Besseren) verglichen werden kann.</li><li>Für neuen Code, der mit Evolvierbarkeit im Blick geplant wurde, zeigt solch statische Codeanalyse, ob er das Ideal der Planung erfüllt.<br /></li></ul><br />CCD sind nicht damit zufrieden, Code nur automatisiert zu testen. Sie haben auch immer ein Auge auf seine Evolvierbarkeit, denn sie wissen, dass Kunden daran genauso interessiert sind - egal, ob sie es explizit gesagt haben oder nicht.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Inversion of Control Container<a class="headeranchor" id="Inversion_of_Control_Container_5" href="#Inversion_of_Control_Container_5" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Nur, was nicht fest verdrahtet ist, kann leichter umkonfiguriert werden.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td></td><td>++</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Bereits im <a class="pagelink" href="Gelber-Grad.ashx" title="Gelber Grad">gelben Grad</a> hat der CCD das Dependency Inversion Principle kennengelernt. Dabei wurden die Abhängigkeiten noch "von Hand" aufgelöst. Der nächste logische Schritt besteht nun darin, das Auflösen der Abhängigkeiten zu automatisieren. Dazu stehen zwei Verfahren zur Verfügung:
<ul><li>Locator</li><li>Container<br /></li></ul><br />Beide verwenden einen sogenannten <i>Inversion of Control Container</i> (IoC Container). Vor der Verwendung des Containers müssen die verwendeten Klassen im Container hinterlegt werden. Anschließend kann der Container Instanzen der hinterlegten Klassen liefern. Beim <i>Locator</i> geschieht dies explizit. Dies hat den Vorteil, dass die Abhängigkeiten nicht alle im Konstruktor der Klasse aufgeführt werden müssen. Bei Querschnittsaufgaben wie beispielsweise <i>Logging</i> ist dies ein übliches Vorgehen. In der Regel werden die Abhängigkeiten jedoch als Parameter des Konstruktors aufgeführt. Dies hat den Vorteil dass alle Abhängigkeiten sichtbar sind. Der Container ist damit in der Lage die Abhängigkeiten implizit aufzulösen in dem er rekursiv alle benötigten Objekte über den Container instanziert.<br /><br />IoC Container werden wichtig, sobald die Anzahl der Klassen wächst. Wenn man <i>Separation of Concerns</i> beherzigt, entstehen viele kleine Klassen mit überschaubaren Aufgaben. Das Zusammensetzen von Instanzen dieser Klassen wird entsprechend aufwendiger. Genau hier setzt der IoC Container an, er hilft beim Instanziieren und Verbinden der vielen kleinen Objekte.<br /><br />Ein weiterer Vorteil von IoC Containern ist die Tatsache, dass der <i>Lebenszyklus</i> eines Objektes per Konfiguration bestimmt werden kann. Soll es zur Laufzeit nur eine einzige Instanz eines Objektes geben (<i>Singleton</i>) kann der Container angewiesen werden, immer ein und dieselbe Instanz zu liefern. Auch andere Lebenszyklen wie z.B. <i>eine Instanz pro Session</i> werden unterstützt.<br /><br />Um bei Verwendung eines Locators nicht in Abhängigkeit zu einem bestimmten IoC Container zu geraten, kann der <i>Microsoft Common Service Locator</i> (siehe Tools) verwendet werden. Dieser bietet eine vereinheitlichte Schnittstelle zu den gängigen IoC Containern.<br /><br />Zum Verständnis der Mechanik die hinter einem IoC Container steckt, ist es nützlich die Funktionalität einmal selber zu implementieren. Dabei soll kein vollständiger Container implementiert werden sondern lediglich die Grundfunktionen.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Erfahrung weitergeben<a class="headeranchor" id="Erfahrung_weitergeben_6" href="#Erfahrung_weitergeben_6" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Wer sein Wissen weitergibt, hilft nicht nur anderen, sondern auch sich selbst.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td></td><td></td><td></td><td>++</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Zu professioneller Arbeit gehört selbstverständlich ein ständig akuelles Wissen. Das bedeutet natürlich nicht, dass irgendjemand alles zum Thema Softwareentwicklung und sei es auch nur auf der .NET-Plattform wissen kann und soll. Aktuelles Wissen bezieht sich auf die eigenen Spezialgebiete - welche das auch immer sein mögen. Bestandteil anderer Grade ist deshalb die Praktik der regelmäßigen Informationsaufnahme über verschiedene Medien.<br /><br />Aus mehreren Gründen sollte solche Informationssammlung jedoch nur eine von zwei Seiten der Medaille "Lernen" sein. Die andere ist die Informationsweitergabe, die Wissensvermittlung. Zur wahren Professionalität gehört unserer Ansicht nach nicht nur "Forschung", sonder auch "Lehre". Denn erst mit der "Lehre" findet wahre Reflektion und Durchdringung eines Gegenstandes statt.<br /><br />Etwas Gehörtes/Gelesenes anwenden, ist eine Sache. Natürlich bemerkt man dabei auch Verständnislücken. Die "Erforschung" eines Gegenstandes ist dabei jedoch durch den Einsatzzweck natürlich begrenzt. Wer nur soweit forscht, wie er eine Technologie/Konzept gerade braucht, der taucht nicht unbedingt tief ein.<br /><br />Ganz anders ist das hingegen, wenn das Lernen mit dem Vorzeichen des Weitersagens stattfindet. Wer nicht nur für sich, sondern auch immer für andere lernt, der lernt tiefer. Das wird klar, wenn man versucht, (angeblich) Gelerntes anderen zu vermitteln. Wenn man das nicht beim Lernen im Blick hat, tauchen schnell Fragen auf, die man sich selbst nie gestellt hat. Andere haben eben immer ganz andere Blickwinkel.<br /><br />Deshalb meinen wir, dass wirklich solide nur lernt, wer sich auch immer wieder dem Lehren, dem Weitersagen, der Wissensvermittlung aussetzt. Nur wer Gelerntes nicht nur anwendet, sondern es mit eigenen Worten für ein Publikum formuliert, bemerkt in dem Prozess, wie tief sein Wissen wirklich ist. Denn wenn sich die Fragezeichen bei den "Schülern" häufen, dann stimmt irgendetwas noch nicht.<br /><br />Ein reales Publikum ist dafür natürlich am besten. Jeder CCD sollte also möglichst regelmäßig Gelegenheiten suchen, um sein Wissen mündlich weiterzugeben (z.B. bei Veranstaltungen im Kollegenkreis oder User Group Treffen). Unmittelbares Feedback ist ihm dabei gewiss. Alternativ bzw. in Ergänzung taugen aber auch schriftliche Kompetenzäußerungen. Ein Blog ist in 5 Minuten aufgesetzt und Fachzeitschriften suchen ständig nach neuen Autoren. Feedback kommt hier zwar nicht so direkt zurück, dennoch ist die textuelle Ausformulierung von Kenntnissen eine sehr gute Übung.<br /><br />Clean Code Developer ab dem grünen Grad lernen daher nicht nur "passiv" durch Informationsaufnahme, sondern "aktiv" durch Weitergabe ihres Wissens mittels Präsentationen oder Texten. Das mag ungewohnt sein - ungewohnt ist aber auch womöglich Continuous Integration. In jedem Fall ist aktive Wissensvermittlung eine gute Übung zur Vertiefung der eigenen Kompetenzen frei nach dem Motto: "Tue Gutes und sprich darüber" ;-)<br /><br />Dass das "Lehren" auch noch einen Nutzen für die Zuhörer/Leser hat, ist selbstverständlich. Vorteile für andere sind aber nicht so motivierend wie eigene Vorteile. Deshalb betonen wir hier vor allem den Nutzen der Wissensvermittlung für den Clean Code Developer.<br /><br /><h3 class="separator">Messen von Fehlern<a class="headeranchor" id="Messen_von_Fehlern_7" href="#Messen_von_Fehlern_7" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Nur wer weiß, wie viele Fehler auftreten, kann sein Vorgehen so verändern, dass die Fehlerrate sinkt.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td>+</td><td>+</td><td>++</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Während der Softwareentwicklung passieren Fehler. Die passieren in allen Phasen: falsch verstandene oder unklar formulierte Anforderungen führen zu Fehlern genauso wie fehlerhafte Implementierungen. Am Ende ist alles ein Fehler, was dazu führt, dass der Kunde eine Software erhält, die nicht seinen Anforderungen entspricht. Iteratives Vorgehen und Reflexion sind zwei Bausteine, die dazu dienen, den Prozess zu verbessern. Um jedoch zu erkennen, ob tatsächlich eine Verbesserung eintritt, muss eine Messgröße vorliegen, an der man eine Entwicklung zum Besseren überhaupt ablesen kann.<br /><br />Das Messen der Fehler kann durch Zählen oder durch Zeitnahme erfolgen. Dabei steht nicht die Präzision im Vordergrund, solange die Messmethode vergleichbare Daten liefert. Die Entwicklungstendenz über mehrere Iterationen hinweg soll ersichtlich werden. Ferner geht es nicht darum, die Verantwortlichkeit für einen Fehler zu klären. Am Ende ist es egal, wer den Fehler verursacht hat, so lange das Team daraus lernt und seinen Prozess verbessert.<br /><br />Welche Fehler sind zu messen? Es sind nicht die Fehler, die während der Entwicklung auftreten. Die sind nicht zu vermeiden und führen hoffentlich dahin, dass am Ende einer Iteration ein fehlerfreies Produkt ausgeliefert wird. Vielmehr geht es um die Fehler, die nach einer Iteration zurückgemeldet werden vom Kunden bzw. seinem Stellvertreter (z.B. Productowner oder Support). Das sind Fehler, die die Umsetzung neuer Anforderungen behindern. Zu messende Fehler sind also die, die auftreten, wenn man glaubt, dass es sie nicht geben dürfte ;-) Wann im Prozess ein Team diesen Punkt erreicht und flucht, weil da wieder so ein Fehler der sonstigen Arbeit dazwischenfunkt, ist teamindividuell zu bestimmen.<br /><br />
Weiter geht es beim <a class="pagelink" href="Blauer-Grad.ashx" title="Blauer Grad">blauen Grad</a>.
]]></description><pubDate>Sun, 20 Feb 2011 17:46:01 GMT</pubDate><guid isPermaLink="false">68D386A28626E96C49A9E1B5613C4344</guid></item><item><title><![CDATA[LoD]]></title><link>http://clean-code-developer.de/LoD.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[
]]></description><pubDate>Sun, 20 Feb 2011 17:45:56 GMT</pubDate><guid isPermaLink="false">D636B29671D07ECE69CC5CA07E7F03EF</guid></item><item><title><![CDATA[Law of Demeter]]></title><link>http://clean-code-developer.de/Law-of-Demeter.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Abhängigkeiten von Objekten über mehrere Glieder einer Dienstleistungskette hinweg führen zu unschön enger Kopplung.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Beim <a class="externallink" href="http://www.lieser-online.de/blog/?p=124" title="Law of Demeter" target="_blank">Law of Demeter</a> geht es darum, das Zusammenspiel von Objekten auf ein gesundes Maß zu beschränken. Man kann es vereinfacht umschreiben mit "Don't talk to strangers". Nach dem Law of Demeter soll eine Methode nur folgende andere Methoden verwenden:
<ul><li>Methoden der eigenen Klasse</li><li>Methoden der Parameter</li><li>Methoden assoziierter Klassen</li><li>Methoden selbst erzeugter Objekte<br /></li></ul><br />Allerdings: Es ist zu berücksichtigen, dass ab und zu auch reine Datenhaltungsklassen Sinn ergeben. Auf diese muss man das Law of Demeter natürlich nicht anwenden. Es kann z.B. durchaus sinnvoll sein, die Konfigurationsdaten in mehrere Klassen hierarchisch zu verteilen, so dass sich am Ende folgender Zugriff auf einen Wert ergeben könnte:<br /><br /><pre>
int margin = config.Pages.Margins.Left;
</pre><br />Würde man hier das Law of Demeter anwenden, wäre nur der Zugriff auf config.Pages gestattet.
]]></description><pubDate>Sun, 20 Feb 2011 17:45:17 GMT</pubDate><guid isPermaLink="false">B7E107B0427D5974E971DA5E6C5B699F</guid></item><item><title><![CDATA[Tell, don´t ask]]></title><link>http://clean-code-developer.de/Tell-don-t-ask.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Hohe Kohäsion und lose Kopplung sind Tugenden. Öffentliche Zustandsdetails einer Klasse widersprechen dem.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td></td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Etwas provokant formuliert, sollten Klassen keine Property Getter haben. Diese verführen den Verwender einer Klasse dazu, anhand von Werten, die ein Objekt liefert, Entscheidungen zu treffen. Statt also dem Objekt mitzuteilen, was es tun soll, wird es befragt, um dann von außen Betrachtungen über den internen Zustand des Objektes anzustellen.<br /><br />Eines der Kernprinzipien der Objektorientierten Programmierung lautet <i>Information Hiding</i> (siehe dazu auch im <a class="pagelink" href="Gelber-Grad.ashx" title="Gelber Grad">gelben Grad</a>). Keine Klasse soll Details nach außen tragen, aus denen hervorgeht, wie sie intern implementiert ist. Benötigt eine Klasse für ihre Arbeit einen internen Zustand, wird dieser typischerweise in einem internen Feld abgelegt. Wenn nun dieser Wert auch nach außen sichtbar ist, werden Verwender verleitet, diesen eigentlich internen Zustand des Objektes für eigene Entscheidungen heranzuziehen. Dadurch wird die Klasse schnell zur reinen Datenhaltung degradiert. Eine Implementierung, bei der einem Objekt mitgeteilt wird, was es tun soll, ist in jedem Fall vorzuziehen. Dadurch muss es den Verwender nicht mehr interessieren, wie die Klasse die Aufgabe intern bewerkstelligt.<br /><br />Als Ergebnis des <a class="externallink" href="http://www.pragprog.com/articles/tell-dont-ask" title="Tell don't ask" target="_blank">Tell don't ask</a> Prinzips entstehen Objekte mit Verhalten statt "dummer" Datenhaltungsobjekte. Das Zusammenspiel der Objekte ist lose gekoppelt, da die Objekte keine Annahmen über die kollaborierenden Objekte machen müssen. Aber nicht nur das! Wenn Objekte ihren Zustand nicht veröffentlichen, behalten sie die Entscheidungshoheit. Die Kohäsion des entscheidenden Codes wächst damit, weil er an einem Ort zusammengelegt wird.
]]></description><pubDate>Sun, 20 Feb 2011 17:43:29 GMT</pubDate><guid isPermaLink="false">9AEE0247BF3BB0B70B1F695DFF219459</guid></item><item><title><![CDATA[OCP]]></title><link>http://clean-code-developer.de/OCP.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[
]]></description><pubDate>Sun, 20 Feb 2011 17:42:28 GMT</pubDate><guid isPermaLink="false">0D844930E0EFC74B0B039A92F71CDFCD</guid></item><item><title><![CDATA[Open Closed Principle]]></title><link>http://clean-code-developer.de/Open-Closed-Principle.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Weil das Risiko, durch neue Features ein bisher fehlerfreies System zu instabilisieren, so gering wie möglich gehalten werden sollte.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td>+</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Das <i>Open Closed Principle</i> (<a class="externallink" href="http://www.objectmentor.com/resources/articles/ocp.pdf" title="OCP" target="_blank">OCP</a>) besagt, dass eine Klasse offen für Erweiterungen sein muss, jedoch geschlossen gegenüber Modifikationen. Es ist ein weiteres der <a class="pagelink" href="SOLID.ashx" title="SOLID">SOLID</a> Prinzipien. Folgendes Codebeispiel soll verdeutlichen, wo das Problem liegt, wenn das Prinzip nicht befolgt wird:<br /><br /><pre>
public double Preis() &#123;
    const decimal StammkundenRabatt = 0.95m;
    switch(kundenart) &#123;
        case Kundenart.Einmalkunde&#58;
            return menge &#42; einzelpreis;
        case Kundenart.Stammkunde&#58;
            return menge &#42; einzelpreis &#42; StammkundenRabatt;
        default&#58;
            throw new ArgumentOutOfRangeException();
    &#125;
&#125;
</pre>
                    
Das problematische an dieser Form der Implementierung ist, dass die Klasse modifiziert werden muss, wenn eine weitere Art der Preisberechnung erforderlich wird. Die Gefahr dabei ist, dass bei dieser Modifikation Fehler gemacht werden und die bisher schon vorhandenen Funktionen nicht mehr ordnungsgemäß funktionieren. Auch wenn automatisierte Unit Tests und Integrationstests vorhanden sind besteht das Risiko, neue Bugs zu hinterlassen, weil man keine hundertprozentige Testabdeckung erreichen kann. Gesucht ist also generell ein Verfahren, welches die Klasse erweiterbar macht, ohne dass dazu die Klasse selbst modifiziert werden muss. Dies kann z.B. mit Hilfe des <i>Strategy Patterns</i> erreicht werden:<br /><br /><pre>
public interface IPreisRechner &#123;
    double Preis(int menge, double einzelpreis);
&#125;

private IPreisRechner preisRechner;

public double Preis() &#123;
    return preisRechner.Preis(menge, einzelpreis);
&#125;

public class Einmalkunde &#58; IPreisRechner &#123;
    public double Preis(int menge, double einzelpreis) &#123;
        return menge &#42; einzelpreis;
    &#125;
&#125;

public class Stammkunde &#58; IPreisRechner &#123;
    const decimal StammkundenRabatt = 0.95m;
    
    public double Preis(int menge, double einzelpreis) &#123;
        return menge &#42; einzelpreis &#42; StammkundenRabatt;
    &#125;
&#125;
</pre>      
              
Die konkrete Berechnung des Preises wird über ein Interface in andere Klassen ausgelagert. Dadurch ist es möglich, jederzeit neue Implementierungen des Interfaces zu ergänzen. Damit ist die Klasse offen für Erweiterungen, gleichzeitig aber geschlossen gegenüber Modifikationen. Bestehender Code kann z.B. mit dem Refactoring <a class="externallink" href="http://www.industriallogic.com/xp/refactoring/conditionalWithStrategy.html" title="Replace Conditional with Strategy" target="_blank">Replace Conditional with Strategy</a> so umgestaltet werden, dass das Open Closed Principle eingehalten wird.<br /><br /><h4 class="separator">Quellen<a class="headeranchor" id="Quellen_0" href="#Quellen_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<table><thead><tr><th>Quelle</th><th>Autor</th><th>Kurzbeschreibung</th></tr></thead><tbody><tr><td><a class="externallink" href="http://www.objectmentor.com/resources/articles/ocp.pdf" title="http://www.objectmentor.com/resources/articles/ocp.pdf" target="_blank">http://www.objectmentor.com/resources/articles/ocp.pdf</a></td><td>Robert C. Martin</td><td>Artikel zum Open Closed Principle von 1996 veröffentlicht für The C++ Report</td></tr></tbody></table>
]]></description><pubDate>Sun, 20 Feb 2011 17:42:08 GMT</pubDate><guid isPermaLink="false">1F25F5D047CC0269AADD089AD87206FD</guid></item><item><title><![CDATA[Gelber Grad]]></title><link>http://clean-code-developer.de/Gelber-Grad.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<h1 class="separator">Der gelbe Grad<a class="headeranchor" id="Der_gelbe_Grad_12" href="#Der_gelbe_Grad_12" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h1>
<table id="TocContainerTable"><tr><td><div id="TocContainer"><p class="small"><b>Inhaltsverzeichnis</b><span id="ExpandTocSpan"> [<a href="#" onclick="javascript:if(document.getElementById('Toc').style['display']=='none') document.getElementById('Toc').style['display']=''; else document.getElementById('Toc').style['display']='none'; return false;">Anzeigen/Verbergen</a>]</span></p><div id="Toc"><p><br /><b><a href="#Der_gelbe_Grad_12">Der gelbe Grad</a></b><br />&nbsp;&nbsp;&nbsp;<a href="#Prinzipien_10">Prinzipien</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Interface_Segregation_Principle_ISP_0">Interface Segregation Principle (ISP)</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Dependency_Inversion_Principle_1">Dependency Inversion Principle</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Liskov_Substitution_Principle_2">Liskov Substitution Principle</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Principle_of_Least_Astonishment_3">Principle of Least Astonishment</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Information_Hiding_Principle_4">Information Hiding Principle</a><br />&nbsp;&nbsp;&nbsp;<a href="#Praktiken_11">Praktiken</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Automatisierte_Unit_Tests_5">Automatisierte Unit Tests</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Mockups_Testattrappen_6">Mockups (Testattrappen)</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Code_Coverage_Analyse_7">Code Coverage Analyse</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Teilnahme_an_Fachveranstaltungen_8">Teilnahme an Fachveranstaltungen</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Komplexe_Refaktorisierungen_9">Komplexe Refaktorisierungen</a><br /></p></div></div></td></tr></table><br /><h2 class="separator">Prinzipien<a class="headeranchor" id="Prinzipien_10" href="#Prinzipien_10" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Interface Segregation Principle (ISP)<a class="headeranchor" id="Interface_Segregation_Principle_ISP_0" href="#Interface_Segregation_Principle_ISP_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Leistungsbeschreibungen, die unabhängig von einer konkreten Erfüllung sind, machen unabhängig.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Das Interface Segregation Principle (<a class="externallink" href="http://www.objectmentor.com/resources/articles/isp.pdf" title="ISP" target="_blank">ISP</a>) ist ein weiteres <a class="pagelink" href="SOLID.ashx" title="SOLID">SOLID</a> Prinzip. <i>Segregation</i> bedeutet <i>Abtrennung</i>. Das Prinzip besagt, dass ein Client nicht von Details eines Service abhängig sein soll, die er gar nicht benötigt. Je weniger in dessen Interface enthalten ist, desto geringer ist die Kopplung zwischen den beiden Komponenten.<br /><br />Stellen wir uns vor, wir müssten einen Stecker planen, mit dem ein Monitor an einen Computer angeschlossen werden soll. Wir entscheiden uns, einfach alle Signale die in einem Computer so anfallen, per Stecker zur Verfügung zu stellen. Der hat dann zwar einige Hundert Pins, aber dafür ist er maximal flexibel. Dummerweise ist damit die Kopplung ebenfalls maximal.<br /><br />Beim Beispiel des Steckers ist es offensichtlich, dass eine Monitorverbindung nur jene Signale enthalten soll, die zur Darstellung eines Bildes auf dem Monitor erforderlich sind. Genauso verhält es sich mit Software Interfaces. Auch sie sollten so klein wie möglich sein, um unnötige Kopplung zu vermeiden. Und genau wie beim Monitorstecker sollte das Interface eine hohe Kohäsion haben: Es sollte nur Dinge enthalten, die wirklich eng zusammen gehören.<br /><br />Um das Interface Segregation Principle anzuwenden, stehen die beiden Refaktorisierungen <a class="externallink" href="http://refactoring.com/catalog/extractInterface.html" title="Extract Interface" target="_blank">Extract Interface</a> und <a class="externallink" href="http://refactoring.com/catalog/extractSuperclass.html" title="Extract Superclass" target="_blank">Extract Superclass</a> zur Verfügung.<br /><br /><h4 class="separator">Quellen<a class="headeranchor" id="Quellen_0" href="#Quellen_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<table><thead><tr><th>Quelle</th><th>Autor</th><th>Kurzbeschreibung</th></tr></thead><tbody><tr><td><a class="externallink" href="http://www.objectmentor.com/resources/articles/isp.pdf" title="http://www.objectmentor.com/resources/articles/isp.pdf" target="_blank">http://www.objectmentor.com/resources/articles/isp.pdf</a></td><td>Robert C. Martin</td><td>Artikel zum Interface Segregation Principle von 1996, veröffentlicht im Engineering Notebook für <i>The C++ Report</i></td></tr></tbody></table>
</div><br /><br /><h3 class="separator">Dependency Inversion Principle<a class="headeranchor" id="Dependency_Inversion_Principle_1" href="#Dependency_Inversion_Principle_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Punktgenaues Testen setzt Isolation von Klassen voraus. Isolation entsteht, wenn Klassen keine Abhängigkeiten von Implementationen mehr enthalten – weder zur Laufzeit, noch zur Übersetzungszeit. Konkrete Abhängigkeiten sollten deshalb so spät wie möglich entschieden werden. Am besten zur Laufzeit.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>++</td><td>+</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Auch das Dependency Inversion Principle (<a class="externallink" href="http://www.objectmentor.com/resources/articles/dip.pdf" title="DIP" target="_blank">DIP</a>) ist ein <a class="pagelink" href="SOLID.ashx" title="SOLID">SOLID</a> Prinzip. Es besagt folgendes:
<ul><li>High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Interfaces.</li><li>Interfaces sollen nicht von Details abhängig sein, sondern Details von Interfaces.<br /></li></ul><br />Verwendet eine High-Level Klasse eine Low-Level Klasse unmittelbar, so ergibt sich eine starke Kopplung zwischen beiden. Spätestens beim Versuch, die High-Level Klasse isoliert zu testen, wird man auf Schwierigkeiten stoßen. Aus diesem Grund sollte die High-Level Klasse von einem Interface abhängig sein, das wiederum von der Low-Level Klasse implementiert wird. So kann die Low-Level Klasse im Unit Test durch ein <i>Mockup</i> ersetzt werden.<br /><br />Um zur Laufzeit die invertierte, abstrakte Abhängigkeit mit einem konkreten Objekt aufzulösen, bieten sich im Prinzip drei Möglichkeiten:
<ul><li>mittels Konstruktorparameter "per Hand"</li><li>Einsatz eines Inversion of Control Containers (IoC Container) wie etwa Castle Windsor</li><li>Dependency Lookup<br /></li></ul><br />Im <a class="pagelink" href="Gelber-Grad.ashx" title="Gelber Grad">gelben Grad</a> injizieren wir die Abhängigkeiten zunächst nur über die Parameter der Konstruktoren. Dies ist anfangs die einfachste Lösung und funktioniert mit einer handvoll Klassen ganz gut. Später im <a class="pagelink" href="Gr%c3%bcner-Grad.ashx" title="Grüner Grad">grünen Grad</a> nutzen wir einen IoC Container und Dependency Lookup.<br /><br /><h4 class="separator">Quellen<a class="headeranchor" id="Quellen_0" href="#Quellen_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<table><thead><tr><th>Quelle</th><th>Autor</th><th>Kurzbeschreibung</th></tr></thead><tbody><tr><td><a class="externallink" href="http://www.objectmentor.com/resources/articles/dip.pdf" title="http://www.objectmentor.com/resources/articles/dip.pdf" target="_blank">http://www.objectmentor.com/resources/articles/dip.pdf</a></td><td>Robert C. Martin</td><td>Artikel zum Dependency Inversion Principle von 1996, veröffentlicht im Engineering Notebook für <i>The C++ Report</i></td></tr></tbody></table>
</div><br /><br /><h3 class="separator">Liskov Substitution Principle<a class="headeranchor" id="Liskov_Substitution_Principle_2" href="#Liskov_Substitution_Principle_2" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Wer mit Erben zu tun hat, möchte keine Überraschungen erleben, wenn er mit Erblassern vertraut ist.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Auch das Liskov Substitution Principle (<a class="externallink" href="http://www.objectmentor.com/resources/articles/lsp.pdf" title="LSP" target="_blank">LSP</a>) ist ein <a class="pagelink" href="SOLID.ashx" title="SOLID">SOLID</a> Prinzip. Es besagt, dass Subtypen sich so verhalten müssen wie ihr Basistyp. Dies klingt zunächst banal. Am Beispiel von Exceptions wird deutlich, welche Probleme entstehen, wenn das Prinzip verletzt wird: Löst der Basistyp bei der Ausführung einer Methode keine Exception aus, müssen alle Subtypen sich an diese Regel halten. Löst die Methode eines Subtyps dennoch eine Exception aus, würde dies bei Verwendern, die ein Objekt vom Basistyp erwarten, Probleme verursachen, weil sie nicht darauf vorbereitet sind. Wenn der Basistyp an der Stelle keine Exception auslöst, ist der Verwender nicht darauf eingestellt, Exceptions behandeln zu müssen.<br /><br />Allgemeiner kann man das Prinzip auch so ausdrücken, dass ein Subtyp die Funktionalität eines Basistyps lediglich erweitern, aber nicht einschänken darf. Wenn eine Methode im Basistyp auf einem bestimmten Wertebereich definiert ist, darf der Subtyp diesen Wertebereich übernehmen oder auch erweitern, er darf ihn jedoch keinesfall einschränken.<br /><br />Aus dem Liskov Substitution Principle ergibt sich ferner die Empfehlung, über Vererbung sehr genau nachzudenken. In den allermeisten Fällen ist die Komposition der Vererbung vorzuziehen (<i>Favor Composition over Inheritance</i>). Bei der Vererbung sollte man in jedem Fall über das Verhalten nachdenken, nicht nur über die Struktur. Statt Vererbung als <i>is-a</i> Relation zu betrachten und dabei nur die (Daten-)Struktur zu bedenken, sollte man besser von einer <i>behaves-as</i> Relation ausgehen und das Verhalten der Klasse berücksichtigen.<br /><br /><h4 class="separator">Quellen<a class="headeranchor" id="Quellen_0" href="#Quellen_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<table><thead><tr><th>Quelle</th><th>Autor</th><th>Kurzbeschreibung</th></tr></thead><tbody><tr><td><a class="externallink" href="http://www.objectmentor.com/resources/articles/lsp.pdf" title="http://www.objectmentor.com/resources/articles/lsp.pdf" target="_blank">http://www.objectmentor.com/resources/articles/lsp.pdf</a></td><td>Robert C. Martin</td><td>Artikel zum Liskov Substitution Principle von 1996, veröffentlicht im Engineering Notebook für <i>The C++ Report</i></td></tr></tbody></table>
</div><br /><br /><h3 class="separator">Principle of Least Astonishment<a class="headeranchor" id="Principle_of_Least_Astonishment_3" href="#Principle_of_Least_Astonishment_3" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Wenn sich eine Komponente überraschenderweise anders verhält als erwartet, wird ihre Anwendung unnötig kompliziert und fehleranfällig.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Softwareentwicklung ist in hohem Maße ein kreativer Prozess. In diesem Prozess ist es wichtig, in den Fluss einzutauchen (engl. Flow). Wenn man diesen Zustand erreicht hat, sprudelt der Code nur so heraus. Jegliche Störung des Flow führt zu Unterbrechungen und letztlich dazu, dass in der zur Verfügung stehenden Zeit nur wenig Code produziert wird bzw. die Qualität des Code nicht optimal ist. Denn nach jeder Unterbrechung muss der Entwickler erst wieder Fahrt aufnehmen und erneut in den Fluss zu kommen. Überraschungen stellen Störungen dar. Sie führen zu Unterbrechungen und Fehlern. Dazu ein Beispiel: Ist die Tastenbelegung in der Entwicklungsumgebung so gewählt, dass eine übliche Tastenkombination wie z.B. Ctrl-C eine völlig andere Bedeutung hat, behindert dies den Entwickler. Ein Entwickler wird sich jedesmal ärgern, wenn er die "falsche" Tastenkombination verwendet. Dies behindert kreatives Arbeiten.<br /><br />Software sollte überraschungsarm implementiert sein. Wenn eine Abfragemethode namens <i>GetValue()</i> nicht nur einen Wert liefert, sondern gleichzeitig den Zustand des Systems ändert, wird der Entwickler diese Methode im besten Fall meiden, da er mit bösen Überraschungen rechnet. Im ungünstigen Fall fällt ihm dieses merkwürdige Verhalten nicht rechtzeitig auf. (Abfragemethoden die den Zustand ändern, verstoßen gegen das <i>Command Query Separation</i> Prinzip). Die testgetriebene Entwicklung fördert überraschungsarme Schnittstellen, da die Schnittstelle aus der Sichtweise ihrer Verwendung entworfen und implementiert wird.
</div><br /><br /><h3 class="separator">Information Hiding Principle<a class="headeranchor" id="Information_Hiding_Principle_4" href="#Information_Hiding_Principle_4" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="transcludedpage"><div class="box">Warum?<br />
Durch das Verbergen von Details in einer Schnittstelle werden die Abhängigkeiten reduziert.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Beim Design einer Schnittstelle sollte man sich fragen, welche Details außen unbedingt sichtbar sein müssen. Mit Schnittstelle sind hier nicht nur Interfaces im objektorientierten Sinne gemeint, sondern auch implizite Schnittstellen. Jede Klasse hat zwangsläufig eine implizite Schnittstelle – sie enthält alle nach außen sichtbaren Details. Je mehr Details von außen sichtbar sind, desto höher ist die Kopplung zwischen der Klasse und ihren Verwendern. Benutzen die Verwender einer Klasse erstmal ein Detail, wird es schwerer, dieses Detail zu verändern. Dies steht der Evolvierbarkeit der Software entgegen.
</div><br /><br /><h2 class="separator">Praktiken<a class="headeranchor" id="Praktiken_11" href="#Praktiken_11" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h2>
<h3 class="separator">Automatisierte Unit Tests<a class="headeranchor" id="Automatisierte_Unit_Tests_5" href="#Automatisierte_Unit_Tests_5" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Nur automatisierte Tests werden auch wirklich konsequent ausgeführt. Je punktgenauer sie Code testen, desto besser.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>++</td><td>++</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Im <a class="pagelink" href="Oranger-Grad.ashx" title="Oranger Grad">orangen Grad</a> haben wir Integrationstests eingeführt, nun geht es um Unit Tests. Im Gegensatz zu Integrationstests wird bei Unit Tests eine einzelne Funktionseinheit (vor allem Klassen, aber auch Methoden oder Komponenten) isoliert getestet. Dazu ist es erforderlich, diese Funktionseinheit von ihren Abhängigkeiten befreien zu können. Sollen Unit Tests im Nachhinein für bestehenden Code ergänzt werden, sind häufig Refaktorisierungen erforderlich. Wir haben durch die Integrationstests die Sicherheit, dass wir dabei keine Fehler einbauen.<br /><br />Automatisierte Tests bieten zweifachen Nutzen:
<ul><li>Sie sparen Zeit</li><li>Sie nehmen Angst<br /></li></ul><br />Je stärker eine Codebasis in Veränderung begriffen ist, desto eher ist die Zeitersparnis zu spüren. Denn wo Code sich verändert, muss immer wieder Neues und auch Altes (Regressionstests) getestet werden. Da spart Automatisation einfach Zeit. Und je komplexer der Code, desto größer ist die Angstreduktion. Denn wenn komplexer Code verändert werden soll – um Funktionalität hinzuzufügen, ihn zu optimieren oder schlicht zu korrigieren –, da besteht hohe Gefahr, ungewollt Fehler einzuführen. Kleinschrittige automatisierte Tests decken diese jedoch auf, sodass kein Grund zur Angst besteht, zu "verschlimmbessern". <br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Mockups (Testattrappen)<a class="headeranchor" id="Mockups_Testattrappen_6" href="#Mockups_Testattrappen_6" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Ohne Attrappen keine einfach kontrollierbaren Tests.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td></td><td>++</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />In der Regel verwenden Komponenten andere Komponenten. Will man eine Komponente isoliert testen, müssen diese Abhängigkeiten abgetrennt werden. Dabei interessiert uns nun ausschließlich die Funktionalität der zu testenden Komponente (<i>System Under Test (SUT)</i>). Und es interessiert uns, wie die Komponente mit den anderen interagiert.<br /><br />Beim Isolieren verwenden wir sogenannte Mockups. Diese werden anstelle der echten Komponenten verwendet. So interagiert das System Under Test während der Tests mit gut kontrollierbaren Attrappen statt mit realen Komponenten.<br /><br />Die Literatur kennt noch andere Bezeichnungen für Attrappen wie <i>Stub</i>, <i>Dummy</i> oder <i>Fake</i>, die teilweise synonym zu Mockup benutzt werden, aber durchaus für <a class="externallink" href="http://martinfowler.com/articles/mocksArentStubs.html" title="unterschiedliche Funktionsweisen" target="_blank">unterschiedliche Funktionsweisen</a> stehen. Bevor man ein Mock Framework wie z.B. <a class="externallink" href="http://ayende.com/projects/rhino-mocks.aspx" title="Rhino Mocks" target="_blank">Rhino Mocks</a> verwendet, sollte man ein Mockup zunächst "per Hand" implementieren. Dies hilft, den Mechanismus zu verstehen.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Code Coverage Analyse<a class="headeranchor" id="Code_Coverage_Analyse_7" href="#Code_Coverage_Analyse_7" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Traue nur Tests, von denen du weißt, dass sie auch wirklich das Testareal abdecken.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td></td><td>+</td><td>+</td><td>+ </td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Unit Tests sollten nach Möglichkeit alle Pfade durch unseren Code abdecken. Nur so gewinnen wir das Vertrauen, dass der Code korrekt arbeitet. Um in Erfahrung zu bringen, welche Codebereiche bislang nicht durch Tests abgedeckt sind, bedienen wir uns der <i>Code Coverage Analyse</i>. Diese dient dazu, Bereiche im Code aufzudecken, die noch nicht während der automatisierten Tests ausgeführt werden.<br /><br />Unit Tests sollten eigentlich 100% des zu testenden Codes abdecken. Zwar bedeutet das nicht automatisch, dass genügend Tests existieren, doch weniger als 100% Code Coverage zeigen an, dass es noch Taschen von Code gibt, über die überhaupt noch keine Korrektheitsaussage gemacht werden kann. 100% Codeabdeckung sind deshalb immer anzustreben.<br /><br />In der Praxis zeigt es sich jedoch, dass 100% Codeabdeckung nicht immer mit unmittelbar vertretbarem Aufwand erreicht werden können. Wie auch sonst im Leben kann die Mühe für die letzten 2,3,4 Prozent überproportional wachsen. Deshalb kann es nach genauer Analyse der Abdeckungslage akzeptabel sein, mit weniger als 100% zufrieden zu sein.<br /><br />Unterhalb von 90% ist die Abdeckung dann allerdings so löchrig, dass sie als unprofessionell anzusehen ist. Wer also mit automatischen Tests beginnt, sollte immer auch gleichzeitig die Codeabdeckung messen. Sonst lässt sich keine Aussage über die Qualität der Tests machen.<br /><br />Für die Messung der Codeüberdeckung gibt es zwei einfache Kennzahlen, die als C0- und C1-Kennzahlen bezeichnet werden. Die C0-Kennzahl misst die Anweisungsüberdeckung, wogegen die C1-Kennzahl die Entscheidungsüberdeckung bzw. die Zweigüberdeckung misst.<br /><br /><pre>
C0 = (Anzahl der getesteten Anweisungen / Anzahl der gesamten Anweisungen) &#42; 100%
</pre><br /><pre>
C1 = (Anzahl der getesteten Entscheidungen bzw. Zweige / Anzahl der gesamten Entscheidungen bzw. Zweige) &#42; 100%
</pre><br />C1 ist dabei die stärkere Kennzahl, da 100% Entscheidungsüberdeckung bzw. Zweigüberdeckung 100% Anweisungsüberdeckung impliziert. Der Umkehrschluss gilt nicht.<br /><br />Der Anweisungsüberdeckungstest sowie der Zweigüberdeckungstest arbeiten auf Basis eines Kontrollflussgraphen, siehe <a class="externallink" href="http://de.wikipedia.org/wiki/Kontrollflussgraph" title="http://de.wikipedia.org/wiki/Kontrollflussgraph" target="_blank">http://de.wikipedia.org/wiki/Kontrollflussgraph</a>, während der Entscheidungsüberdeckungstest direkt auf dem Quellcode basiert. Die Testverfahren Anweisungsüberdeckungstest und Zweigüberdeckungstest sind sehr gut unter <a class="externallink" href="http://de.wikipedia.org/wiki/Kontrollflussorientierte_Testverfahren" title="http://de.wikipedia.org/wiki/Kontrollflussorientierte_Testverfahren" target="_blank">http://de.wikipedia.org/wiki/Kontrollflussorientierte_Testverfahren</a> beschrieben.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br /><h3 class="separator">Teilnahme an Fachveranstaltungen<a class="headeranchor" id="Teilnahme_an_Fachveranstaltungen_8" href="#Teilnahme_an_Fachveranstaltungen_8" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3>
<div class="box">Warum?<br />
Am besten lernen wir von anderen und in Gemeinschaft.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td></td><td></td><td></td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Um nicht nur "im eigenen Saft zu schmoren", ist es wichtig, regelmäßig mit anderen Softwareentwicklern zu diskutieren und Erfahrungen auszutauschen. Um dabei auch über den Tellerrand zu blicken, sollte der Austausch mit Entwicklern außerhalb des eigenen Teams, der täglichen Routine, erfolgen. Gut geeignet sind User Groups, die sich in allen Regionen Deutschlands finden lassen.<br /><br />Bei den regionalen User Groups steht der Erfahrungsaustausch im Vordergrund. Der ist wichtig. Je länger der aber innerhalb derselben Gruppe stattfindet, je besser man die Gesprächspartner kennt, desto mehr gleichen sich die Meinungen auch in einer User Group wieder an. Deshalb ist es wichtig, immer wieder auch über diesen Tellerrand hinaus zu schauen. Neues Gedankenfutter und Diskussionen mit ganz anderen Entwicklern bieten dafür überregionale Entwicklerkonferenzen.<br /><br />Für Gedankenaustausch und Inspiration sollte ein CCD also drei Ebenen im Blick behalten: das eigene Entwicklerteam, die regionale User Group und die überregionale Konferenz. Jede Ebene hat dabei ihren eigenen Rhythmus: täglich, monatlich, jährlich.<br /><br />Links:
<ul><li><a class="externallink" href="http://europe.ineta.org/Countries/Germany/Home/tabid/178/Default.aspx" title=".Net User Groups in Deutschlands" target="_blank">.Net User Groups in Deutschlands</a></li><li><a class="externallink" href="http://wiki.python.de/Stammtisch" title=" Python User Groups in Deutschland" target="_blank"> Python User Groups in Deutschland</a></li><li><a class="externallink" href="http://www.ijug.eu/index.php?option=com_content&amp;view=article&amp;id=6&amp;Itemid=26 " title=" Einige deutsche Java User Groups" target="_blank"> Einige deutsche Java User Groups</a></li><li><a class="externallink" href="http://ka.stadtblog.de/it-termine " title=" IT-Termine in Karlsruhe" target="_blank"> IT-Termine in Karlsruhe</a></li><li><a class="externallink" href="http://www.techism.de/ " title=" IT-Termine in München" target="_blank"> IT-Termine in München</a><br /></li></ul><br /><h3 class="separator">Komplexe Refaktorisierungen<a class="headeranchor" id="Komplexe_Refaktorisierungen_9" href="#Komplexe_Refaktorisierungen_9" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h3><div class="box">Warum?<br />
Es ist nicht möglich, Code direkt in der ultimativen Form zu schreiben.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td></td><td></td><td>+</td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Bereits im <a class="pagelink" href="Roter-Grad.ashx" title="Roter Grad">roten Grad</a> sind einfache Refaktorisierungen eingeführt worden. Doch <i>Umbenennen</i> und <i>Methode extrahieren</i> reichen nicht aus, um den Code zu verbessern – oft sind größere Eingriffe erforderlich. Die Einteilung in einfache und komplexe Refaktorisierungen ist sinnvoll, weil komplexe Refaktorisierungen nur mit vorhandenen automatisierten Tests effizient und risikolos zu bewerkstelligen sind. Ohne Tests wäre nach dem Refaktorisieren nicht bekannt, ob der Code immer noch korrekt ist.<br /><br />Siehe auch unter <a class="pagelink" href="Tools.ashx" title="Tools">Tools</a>.<br /><br />Weiter geht es beim <a class="pagelink" href="Gr%c3%bcner-Grad.ashx" title="Grüner Grad">grünen Grad</a>
]]></description><pubDate>Sun, 20 Feb 2011 17:40:53 GMT</pubDate><guid isPermaLink="false">6E3636F7F342B29C5979A836BF06CC62</guid></item><item><title><![CDATA[Information Hiding Principle]]></title><link>http://clean-code-developer.de/Information-Hiding-Principle.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Durch das Verbergen von Details in einer Schnittstelle werden die Abhängigkeiten reduziert.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Beim Design einer Schnittstelle sollte man sich fragen, welche Details außen unbedingt sichtbar sein müssen. Mit Schnittstelle sind hier nicht nur Interfaces im objektorientierten Sinne gemeint, sondern auch implizite Schnittstellen. Jede Klasse hat zwangsläufig eine implizite Schnittstelle – sie enthält alle nach außen sichtbaren Details. Je mehr Details von außen sichtbar sind, desto höher ist die Kopplung zwischen der Klasse und ihren Verwendern. Benutzen die Verwender einer Klasse erstmal ein Detail, wird es schwerer, dieses Detail zu verändern. Dies steht der Evolvierbarkeit der Software entgegen.
]]></description><pubDate>Sun, 20 Feb 2011 17:38:25 GMT</pubDate><guid isPermaLink="false">98EE172E78804B0939B448DAD43FAD09</guid></item><item><title><![CDATA[Principle of Least Astonishment]]></title><link>http://clean-code-developer.de/Principle-of-Least-Astonishment.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Wenn sich eine Komponente überraschenderweise anders verhält als erwartet, wird ihre Anwendung unnötig kompliziert und fehleranfällig.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Softwareentwicklung ist in hohem Maße ein kreativer Prozess. In diesem Prozess ist es wichtig, in den Fluss einzutauchen (engl. Flow). Wenn man diesen Zustand erreicht hat, sprudelt der Code nur so heraus. Jegliche Störung des Flow führt zu Unterbrechungen und letztlich dazu, dass in der zur Verfügung stehenden Zeit nur wenig Code produziert wird bzw. die Qualität des Code nicht optimal ist. Denn nach jeder Unterbrechung muss der Entwickler erst wieder Fahrt aufnehmen und erneut in den Fluss zu kommen. Überraschungen stellen Störungen dar. Sie führen zu Unterbrechungen und Fehlern. Dazu ein Beispiel: Ist die Tastenbelegung in der Entwicklungsumgebung so gewählt, dass eine übliche Tastenkombination wie z.B. Ctrl-C eine völlig andere Bedeutung hat, behindert dies den Entwickler. Ein Entwickler wird sich jedesmal ärgern, wenn er die "falsche" Tastenkombination verwendet. Dies behindert kreatives Arbeiten.<br /><br />Software sollte überraschungsarm implementiert sein. Wenn eine Abfragemethode namens <i>GetValue()</i> nicht nur einen Wert liefert, sondern gleichzeitig den Zustand des Systems ändert, wird der Entwickler diese Methode im besten Fall meiden, da er mit bösen Überraschungen rechnet. Im ungünstigen Fall fällt ihm dieses merkwürdige Verhalten nicht rechtzeitig auf. (Abfragemethoden die den Zustand ändern, verstoßen gegen das <i>Command Query Separation</i> Prinzip). Die testgetriebene Entwicklung fördert überraschungsarme Schnittstellen, da die Schnittstelle aus der Sichtweise ihrer Verwendung entworfen und implementiert wird.
]]></description><pubDate>Sun, 20 Feb 2011 17:37:41 GMT</pubDate><guid isPermaLink="false">1F144C9CD1EBEFBA57035275420E2C07</guid></item><item><title><![CDATA[LSP]]></title><link>http://clean-code-developer.de/LSP.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[
]]></description><pubDate>Sun, 20 Feb 2011 17:37:04 GMT</pubDate><guid isPermaLink="false">C3C6084F86BFBD3BF543844C5C2999DF</guid></item><item><title><![CDATA[Liskov Substitution Principle]]></title><link>http://clean-code-developer.de/Liskov-Substitution-Principle.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Wer mit Erben zu tun hat, möchte keine Überraschungen erleben, wenn er mit Erblassern vertraut ist.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td>+</td><td></td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Auch das Liskov Substitution Principle (<a class="externallink" href="http://www.objectmentor.com/resources/articles/lsp.pdf" title="LSP" target="_blank">LSP</a>) ist ein <a class="pagelink" href="SOLID.ashx" title="SOLID">SOLID</a> Prinzip. Es besagt, dass Subtypen sich so verhalten müssen wie ihr Basistyp. Dies klingt zunächst banal. Am Beispiel von Exceptions wird deutlich, welche Probleme entstehen, wenn das Prinzip verletzt wird: Löst der Basistyp bei der Ausführung einer Methode keine Exception aus, müssen alle Subtypen sich an diese Regel halten. Löst die Methode eines Subtyps dennoch eine Exception aus, würde dies bei Verwendern, die ein Objekt vom Basistyp erwarten, Probleme verursachen, weil sie nicht darauf vorbereitet sind. Wenn der Basistyp an der Stelle keine Exception auslöst, ist der Verwender nicht darauf eingestellt, Exceptions behandeln zu müssen.<br /><br />Allgemeiner kann man das Prinzip auch so ausdrücken, dass ein Subtyp die Funktionalität eines Basistyps lediglich erweitern, aber nicht einschänken darf. Wenn eine Methode im Basistyp auf einem bestimmten Wertebereich definiert ist, darf der Subtyp diesen Wertebereich übernehmen oder auch erweitern, er darf ihn jedoch keinesfall einschränken.<br /><br />Aus dem Liskov Substitution Principle ergibt sich ferner die Empfehlung, über Vererbung sehr genau nachzudenken. In den allermeisten Fällen ist die Komposition der Vererbung vorzuziehen (<i>Favor Composition over Inheritance</i>). Bei der Vererbung sollte man in jedem Fall über das Verhalten nachdenken, nicht nur über die Struktur. Statt Vererbung als <i>is-a</i> Relation zu betrachten und dabei nur die (Daten-)Struktur zu bedenken, sollte man besser von einer <i>behaves-as</i> Relation ausgehen und das Verhalten der Klasse berücksichtigen.<br /><br /><h4 class="separator">Quellen<a class="headeranchor" id="Quellen_0" href="#Quellen_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<table><thead><tr><th>Quelle</th><th>Autor</th><th>Kurzbeschreibung</th></tr></thead><tbody><tr><td><a class="externallink" href="http://www.objectmentor.com/resources/articles/lsp.pdf" title="http://www.objectmentor.com/resources/articles/lsp.pdf" target="_blank">http://www.objectmentor.com/resources/articles/lsp.pdf</a></td><td>Robert C. Martin</td><td>Artikel zum Liskov Substitution Principle von 1996, veröffentlicht im Engineering Notebook für <i>The C++ Report</i></td></tr></tbody></table>
]]></description><pubDate>Sun, 20 Feb 2011 17:36:38 GMT</pubDate><guid isPermaLink="false">255F327C3ADB7D1B5A159BBAAD2EB961</guid></item><item><title><![CDATA[DIP]]></title><link>http://clean-code-developer.de/DIP.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[
]]></description><pubDate>Sun, 20 Feb 2011 17:35:51 GMT</pubDate><guid isPermaLink="false">27F430579FA1C6E1BFE81F475F08EAD0</guid></item><item><title><![CDATA[Dependency Inversion Principle]]></title><link>http://clean-code-developer.de/Dependency-Inversion-Principle.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Punktgenaues Testen setzt Isolation von Klassen voraus. Isolation entsteht, wenn Klassen keine Abhängigkeiten von Implementationen mehr enthalten – weder zur Laufzeit, noch zur Übersetzungszeit. Konkrete Abhängigkeiten sollten deshalb so spät wie möglich entschieden werden. Am besten zur Laufzeit.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>++</td><td>+</td><td></td></tr><tr><td>Single Developer</td></tr></tbody></table><br />Auch das Dependency Inversion Principle (<a class="externallink" href="http://www.objectmentor.com/resources/articles/dip.pdf" title="DIP" target="_blank">DIP</a>) ist ein <a class="pagelink" href="SOLID.ashx" title="SOLID">SOLID</a> Prinzip. Es besagt folgendes:
<ul><li>High-Level Klassen sollen nicht von Low-Level Klassen abhängig sein, sondern beide von Interfaces.</li><li>Interfaces sollen nicht von Details abhängig sein, sondern Details von Interfaces.<br /></li></ul><br />Verwendet eine High-Level Klasse eine Low-Level Klasse unmittelbar, so ergibt sich eine starke Kopplung zwischen beiden. Spätestens beim Versuch, die High-Level Klasse isoliert zu testen, wird man auf Schwierigkeiten stoßen. Aus diesem Grund sollte die High-Level Klasse von einem Interface abhängig sein, das wiederum von der Low-Level Klasse implementiert wird. So kann die Low-Level Klasse im Unit Test durch ein <i>Mockup</i> ersetzt werden.<br /><br />Um zur Laufzeit die invertierte, abstrakte Abhängigkeit mit einem konkreten Objekt aufzulösen, bieten sich im Prinzip drei Möglichkeiten:
<ul><li>mittels Konstruktorparameter "per Hand"</li><li>Einsatz eines Inversion of Control Containers (IoC Container) wie etwa Castle Windsor</li><li>Dependency Lookup<br /></li></ul><br />Im <a class="pagelink" href="Gelber-Grad.ashx" title="Gelber Grad">gelben Grad</a> injizieren wir die Abhängigkeiten zunächst nur über die Parameter der Konstruktoren. Dies ist anfangs die einfachste Lösung und funktioniert mit einer handvoll Klassen ganz gut. Später im <a class="pagelink" href="Gr%c3%bcner-Grad.ashx" title="Grüner Grad">grünen Grad</a> nutzen wir einen IoC Container und Dependency Lookup.<br /><br /><h4 class="separator">Quellen<a class="headeranchor" id="Quellen_0" href="#Quellen_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<table><thead><tr><th>Quelle</th><th>Autor</th><th>Kurzbeschreibung</th></tr></thead><tbody><tr><td><a class="externallink" href="http://www.objectmentor.com/resources/articles/dip.pdf" title="http://www.objectmentor.com/resources/articles/dip.pdf" target="_blank">http://www.objectmentor.com/resources/articles/dip.pdf</a></td><td>Robert C. Martin</td><td>Artikel zum Dependency Inversion Principle von 1996, veröffentlicht im Engineering Notebook für <i>The C++ Report</i></td></tr></tbody></table>
]]></description><pubDate>Sun, 20 Feb 2011 17:35:14 GMT</pubDate><guid isPermaLink="false">4C486006F85AE6B69DB67B57FA8A8D1D</guid></item><item><title><![CDATA[Source Code Konventionen]]></title><link>http://clean-code-developer.de/Source-Code-Konventionen.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Code wird häufiger gelesen als geschrieben. Daher sind Konventionen wichtig, die ein schnelles Lesen und Erfassen des Codes unterstützen.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>+</td><td>+</td><td></td><td></td></tr><tr><td>Team</td></tr></tbody></table><br />Wir betrachten die folgenden Aspekte als wichtig:
<ul><li>Namensregeln</li><li>Richtig Kommentieren<br /></li></ul><br />Damit wollen wir nicht zum Ausdruck bringen, dass andere Konventionen unwichtig sind, wir wollen nur mit diesen beiden beginnen, weil sie uns elementar erscheinen. Bei allen Code Konventionen ist uns nämlich eines ganz wichtig: es geht weniger um die konkrete Ausgestaltung, sondern um konsequentes Einhalten der Konvention. Und es geht um das Bewusstsein, dass Konventionen notwendig sind.<br /><br /><h4 class="separator">Namensregeln<a class="headeranchor" id="Namensregeln_0" href="#Namensregeln_0" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<div class="box">Warum?<br />
Ohne Namensregeln muss man sich wieder und wieder auf den Stil einzelner Entwickler einstimmen.</div><br />Namensregeln sollen den Leser des Codes dabei unterstützen den Code zu verstehen. Da es z.B. hilfreich ist, Felder von lokalen Variablen zu unterscheiden, könnte dies durch eine Namensregel unterstützt werden. Wie eine solche Konvention im Einzelfall aussieht ist Geschmacksache. Manche bevorzugen "this.xyz" andere "_xyz". Welche Variante man wählt ist uns nicht wichtig. Uns kommt es darauf an, dass die Konvention konsequent eingehalten wird. Die Notwendigkeit einer Namensregel für z.B. Felder hängt ferner vom Kontext ab. In einer Klasse mit 400 Zeilen wäre uns eine Namensregel, die Felder gegenüber Variablen hervorhebt, sehr wichtig, in überschaubaren Klassen tritt sie dagegen eher in den Hintergrund.
Mit Hilfe der Root Cause Analysis geht der Clean Code Developer der eigentlichen Ursache für die Notwendigkeit einer Namensregel auf den Grund.<br /><br /><h4 class="separator">Richtig kommentieren<a class="headeranchor" id="Richtig_kommentieren_1" href="#Richtig_kommentieren_1" title="Verknüpfung zu diesem Abschnitt">&#0182;</a></h4>
<div class="box">Warum?<br />
Unnötige oder gar falsche Kommentare halten beim Lesen auf. Der Code sollte so klar und deutlich sein, dass er möglichst ohne Kommentare auskommt.</div><br />Salopp gesagt ist ein Kommentar im Code ein Hinweis darauf, dass der Code noch verbessert werden kann. Typisch für solche Fälle sind 3 Zeilen Code, die mit einem Kommentar überschrieben sind. An der Stelle hilft es wahrscheinlich, die drei Zeilen als Methode zu extrahieren (Refactoring: Extract Method) und den Kommentar als Name der Methode zu verwenden. Ganz allgemein kann der Bedarf an Kommentaren reduziert werden, in dem man gute Namen verwendet für Variablen, Methoden, Klassen, etc.<br /><br />Statt
<pre>    int laenge; // in mm
</pre>
besser
<pre>    int laengeInMM; 
</pre><br />
Statt
<pre>    public double Preis() &#123;
        // Berechnet den Bruttopreis ...
    &#125;
</pre>
besser
<pre>    public Money BruttoPreis() &#123;
        ...
    &#125; 
</pre><br />Kommentiert werden sollte nicht was man tut, sondern, wenn überhaupt, wieso man etwas tut.
]]></description><pubDate>Sun, 20 Feb 2011 17:30:26 GMT</pubDate><guid isPermaLink="false">9EC8F450A439F9A70A5CECFC643D3DC2</guid></item><item><title><![CDATA[SoC]]></title><link>http://clean-code-developer.de/SoC.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[
]]></description><pubDate>Sun, 20 Feb 2011 17:29:37 GMT</pubDate><guid isPermaLink="false">EAE2D0001143941A1DE03A1B17EF56DC</guid></item><item><title><![CDATA[Separation of Concerns (SoC)]]></title><link>http://clean-code-developer.de/Separation-of-Concerns-SoC.ashx</link><author>herbivore (herbivore)</author><description><![CDATA[<div class="box">Warum?<br />
Wenn eine Codeeinheit keine klare Aufgabe hat ist es schwer sie zu verstehen, sie anzuwenden und sie ggf. zu korrigieren oder zu erweitern.</div><br /><table><thead><tr><th>Evolvierbarkeit</th><th>Korrektheit</th><th>Produktionseffizienz</th><th>Reflexion</th></tr></thead><tbody><tr><td>++</td><td>+</td><td></td><td></td></tr><tr><td>Team</td></tr></tbody></table><br />Übersetzt mit Trennung der Belange bedeutet dieses Prinzip, dass man nicht mehrere Belange in einer Klasse zusammenfassen soll. Was sind Belange? Belange sind "komplett verschiedene" Zwecke. Man sagt auch, Belange seien orthogonal zu einander und vor allem orthogonal zur Hauptfunktionalität einer Funktionseinheit. Beispiele für typische Belange sind: Tracing, Logging, Transaktionalität, Caching. Diese Belange sollen nach dem Prinzip der Separation of Concerns in spezialisierte Funktionseinheiten ausgelagert werden.<br /><br />Das Separation of Concerns Prinzip hängt eng mit dem Single Responsibility Prinzip zusammen. Dabei sind Concerns eine Übermenge von Responsibilities. Jede Responsibility besteht im Idealfall aus genau einem Concern, nämlich ihrer Kernfunktionalität. Oft sind in einer Responsibility jedoch mehrere Concerns vermischt. Da sich dies technisch meist nicht ganz vermeiden läßt, besagt das Prinzip nicht etwa, dass eine Responsibility nur aus einem Concern bestehen darf, sondern dass die Concerns getrennt sein sollten. Innerhalb einer Methode sollte beispielsweise klar erkennbar sein, dass es mehrere Concerns gibt. Ferner sollten die Concerns nicht irgendwie über die Methode verstreut sein, sondern so gruppiert, dass klar ist, was zu einem Concern gehört.<br /><br />Im Domain Driven Design versucht man beispielsweise die Business Domain von der Infrastruktur strikt zu trennen. So darf dort eine Klasse aus der Business Domain keinerlei Infrastruktur, etwa für Datenbankzugriffe, enthalten, sondern soll ausschließlich die Geschäftslogik abbilden. Persistenz ist ein "Concern" der nichts mit der Business Logik zu tun hat.
Separation of Concerns führt zu loser Kopplung und hoher Kohäsion. Die einzelnen Komponenten sind jeweils auf eine Aufgabe, einen Concern, fokussiert und dadurch leicht verständlich. Alle Teile aus denen die Komponente besteht, sind auf diese eine Aufgabe ausgerichtet, dadurch hängen die Teile eng zusammen (hohe Kohäsion). Separation of Concerns führt darüber hinaus auch zu gut testbaren Komponenten. Denn wenn der Zweck einer Codeeinheit fokussiert ist, muss weniger breit getestet werden. In Bezug auf die zu testende Codeeinheit sind weniger Testparameterkombinationen zu prüfen.
Soll die Trennung der Belange konsequent betrieben werden, muss die Objektorientierung um das Konzept der Aspektorientierten Programmierung (AOP) erweitert werden. Dadurch wird es möglich, Aspekte wie etwa Transaktionalität, Tracing oder Caching vollständig aus einer Methode herauszuziehen. 
]]></description><pubDate>Sun, 20 Feb 2011 17:29:17 GMT</pubDate><guid isPermaLink="false">4E664762DBF8BF47303D4616E5FB80E7</guid></item></channel></rss>
