MSDN Webcast: Codequalität (4 Teile)

Es gibt seit einigen Tagen einen Webcast von Golo Roden über das Thema “Codequalität”. Um Golo Rodes Blog nicht mit meinen Kommentaren zu zuspamen schreibe ich meine Kommentare hier als eignen Blog-Eintrag.

Um es gleich vorwegzunehmen: Wie auch von Golo Roden im Webcast erwähnt, gibt es kein “richtig” oder “falsch”. Es sollte eben aber auch konsistent sein bzw sich in einem Team alle Team-Mitglieder über ihre Guides einig sein, auch wenn’s schwer fällt. Meine Kommentare hier gehen davon aus, dass der/die LeserIn die entsprechenden Teile des Webcasts gesehen hat!

Teil 1: Richtlinien und Stil

Siehe Golo Rodens “Eisbären-Blog”, dort sind meine Kommentare bzgl. des ersten Teils dieser Webcast-Serie beim Blog-Eintrag “Anmut und Eleganz” vorhanden: http://www.des-eisbaeren-blog.de/post/2010/05/01/Anmut-und-Eleganz.aspx

Teil 2: Die äußere Form

Heute hatte ich endlich mal Zeit, mir den zweiten Teil dieser Webcast-Serie anzusehen. Im Großen und Ganzen gelungen. Aber hier einige Punkte, in denen ich nicht ganz mit Golo Roden übereinstimme (Erinnerung: Es gibt kein “richtig” oder “falsch”)

Empfehlungen

  1. Warning Level: 4 (Stimme zu!)
  2. Treat warning as errors: All (stimme auch hier zu – das durchzusetzen ist aber nicht überall leicht bzw. möglich, leider …)
  3. XML documentation file (Jein, ich bevorzuge das Microsoft-Utility StyleCop – nicht zu verwechseln mit FxCop; verwende aber beide!)

Zusätzliche Empfehlung meinerseits: Der ReSharper muss grün (=OK) anzeigen! Ist im Webcast schön zu sehen, dass der überwiegend gelb (=Warnung) ist.

ConsoleApplication1

Meiner Meinung nach, sollte auch der Projekt-Name bzw. Assembly-Name “sprechend” sein.

Namespaces

Bei der Namensgebung von Namespaces halte ich mich lieber an das in der MSDN vorgeschlagene Schema:
CompanyName.TechnologyName[.Feature][.Design]

Namespaces nach Namen sortieren halte ich für keine gute Idee. Meiner Meinung nach, sollte man Namespaces nach “Funktionalität” und nicht nach dem Alphabet sortieren. Allgemeinere Namespaces nach oben, sprich System wird immer der erste sein. ReSharper habe ich so konfiguriert, sodass System-Namespace immer expizit inkludiert sein darf.

Siehe auch Beispiel im Webcast: System.Globalization – händisch nachpflegen:
“Fehlerquelle” bzw. wird sicher oft und gerne vergessen …

Leerzeilen zwischen Namespace-Gruppen erübrigt sich für mich und finde ich nicht besonders schön. Kenne ein ASP.NET-Projekt wo teilweise 30 Namespaces importiert werden. Wenn bei einer Page (ASP.NET) System.Drawing, System.IO udgl. importiert werden, dann sollte man sich vielleicht überlegen, ob man am Design etwas verbessern kann (z.B. Style Sheets/CSS verwenden). Darüber hinaus finde ich es gut, wenn nur tatsächlich verwendete Namespaces verwendet werden. Habe oft gesehen, dass 30 oder mehr importiert, aber tatsächlich nur wenige (4-6) tatsächlich auch verwwendet wurden: Lesbarkeit. Wenn man ein .cs-File aufmacht, dann sieht man als erstes die importieren Namespaces und das sagt schon viel aus. Beispiel: Wird Linq inkludiert? Wenn ja, dann muss da irgendwo auch eine Linq-Query sein … (in einer ASP.NET-Page sollte das eher nicht der Fall sein: Business-Logik von UI trennen!)

Golo Roden:
using Microsoft.CSharp;
using Microosft.VisualBasic;

using System;
using System.Data;
using System.Globalization;
using System.Timers;

hfrmobile:
using System;
using System.Data;
using System.Timers;
using System.Globalization;
using Microsoft.CSharp;
using Microosft.VisualBasic;
using ThirtParty.Stuff…;

