Communitygithub.com

Razsk/VideoStudio

Gemeinsame Vokabeln für das Design tiefer Module. Verwende dies, wenn der Benutzer das Interface eines Moduls entwerfen oder verbessern, Vertiefungsmöglichkeiten finden, eine Nahtstelle festlegen, Code testbarer oder KI-navigierbarer machen möchte, oder wenn eine andere Fähigkeit die Tiefmodul-Vokabeln benötigt.

Was ist VideoStudio?

Diese Fähigkeit (Skill) definiert eine präzise Terminologie für das Design sogenannter 'tiefer Module' (Deep Modules) in der Softwareentwicklung. Sie basiert auf dem Konzept von John Ousterhout und Michael Feathers und zielt darauf ab, Softwarearchitektur durch konsistente Sprache wie 'Modul', 'Interface', 'Implementation', 'Naht' (Seam), 'Tiefe' (Depth) und 'Adapter' zu verbessern. Die Hauptvorteile sind 'Hebelwirkung' (Leverage) für Aufrufer und 'Lokalität' (Locality) für Entwickler. Die Fähigkeit unterstützt die Entwicklung mit KI-Assistenten wie Claude Code oder Cursor, indem sie eine klare, von KI verarbeitbare Vokabelbasis für Code-Reviews, Refactoring und Testbarkeit bietet. Sie enthält praktische Prinzipien wie den 'Lösch-Test', die Regel 'Ein Adapter ist eine hypothetische Naht, zwei Adapter eine reale', und konkrete Testbarkeitsrichtlinien. Verweise auf vertiefende Dokumente wie DEEPENING.md und DESIGN-IT-TWICE.md sind enthalten.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Razsk/VideoStudio/tree/HEAD/.agents/skills/codebase-design

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Codebase-Design

Design tiefer Module: viel Verhalten hinter einer kleinen Schnittstelle, platziert an einer sauberen Naht, testbar durch diese Schnittstelle. Verwende diese Sprache und diese Prinzipien überall dort, wo Code entworfen oder umstrukturiert wird. Ziel ist Hebelwirkung für Aufrufer, Lokalität für Entwickler und Testbarkeit für alle.

Glossar

Verwende diese Begriffe genau: Ersetze sie nicht durch „Komponente", „Service", „API" oder „Grenze". Konsistente Sprache ist der ganze Punkt.

Modul: Alles mit einer Schnittstelle und einer Implementierung. Bewusst skalierungsneutral: eine Funktion, Klasse, ein Paket oder ein bereichsübergreifender Schnitt. Vermeide: Einheit, Komponente, Service.

Schnittstelle (Interface): Alles, was ein Aufrufer wissen muss, um das Modul korrekt zu verwenden: die Typsignatur, aber auch Invarianten, Ordnungsbeschränkungen, Fehlermodi, erforderliche Konfiguration und Leistungsmerkmale. Vermeide: API, Signatur (zu eng, sie beziehen sich nur auf die Typebene).

Implementierung: Was sich innerhalb eines Moduls befindet, sein Codekörper. Unterscheidet sich von Adapter: Ein Ding kann ein kleiner Adapter mit einer großen Implementierung sein (ein Postgres-Repository) oder ein großer Adapter mit einer kleinen Implementierung (ein In-Memory-Fake). Greife zu „Adapter", wenn die Naht das Thema ist; andernfalls zu „Implementierung".

Tiefe (Depth): Hebelwirkung an der Schnittstelle. Die Menge an Verhalten, die ein Aufrufer (oder ein Test) pro Einheit der Schnittstelle ausüben kann, die er lernen muss. Ein Modul ist tief, wenn eine große Menge an Verhalten hinter einer kleinen Schnittstelle sitzt, flach, wenn die Schnittstelle fast so komplex ist wie die Implementierung.

Naht (Seam) (Michael Feathers): Ein Ort, an dem du Verhalten ändern kannst, ohne an dieser Stelle zu editieren; der Ort, an dem die Schnittstelle eines Moduls lebt. Wo die Naht platziert wird, ist eine eigene Designentscheidung, die sich von dem unterscheidet, was dahinter liegt. Vermeide: Grenze (überladen mit dem DDD-Bounded Context).

Adapter: Ein konkretes Ding, das eine Schnittstelle an einer Naht erfüllt. Beschreibt die Rolle (welchen Slot es füllt), nicht die Substanz (was drin ist).

Hebelwirkung (Leverage): Was Aufrufer aus der Tiefe gewinnen. Mehr Fähigkeit pro Einheit der Schnittstelle, die sie lernen. Eine Implementierung zahlt sich über N Aufrufstellen und M Tests aus.

Lokalität (Locality): Was Entwickler aus der Tiefe gewinnen. Änderungen, Fehler, Wissen und Verifikation konzentrieren sich an einem Ort, anstatt sich über Aufrufer zu verteilen. Einmal repariert, überall repariert.

Tief vs. flach

Tiefes Modul = kleine Schnittstelle + viel Implementierung:

┌─────────────────────┐
│  Kleine Schnittstelle │  ← Wenige Methoden, einfache Parameter
├─────────────────────┤
│                     │
│  Tiefe Implementierung│  ← Komplexe Logik verborgen
│                     │
└─────────────────────┘

Flaches Modul = große Schnittstelle + wenig Implementierung (vermeiden):

┌─────────────────────────────────┐
│       Große Schnittstelle       │  ← Viele Methoden, komplexe Parameter
├─────────────────────────────────┤
│  Dünne Implementierung          │  ← Leitet nur durch
└─────────────────────────────────┘

Wenn du eine Schnittstelle entwirfst, frage:

  • Kann ich die Anzahl der Methoden reduzieren?
  • Kann ich die Parameter vereinfachen?
  • Kann ich mehr Komplexität im Inneren verstecken?

Prinzipien

  • Tiefe ist eine Eigenschaft der Schnittstelle, nicht der Implementierung. Ein tiefes Modul kann intern aus kleinen, mockbaren, austauschbaren Teilen bestehen; sie sind nur nicht Teil der Schnittstelle. Ein Modul kann interne Nähte (privat für seine Implementierung, verwendet von seinen eigenen Tests) sowie die externe Naht an seiner Schnittstelle haben.
  • Der Lösch-Test. Stell dir vor, das Modul zu löschen. Wenn die Komplexität verschwindet, war es ein Durchgang. Wenn die Komplexität über N Aufrufer wieder auftaucht, hat es sich bezahlt gemacht.
  • Die Schnittstelle ist die Testoberfläche. Aufrufer und Tests überschreiten dieselbe Naht. Wenn du hinter die Schnittstelle testen willst, hat das Modul wahrscheinlich die falsche Form.
  • Ein Adapter bedeutet eine hypothetische Naht. Zwei Adapter bedeuten eine echte. Führe keine Naht ein, es sei denn, es variiert tatsächlich etwas über sie hinweg.

Entwerfen für Testbarkeit

Gute Schnittstellen machen Tests natürlich:

  1. Abhängigkeiten akzeptieren, nicht erzeugen.

    // Testbar
    function processOrder(order, paymentGateway) {}
    
    // Schwer zu testen
    function processOrder(order) {
      const gateway = new StripeGateway();
    }
    
  2. Ergebnisse zurückgeben, keine Seiteneffekte erzeugen.

    // Testbar
    function calculateDiscount(cart): Discount {}
    
    // Schwer zu testen
    function applyDiscount(cart): void {
      cart.total -= discount;
    }
    
  3. Kleine Oberfläche. Weniger Methoden = weniger benötigte Tests. Weniger Parameter = einfachere Testeinrichtung.

Beziehungen

  • Ein Modul hat genau eine Schnittstelle (die Oberfläche, die es Aufrufern und Tests präsentiert).
  • Tiefe ist eine Eigenschaft eines Moduls, gemessen an seiner Schnittstelle.
  • Eine Naht ist der Ort, an dem die Schnittstelle eines Moduls lebt.
  • Ein Adapter sitzt an einer Naht und erfüllt die Schnittstelle.
  • Tiefe erzeugt Hebelwirkung für Aufrufer und Lokalität für Entwickler.

Abgelehnte Rahmen

  • Tiefe als Verhältnis von Implementierungszeilen zu Schnittstellenzeilen (Ousterhout): Belohnt das Aufblähen der Implementierung. Wir verwenden stattdessen Tiefe-als-Hebelwirkung.
  • „Schnittstelle" als das TypeScript-interface-Schlüsselwort oder die öffentlichen Methoden einer Klasse: zu eng: Schnittstelle umfasst hier jede Tatsache, die ein Aufrufer kennen muss.
  • „Grenze": Überladen mit dem DDD-Bounded Context. Sage Naht oder Schnittstelle.

Tiefer gehen

  • Vertiefen eines Clusters unter Berücksichtigung seiner Abhängigkeiten, siehe DEEPENING.md: Abhängigkeitskategorien, Naht-Disziplin und Ersetzen-statt-Schichten-Testen.
  • Erkunden alternativer Schnittstellen, siehe DESIGN-IT-TWICE.md: Parallele Sub-Agenten starten, um die Schnittstelle auf mehrere radikal unterschiedliche Weisen zu entwerfen, dann hinsichtlich Tiefe, Lokalität und Nahtplatzierung vergleichen.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Verwandte Skills