← SEARCHABLE ARCHIVE
C# · 2026-08-12

C# von den Grundlagen bis zum Profi — Folge 10

C# in einer testbaren Spielstruktur organisieren

INTERACTIVE READING MODE →

Die in diesem Blog verfassten Artikel wurden mit dem Ziel erstellt, zu unterrichten. Außerdem können die Informationen im Artikel falsch sein, also seien Sie bitte vorsichtig.

Es gibt einen Unterschied zwischen umfangreichen Grammatikkenntnissen und dem Erstellen eines Programms, das sich leicht ändern lässt. Lassen Sie uns abschließend die Spielregeln, das Speichern und den Bildschirm trennen, um eine Struktur zu erstellen, die in kleinen Einheiten überprüft werden kann.

Platzieren Sie Regeln in reinen Objekten

public sealed class CombatService
{
    public int CalculateDamage(int attack, int defense)
    {
        return Math.Max(1, attack - defense);
    }

    public void Attack(Character attacker, Character target)
    {
        int damage = CalculateDamage(attacker.Attack, target.Defense);
        target.TakeDamage(damage);
    }
}

Wenn Ihre Kampfregeln nicht direkt auf UI- oder Engine-Objekte verweisen, können Sie denselben Code in der Konsole und in Tests verwenden. Der Bildschirm ist lediglich für die Anzeige der Ergebnisse und die Übermittlung von Eingaben zuständig.

Hinter der Schnittstelle werden externe Funktionen platziert

public interface ISaveStore
{
    Task SaveAsync(SaveData data, CancellationToken token);
    Task<SaveData?> LoadAsync(CancellationToken token);
}

public sealed class GameSession
{
    private readonly ISaveStore saveStore;

    public GameSession(ISaveStore saveStore)
    {
        this.saveStore = saveStore;
    }
}

Indem Sie Ihre Datei- oder Serverimplementierung hinter einer Schnittstelle platzieren, können Sie anstelle eines echten Repositorys eine gefälschte Implementierung zum Testen bereitstellen. Dabei handelt es sich nicht um eine Ebene zum Verbergen der Funktionalität, sondern vielmehr um eine Grenze, die Code trennt, der sich unterschiedlich ändern kann.

Testen Sie den Vorgang

[Fact]
public void DamageNeverDropsBelowOne()
{
    var combat = new CombatService();

    int damage = combat.CalculateDamage(5, 100);

    Assert.Equal(1, damage);
}

Der Test überprüft extern sichtbare Regeln und folgt nicht einfach der Implementierung der privaten Methode. Dann können Sie sehen, ob derselbe Betrieb auch dann erhalten bleibt, wenn die interne Struktur organisiert ist.

Motorgrenzen setzen

In Unity kann ein MonoBehaviour Eingaben und einen Lebenszyklus empfangen, und ein reguläres C#-Objekt kann in Verantwortliche für die Regeln unterteilt werden. Wenn Sie alle Klassen zu einem MonoBehaviour machen, ist es einfacher, eine Verbindung zum Editor herzustellen, aber Erstellung und Test sind an die Engine gebunden.

Eine gute Struktur besteht nicht aus einer großen Anzahl von Dateien. Statuseigentümer, Lebensdauer asynchroner Vorgänge, Ereignisabmeldung und externe Ressourcengrenzen sind im Code klar strukturiert.

Die Typen, Schnittstellen, Generika, Ereignisse, LINQ und Async von C# sind keine separaten Technologien. Es handelt sich um ein Werkzeug, das gemeinsam genutzt wird, um veränderbare Teile aufzuteilen und Fehlzustände zu reduzieren.