Meine Variante hat den Vorteil, dass das Visual Studio neue Namespace nicht an die abenteuerlichsten Stellen einfügt😉 Und für den ReSharper gibt es schon einen Feature-Request dzbgl. Ist aber sicher auch, wie vieles zu diesem Thema, Geschmackssache.

Das die Ordner-Struktur mit der Namespace-Struktur übereinstimmen sollte, da stimme ich Golo Roden gerne zu!

Tabs vs. Spaces

Tja, das leidige Thema. Meine nun knapp 15 jährige Programmier-Erfahrung hat mich gelehrt, dass Tabs der “bessere” Weg ist:

  1. In älteren Visual Studio Source Code Templates wurden Tabs verwendet – was unweigerlich zur Vermischung von “Tabs und Spaces” geführt hat und in anderen Editoren (z.B. Notepad++, Diff-Dialog von Tortoise/Subversion) der Code unleserlich wurde, je nachdem welche Tab-Einrückung gerade zufällig im Visual Studio eingestellt war (“Tabs to spaces” ist wohl das ungeschickteste Setting, dass sich MS hat einfallen lassen – ist aber nur meine Meinung bzw. Erfahrung)
  2. Die Source-Code-Dateien brauchen wenige Speicherplatz (dieses Argument nicht allzu ernst nehmen!)
  3. Regel Nr. 1, die ich damals beim MCSE gelernt habe: Default Settings! Und die war nun mal: Tabs
  4. Das, meiner Meinung nach Killer-Argument für Tabs: Jeder Entwickler hat seine “Vorlieben”. Golo Roden z.B. bevorzugt für Einrückungen 4 Zeichen. 90% der Entwickler, die ich kenne bevorzugen: 2 Zeichen (mich eingeschlossen). Wenn man Tabs verwendet, dann kann sich jeder seinen Editor die Tabsize so einstellen, wie er/sie es eben mag bzw. gewohnt ist.
  5. Vortsetzung des Killer-Argumentes für Tabs: Collective Code Ownership!

Bei Minute 44 spricht Golo Roden aber wieder von Tablaturen etc.😉 und zwar bei folgendem Beispiel:

int age  = 23;
int year = 2010;

Ja, früher hat man es so gemacht, ist aber genau so wie die Hungarian Notation in .NET unüblich. Warum Golo Roden hier die Tab-Settings als Argument dagen erwähnt bleibt mir noch ein Rätsel, da er ha ohnehin nur Spaces verwendet (auch für Einrückungen …). Ein Grund mehr für mich, bei Tabs zu bleiben😉 Das Argument mit der Schriftart (das nennt man auch “Monospace”-Schriftart) kann ich nicht nachvollziehen. Bei solchen Schriftarten, wo ein “i” underschiedlich breit wie ein “w” ist, sind üblicherweise auch die Spaces schmaler und wenn mit Spaces eingerückt wird …😉 Also, wie gesagt, viele Argumente sprechen für Tabs bei Einrückungen!

Lange Zeilen

Stimme hier Golo Roden gerne zu! Verwende zwar 120 Zeichen, aber das ist eben Geschmacks/Definitionssache.

Tipp: Seit VS.NET 2003 gibt es eine Möglichkeit eine Linie am rechten Rand einzublenden, dann sieht man gleich, wie lange eine Zeile tatsächlich sein darf bzw. kann das auch der StyleCop prüfen…?

Was sich auch noch bewährt hat, aber kein “Standard” ist: Nicht-Logische Einrückungen doppelt machen (siehe Beispiel mit dem Console.WriteLine()).

Leerzeilen / Kommentare

Stimme auch hier gößtenteils zu. Das sollte eigentlich selbstverständlich sein bzw. sollte ein Entwickler schon wissen, wo Leerzeilen bzw. Kommentare angebracht sind und wo nicht. Hier hilft auch der StyleCop von Microsoft (MSDN Code).

Das Beispiel im Webcast ist etwas konstruiert, aber sollte ja nur dem Verständnis dienen (z.B. “Say hello world.”). Im ersten Teil des Webcast wird von “unnötigen Kommentaren” gewarnt bzw. abgeraten:

// set i to 0
int i = 0;
// Say hello world
Console.WriteLine(“Hallo Welt”);

Meiner Meinung nach, sollten Kommentare einheitlich in einer Sprache (ich bevorzuge Englisch), nicht wie im Webcast bei Block-Kommentaren gezeigt, einmal auf Deutsch und dann wieder auf Englisch.

Types (Enums, Klassen etc.)

