CodeGym /Kurse /C# SELF /Tipps für Stil und Lesbarkeit von OOP-Code

Tipps für Stil und Lesbarkeit von OOP-Code

C# SELF
Level 25 , Lektion 4
Verfügbar

1. Einführung

"Sauberer Code" ist kein heiliges Mantra, sondern ein echtes Überlebenswerkzeug für Programmierer. In jedem, selbst im schönsten, OOP-Projekt sammeln sich sehr schnell viele Klassen, Felder, Methoden, tricky Verbindungen... Wenn du die Ästhetik und Struktur verletzt, wird dein eigener Code nach einer Woche zu einem unlösbaren Quest. Mehr über den "Kampf ums Überleben" findest du bei Robert Martin, "Clean Code" – genau über solche Schlachten.

Stil im Code ist nicht "jeder wie er will", sondern dafür da, dass alle leichter leben:

  • Ein Kollege (oder du selbst) kann schnell verstehen, was abgeht.
  • Fehler (vor allem architektonische) sind sofort sichtbar.
  • Der Code ist einfacher zu erweitern, mit weniger Fehlern.

Schauen wir uns an, wie man OOP-Code so schreibt, dass ihn Reviewer, Kollegen und sogar Linter lieben.

2. Namen: Deine erste Verteidigungslinie

Klassen benennen

Klassen in C# nennt man üblicherweise im PascalCase (jeder neue Wortteil beginnt mit einem Großbuchstaben, z.B.: MyNewClass) und so, dass der Name klar beantwortet: "Was ist das?". Namen sollten Substantive sein!

public class StudentAccount { /* ... */ }
public class InvoiceGenerator { /* ... */ }

Schlecht:

class doMagic { ... } // Schlecht: Was für Magie? PascalCase verletzt.

Methoden benennen

Methoden – auch im PascalCase, aber hier besser Verb + Objekt:

public void PrintReport() { ... }
public string GetFormattedName() { ... }

Methoden sollten eine Aktion widerspiegeln (Print, Get, Save, Calculate usw.), damit beim Lesen klar ist, was passiert.

Felder und Properties benennen

Felder sind meistens private, werden klein geschrieben im camelCase, oft mit Unterstrich:

private int _count;
private Student _owner;

PropertiesPascalCase, weil sie Teil des öffentlichen Interface der Klasse sind:

public int Balance { get; set; }

Variablen

Lokale VariablencamelCase, so kurz und verständlich wie möglich im Kontext:

string inputName;
int studentCount;

Und bitte Variablen wie a1, result2, something – nur wenn du dir selbst ein Quest für den nächsten Monat bauen willst.

3. Struktur einer Klasse organisieren

Die richtige Anordnung der Klassenmitglieder macht die Navigation einfacher und hilft, schnell zu verstehen, was wo ist.

Meistens ordnet man so:

  1. Konstruktoren
  2. Properties
  3. Methoden
  4. Verschachtelte Typen (enum, class usw.)

Beispiel:


public class Student
{
    // --- Felder ---
    private string _name;

    // --- Konstruktor ---
    public Student(string name)
    {
        _name = name;
    }

    // --- Properties ---
    public string Name
    {
        get => _name;
        set => _name = value;
    }

    // --- Methoden ---
    public void PrintInfo()
    {
        Console.WriteLine($"Name: {_name}");
    }
}