Da stimme ich auch wieder mit Golo Roden überein. Jeder Typ (Klasse, Enum) sollte in einer eigenen .cs-Datei stehen, auch wenn z.B. ein Enum auch noch so klein sein möge und das Schlüsselwort partial sollte auch nicht “missbraucht” werden.

Ich habe aber sogar einmal, bewusst dagegen verstoßen, um eine sog. Gott-Klasse in kleinere Teile mit Hilfe von partial aufzubrechen wobei ich den Zeitaufwand dafür möglichst gering halten musste. Eine Klasse die mehrere tausend Zeilen lang ist, ist schwer zu lesen … Das Design-Problem war damit nicht gelöst, aber man konnte die betroffene Klasse aufmachen und der Scrollbar war wieder bedienbar …😉

Access modifier

Im Webcast “Zugriffsmodifizierer” gennant. Soweit mir bekannt, ist eine Methode ohne “Access modifier” automatisch private und nicht wie im Webcast erwähnt public? Korrigiere mich, falls ich mich irre. Falls dem nicht so ist, hätte ich hier was dazugelernt bzw. auch die Bestätigung, dass es gut ist, den Access modifier immer anzugeben. Auch hier hilft StyleCop!

Runde Klammer / Leerzeichen

Stimme hier 100%ig zu! Man kann Visual Studio aber schon so konfiguierern, dass es mit Leerzeichen vor jeder “(“ verlangt. Ich habe die Erfahrung gemacht, dass jene Leute die Leereichen vor jeder “(“ bevorzugen, nicht konsequent sind und man oft so etwas sieht:

MethodA();
MethodB ();
MethodC (param);
MethodD(param);
MethodE ();

Das hat natürlich nichts mehr mit Collective Code Ownership zu tun, denn solchen Code habe ich oft genug gesehen, welcher von einer Person so geschrieben wurde. Je nachdem, wie diese Person aufgelegt war, einmal mit einmal ohne. Vielleicht ja an geraden Tagen mit und an ungeraden Tagen ohne, oder umgekehrt … Visual Studio bzw. StyleCop hilft einem heutzutage eh’ recht viel, seinen Code leserlich zu schreiben😉

Return

Ich bin für ohne Klammerung. Weniger ist mehr, oft habe ich auch folgendes gesehen:

return ((left) + (right));

Das tut dann schon etwas weh bzw. macht es den Code nicht lesbarer und ich keine keinen Entwickler, der nach Zeichenanzahl bezahlt wird. Aber, wie so oft ist das natürlich Geschmackssache, nur konsistent sollte es  sein und nicht einmal so, paar Zeilen weiter unten wieder anders.

for, if, …

Endlich mal wieder, bin ich anderer Meinung😉

if(condition)
{
    Console.WriteLine(“test”);
}
if (condition)
  Console.WriteLine(“test”);

Habe in den letzten 15 Jahren nie einen Bug eingebaut, der durch fehlende { } bei einem if etc. verursacht worden wäre …😉

PascalCase, camelCase, UPPERCASE

Habe einen kleinen Fehler bzw. Ungereihmtheit im Webcast entdeckt. Auf der Folie fehlte lowercase und es wurde erwäht (01:05:13), dass es das in C# nicht gibt. Stimmt so nicht: string name = “Golo”; // name is lowercase😉  (das //-Kommentar in der gleichen Zeile ist bewusst so).

Ist natürlich auch Auslegungssache, zu “name”, “left”, “right” etc. CamelCase zu sagen oder lowercase😉

Hehe, this. ist ausgeraut ^^ (siehe oben meine Empfehlung: ReSharper sollte grün sein – kann man konfigurieren)

_fieldName : Ja, stimme 100%ig zu😉 Auch StyleCop verlangt das so! In C# 3.0 eher in den Hintegrund gerückt, durch entpsrechende Sprachkonstrukte, aber _fieldName ist absolut üblich.

Aber finde folgende schreibweise für bevor C# 3.0 “schöner”:

public FirstName
{
  get { return _firstName; }
  set { _firstName = value; }
}

Auch die Reihenfolge von get / set ist “standardisiert” bzw. hilft hier auch StyleCop.

Keine Umlaute in Bezeichnern. Stimme auch hier zu, aber habe schon gesehen, dass das gerne gemacht wird … (leider).

Keine Abkürzungen: Auch hier stimmeich mit Golo Roden bzw. der MSDN überein.

Würde mir wünschen, dass bei diversen Microsoft-Prüfungen (z.B. MCPD) die Code-Samples im Test auch entsprechend MSDN konform sind, aber leider …

Präfixe und Suffixe

Hier stimme ich nicht ganz zu. Man sieht oft (leider) Präfixe á la txtFirstName (soll eine TextBox sein). Üblicher ist aber Suffixe á la FirstNameTextBox da es den Code besser lesbarer macht, wenn man gleich sieht, dass es sich um eine TextBox handelt. Könnte ja auch ein FirstNameComboBox sein, wenn der User einen Vornamen aus einer Liste auswählen kann.

Etwas anschaulicher: ProjectCategory

  1. Kann eine Eigenschaft sein
  2. Kann ein Klassenname sein
  3. Kann eine Methode sein (sollte nicht sein, sondern eher z.B. GetProductCategory())

Besser: ProjectCategoryReferenceValue oder ProjectCategoryEnumValue, ProjectCategoryIntegerValue etc., dann weiß man anhand des Namens gleich, ist es ein object, enum oder gar int. Ausnahmen bestätigen die Regel: Enum(eration) vs. Integer …😉

Aber wie gesagt, alles “nur” Richtlinien und keine Gesetze😉 Microsoft StyleCop (erhältlich bei MSDN Code) prüft vieles der erwähnen Konstrukte schon automatisch. Es gibt übrigens auch ein StyleCop for ReSharper-Visual Studio-PlugIn, der einem gleich beim Tippen auf die Finger klopft, sollte man was falsch machen.

Teil 3: Die innere Form

Hatte heute (2010-07-21) endlich mal wieder Zeit, da weiter zu machen. Im Großen und Ganzen OK. Hätte mir eine Auflistung der wichtigsten bzw gängigsten Pattern noch gewünscht. Die Ausprache von C# (ZE SHARP – aber es könnte schlimmer sein: ZE-KANALGITTER) lenkt mich leider immer wieder ab. Ich bin die Aussprache “SEE SHARP” gewohnt bzw. mag ich es nicht wenn man bestimmte Fachbegriffe wie Exception (Ausnahme), Factory (Fabrik)-Methoden, Pattern (Entwurfsmuster) etc. zwangsübersetzt, aber das ist wohl auch Geschmackssache. Bin eben der Meinung, dass ein Entwickler (OK, Developer ;-)) gewisse Grund-Kenntnisse in Englisch mitbringen muss. “Best Practice” wurde ja auch nicht übersetzt bzw. “stört” mich, dass manchmal der deutsche, manchmal der Englische Begriff verwendet wird (z.B.: Pattern / Entwurfsmuster, Exception / Ausnahme). Da würde ich mir etwas mehr Konsequenz wünschen …

Wie gesagt, Geschmäcker sind verschieden!

Aber es wird recht gut auf diverse Basics eingegangen (struct vs. class, abstract class vs. interface etc.).

Das sealed (“versiegelt” – mag diese Übersetzung auch nicht besonders) Klassen ein Problem bei TDD darstellen ist mir neu. Das hat ja schon einen Grund, warum eine Klasse sealed ist!

Habe vor kurzem (spät aber doch) meinen MCP-Track für den MCTS und den MCPD abgeschlossen:

  • MCTS
    • SQL Server 2005
    • .Net Framework 2.0 – Windows Applications
    • .Net Framework 2.0 – Web Applications
    • .Net Framework 2.0 – Distributed Applications
  • MCPD
    • Enterprise Application Developer
    • Windows Developer
    • Web Developer

Da kamen natürlich auch Fragen über TDD und die Kernaussage war/ist, dass man “nur” alle public Methoden/Eigenschaften einer Klasse testen soll/muss. Sprich, die Problematik, dass man protected-Methoden testen möchte und man dadurch ableiten muss, fällt zur Gänze weg. Sollte man, aus welchen Gründen auch immer, protected-Methoden testen wollen, dann sollte man sich über das Design der betroffenen Klasse noch Gedanken machen. Ausnahmen (nicht Exception ;-)) bestätigten die Regel. Auf mocking wurde nur ganz, ganz am Rande eingegangen.

Bei der Sache mit dem Standard-ctor stimme ich nicht ganz zu, obwohl die im Webcast angeführten Gründe recht plausibel klingen. Wenn eine Klasse keinen ctor hat, dann sollte man natürlich wissen, dass ein Standard-ctor vom C#-Compiler generiert wird. Und das ist auch gut so und hat sich bewehrt, auch bei C++. Wenn später ein ctor mit Parametern hinzukommt, sollte man natürlich einen parameterlosen ctor hinzufügen bzw. muss wissen was man tut. In den letzten 15 Jahren wäre mir kein Fehler/Bug untergekommen, der durch so eine Situation verursacht worden wäre. Für etwas, dass nie auftritt, braucht man auch keine Ausnahmespezialsonderregel erfinden … Stimme hier also mit dem ReSharper (R#) überein, der das gleich bemängelt, wenn man einen Standard-ctor baut, der nichts macht😉

Weniger ist mehr!

R#: Im Webcast ist es schön zu sehen, dass das this immer bzw. sehr oft unnötigerweise angegeben wird, es aber vom R# “ausgegraut” wird … Wenn man der “this-immer-angeben-Fraktion” angehört, sollte man den R# entsprechend konfigurieren … Ich bleibe bei meiner Meinung, dass man das this nur angeben sollte, wenn es tatsächlich benötigt wird.

Weniger ist mehr!

Was für mich etwas neu bzw. verwirrend war: Service Locator, Dependency Injection und “LightCore”. Bei den ersten beiden Begriffen handelt es sich vielleicht um eine nicht ganz übliche oder mir unbekannte Übersetzungen?

Wenn es darum geht, die “innere Form” anhand von Sprachkonstrukten zu erklären, dann erfüllt dieser Teil aber seine Aufgabe recht gut und in 77 Minuten kann man nicht alles abarbeiten. Mich verwirrten aber oftmals die Slides, die eine DEMO versprachen, aber es kam keine und es wurde zur nächsten Seite gesprungen.

Mythos “Exceptions” vs. “int-Fehlercodes”: Da sage ich jetzt nichts dazu😉 “Ausnahmen bestätigen die Regel” …

Exception vs. ApplicationException: Da stimme ich 100%ig zu🙂 Auch Microsoft ist manchmal etwas inkonsequent😉 MS sollte ihre ApplicationException mit [Obsolete] markieren😉

Bin schon auf den vierten Teil gespannt den ich mir bei Gelegenheit ansehen werde.

Erfahrung als wesentliche Richtlinie.
Dieses Fazit teile ich gerne und stimme 100%ig zu.

Teil 4: Werkzeuge

Vor wenigen Tagen hatte ich mal wieder Zeit und habe mir den vierten und letzten Teil dieser Webcast-Serie "reingezogen". Im Großen und Ganzen OK. Was aber wirklich gefehlt hat, war (zumindest) eine Aufzählung der gängigsten Tools. Das man, aus zeitlichen Grünen, nicht alle im Webcast im Detail vorstellen bzw. erklären kann, ist schon klar, aber was wirklich gefehlt hat, war: StyleCop!

FxCop wurde ja auch, mehr oder weniger detailliert, gezeigt. Kurzerhand behaupte ich, dass diese Tools folgendermaßen einzusetzen sind:

  • FxCop + StyleCop: Class library development
  • StyleCop: application development

Nett fand ich aber, dass #develop kurz erwähnt wurde. Ist, meiner Meinung nach, eine echte Alternative zu den Express-Editions von Visual Studio.

.NET ist immer und überall. So scheint es zumindest. Wenn man sich aber die Homepage der CCD (Clean Code Developer) mal anschaut, wird man sehen, dass es da auch einigermaßen gute Tools für z.B. C++ gibt: Visual Assist X von Tomato Software ist hier erwähnenswert.

Fazit

Insgesamt eine nette kleine Webcast-Serie die keineswegs überladen und die Zeit die man für’s Ansehen braucht wert ist. Man sollte allerdings nicht allzu viel erwarten, denn das beste "Tool" in der Softwareentwicklung ist immer noch "jahrelange Erfahrung". Aber ist auch schön zu sehen, dass man oft bestätigt wird bzw. dass man das letzte Jahrzehnt nicht alles "falsch" gemacht hat😉

About hfrmobile

Nice guy but with a sarcastic type of humor. I have combined hobby and profession and I am happy about this. At the moment I am holding MCP, MCSE (NT 4.0), MCTS and MCPD certificates. Having experience in developing software for more than 15 years. Started learning programming using Pascal, Assembler, C/C++. Also having experience with non-Microsoft products / programming languages (e.g. PHP). Most experiences at the moment: MySQL, MS-SQL, PL/SQL, ASP.NET, C#, Silverlight (Windows Phone) and WPF.
This entry was posted in Coding. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s