Diese "Blöcke" kann man gut mit Kommentaren trennen (// --- Methoden ---), besonders in großen Klassen. JetBrains Rider, Visual Studio und andere IDEs erlauben schnelles Ein- und Ausklappen von Sektionen.

4. Kommentare und Dokumentation

Kommentare sind gut. Aber schlecht, wenn man sie übertreibt oder "Erklärungen für unverständlichen Code" schreibt, wenn man einfach den Code ändern könnte!

Ein guter Kommentar erklärt das "Warum", nicht das "Was".

// Wir nutzen Guid als eindeutige ID, weil das System verteilt ist
public Guid Id { get; set; }

Dokumentation von Methoden, Klassen und Properties

Nutze xml-Dokumentation für Klassen und öffentliche Methoden. IDEs zeigen diese Beschreibungen beim Hover an.


/// <summary>
/// Repräsentiert einen Studenten der Uni.
/// </summary>
public class Student
{
    /// <summary>
    /// Name des Studenten.
/// </summary>
    public string Name { get; set; }
}

Was man NICHT kommentieren sollte

  • Einfache Sachen (i++ // erhöhen i um 1).
  • Schlecht benannte Variablen ("// hier passiert was" – ja, aber was?).

5. Teile und herrsche

Kleine Klassen und Methoden

Goldene Regel: eine Klasse – eine Verantwortung (siehe Single Responsibility Principle). Wenn die Klasse Student Notenverwaltung, E-Mail-Verarbeitung und Stundenplan-Management macht – irgendwas läuft da schief.

  • Klassen bis 300-400 Zeilen – okay. Mehr – Grund zum Nachdenken.
  • Methoden bis 15-20 Zeilen – lesbar. Ausnahmen gibt's, wenn es ein Handler für einen großen Case ist.

Beispiel für eine "aufgeblasene" Methode:


public void Process()
{
    // Benachrichtigung an den Kunden
    // Änderungen speichern
    // E-Mail senden
    // Logs schreiben
    // ... (15 Schritte)
}

Besser:


public void Process()
{
    NotifyClient();
    SaveChanges();
    SendEmail();
    LogActivity();
}

Jede Aktion ist in eine eigene private Methode ausgelagert, der Code wird kompakter und leichter zu testen.

6. Nützliche Tipps

Visuelle Struktur: Formatierung, Einrückungen, Leerzeilen

IDEs können Code automatisch schön formatieren (Ctrl+K, D in Visual Studio, Ctrl+Alt+L in Rider), aber die Prinzipien sollte man trotzdem kennen.

  • EINRÜCKUNGEN – 4 Leerzeichen. Keine Tabs, keine 2 Leerzeichen.
  • LEERZEILEN – trenne Methoden voneinander, Felder von Properties, Properties von Methoden.
  • KLAMMERN immer in neuer Zeile bei Klassen und Methoden (Allman-Stil):

public class Test
{
    public void Print()
    {
        Console.WriteLine("Hallo");
    }
}

"Starke" und "schwache" Klassenmitglieder: Zugriffsmodifikatoren

Mach immer alles so privat wie möglich: Öffne nur das, was wirklich von außen gebraucht wird. Wenn ein Feld oder eine Methode nur innerhalb der Klasse gebraucht wird – private. Nur wenn es für Vererbung gebraucht wird – protected. public – nur für Verträge.

Schlecht:

public string ConnectionString; // Jeder kann das ändern!

Besser:


private string _connectionString;
public string ConnectionString
{
    get => _connectionString;
    private set => _connectionString = value;
}

Automatische Properties verwenden

Seit es automatische Properties und init-only-Setter gibt, ist es fast schon peinlich, "manuelle" Properties zu schreiben.

Beispiel:


public string Name { get; set; } // Top!
public int Age { get; init; }    // Nur zur Initialisierung, sicherer.

Und wenn du berechnete Properties brauchst:


public string FullName => $"{FirstName} {LastName}";

Kapselung und Getter/Setter

Wenn eine Property eine Business-Logik für Änderung oder Kontrolle braucht, nutze ein privates Feld + öffentlichen Getter/Setter mit Logik.


private int _grade;
public int Grade
{
    get => _grade;
    set
    {
        if (value < 0) _grade = 0;
        else if (value > 100) _grade = 100;
        else _grade = value;
    }
}

So verhinderst du, dass du oder andere das Objekt versehentlich "kaputtmachen".

7. Noch mehr nützliche Tipps

Hab keine Angst vor Interfaces und Abstraktionen

Interfaces sind für bequeme Verträge, Tests und Erweiterbarkeit da.

Schlecht:

  • Interface mit nur einer Methode, die nirgends gebraucht wird;
  • Interface, das nur von einer Klasse implementiert wird.
Gut:
  • Interface, das von 2+ Klassen genutzt wird;
  • Interface für die Abstraktion externer Systeme (z.B. für Logging, Datenspeicherung).

Schreib Code so, dass er leicht testbar ist

Ein Zeichen für guten OOP-Code ist Testbarkeit.

  • Mach keine Methoden, die komplett auf globale Variablen oder statische Felder angewiesen sind.
  • Hab keine Angst vor Dependency Injection – über Konstruktor-Parameter (Dependency Injection).
  • Trenne Berechnungen (Logik) und User-Interaktion (Input/Output). Das erleichtert nicht nur das Testen, sondern auch die Weiterentwicklung.

Lifehacks und Anti-Patterns für Einsteiger

  • Schreib keinen "Gott-Klasse" (God Object), die alles macht.
  • Mach keine "magischen Zahlen" ohne Erklärung (if (status == 42) – warum 42?).
  • Missbrauch Vererbung nicht nur um der Vererbung willen – manchmal ist Komposition besser (Klasse mit Feldern anderer Klassen statt Vererbung).
  • Schreib keine komplexen Methoden mit 100 Zeilen – die kann niemand testen oder verstehen.
  • Lass immer Raum für Erweiterung (open/closed principle).

8. Wie schlechter und guter Code aussieht

Schlechtes Beispiel:


class s // Schlecht: Klassenname klein geschrieben.
{
    public int a; // sinnlos, schlechter Name
    public void m() // Schlecht: Methode mit nur einem Buchstaben.
    {
        Console.WriteLine(a);
        // Schlecht: unklar, was die Methode macht.
    }
}

Gutes Beispiel:


// Repräsentiert einen Studenten.
public class Student
{
    // Alter des Studenten.    
    private int _age;
    public int Age
    {
        get => _age;
        set => _age = value < 0 ? 0 : value;
    }

    // Gibt Infos über den Studenten aus.
    public void PrintInfo()
    {
        Console.WriteLine($"Alter des Studenten: {Age}");
    }
}
2
Aufgabe
C# SELF, Level 25, Lektion 4
Gesperrt
Korrekte Benennung von Klassen und Methoden
Korrekte Benennung von Klassen und Methoden
2
Aufgabe
C# SELF, Level 25, Lektion 4
Gesperrt
Organisation der Klassenstruktur
Organisation der Klassenstruktur
1
Umfrage/Quiz
Fehler beim Vererben, Level 25, Lektion 4
Nicht verfügbar
Fehler beim Vererben
Häufige Fehler beim Deklarieren von Klassen und Objekten
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION