Technik1 阅读

MVP ist kein Kompromiss, sondern eine intelligentere Entwicklungsreihenfolge

Als Ingenieure neigen wir natürlich dazu, Dinge „vollständig“ zu machen: eine elegante Architektur entwerfen, generische Komponenten abstrahieren, Authentifizierung, CI/CD, ein ausgefeiltes Designsystem einrichten … und am Ende verzögert sich der Go-Live immer weiter.

Die Denkweise des MVP (Minimum Viable Product) hilft dir im Wesentlichen dabei, mit geringerem Aufwand zu validieren, ob sich eine Idee lohnt, weiter investiert zu werden.

Für Entwickler bedeutet es nicht „schlechteren Code schreiben“, sondern „zur richtigen Zeit die richtigen technischen Entscheidungen treffen“.

Lass uns klarstellen: Was ist ein MVP?

Eine formellere Definition: Ein MVP ist eine Produktversion mit minimalen Funktionen, die aber ausreicht, um echten Benutzern zur Verfügung gestellt zu werden, um Feedback zu sammeln und Hypothesen zu validieren.

Hier sind drei wichtige Informationen:

Auf einen Satz vereinfacht: Finde mit einem Minimum an Code heraus, ob jemand das Ding wirklich nutzen will.

Die Kern-Denkweise der MVP-Entwicklung

Aus technischer Sicht kann man die MVP-Denkweise in ein paar Schritte unterteilen:

  1. Definiere klar die eine Frage, die validiert werden soll

    Zum Beispiel: „Sind Benutzer bereit, ein minimalistisches Online-Notiztool zu verwenden, anstatt sich weiterhin selbst per WeChat oder E-Mail zu schreiben?“

  2. Behalte nur die Funktionen, die zur Validierung dieser Frage notwendig sind.

    Notiz erstellen, Liste anzeigen, eine löschen – das reicht.

  3. Verwende deine schnellste Implementierungsmethode

    Nicht unbedingt der „angesagteste Tech-Stack“, sondern der, den du am besten kennst.

  4. Im minimalen Umfang veröffentlichen und die tatsächliche Nutzung beobachten

    Gib es zuerst an Kollegen und Freunde weiter, dann erwäge eine öffentliche Veröffentlichung.

  5. Iteriere basierend auf Verhaltensdaten, nicht auf Basis von nachgedachten Anforderungen.

    Schau, ob die Leute zurückkommen und es weiterhin nutzen, und nicht, ob sie „toll, toll“ sagen.

Ein einfacher Vergleich: Zwei typische Wege von Ingenieuren

Nicht-MVP-Weg (also der, den wir oft gehen):

MVP-Weg:

Die Architektur kann später nachgerüstet werden, aber wenn niemand es nutzen will, hast du eine ganze „Geisterstadt“ gebaut.

Praxistipp: Einen Notiz-MVP mit Next.js erstellen

Im Folgenden wird ein „Online-Notizblock/Merkzettel“ als Beispiel verwendet, um den MVP-Gedanken mit Next.js (App Router) einmal durchzuspielen.

1. Definiere zuerst den MVP-Umfang

Die Anforderungen sind bewusst klein gehalten:

Vorläufig nicht gemacht:

Ein solcher Umfang ist für jeden React-entwickler in 1–2 Tagen zu einer nutzbaren Version umsetzbar.

2. Projektgerüst und Grundstruktur

Erstelle ein App Router-Projekt mit der empfohlenen Methode aus der offiziellen Dokumentation.

Im Terminal:

bash
npx create-next-app@latest note-mvp
# oder TypeScript, App Router etc. als Standardoptionen wählen
cd note-mvp
npm run dev

In der Verzeichnisstruktur ist das app/-Verzeichnis der Kern. [nextjs](https://nextjs.org/docs/app)

So können wir die minimale Struktur anlegen:

3. Eine minimalistische API mit App Router schreiben

In app/api/notes/route.ts verwenden wir zunächst ein Array im Arbeitsspeicher, um den Speicher zu simulieren (in einer echten Umgebung könntest du SQLite/Supabase etc. verwenden).

ts
// app/api/notes/route.ts
import { NextResponse } from 'next/server'

type Note = {
  id: string
  content: string
  createdAt: string
}

let notes: Note[] = []

export async function GET() {
  return NextResponse.json(notes)
}

export async function POST(request: Request) {
  const { content } = await request.json()
  if (!content || typeof content !== 'string') {
    return new NextResponse('Invalid content', { status: 400 })
  }

  const note: Note = {
    id: crypto.randomUUID(),
    content,
    createdAt: new Date().toISOString(),
  }

  notes.unshift(note)
  return NextResponse.json(note, { status: 201 })
}

export async function DELETE(request: Request) {
  const { searchParams } = new URL(request.url)
  const id = searchParams.get('id')
  if (!id) {
    return new NextResponse('Missing id', { status: 400 })
  }

  notes = notes.filter((n) => n.id !== id)
  return new NextResponse(null, { status: 204 })
}

Dieser Code hat viele „optimierbare“ Punkte, wie:

Aber in der MVP-Phase erfüllt es bereits das Ziel „validieren: Jemand will etwas schreiben und wiederkommen“.

4. Eine einfache Seite schreiben

In app/page.tsx verwenden wir einen Client Component für die Interaktion.

tsx
'use client'

import { useEffect, useState } from 'react'

type Note = {
  id: string
  content: string
  createdAt: string
}

export default function Home() {
  const [notes, setNotes] = useState<Note[]>([])
  const [input, setInput] = useState('')
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    fetch('/api/notes')
      .then((res) => res.json())
      .then((data) => setNotes(data))
  }, [])

  async function handleAdd(e: React.FormEvent) {
    e.preventDefault()
    if (!input.trim()) return

    setLoading(true)
    try {
      const res = await fetch('/api/notes', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ content: input.trim() }),
      })
      const note: Note = await res.json()
      setNotes((prev) => [note, ...prev])
      setInput('')
    } finally {
      setLoading(false)
    }
  }

  async function handleDelete(id: string) {
    await fetch(`/api/notes?id=${id}`, { method: 'DELETE' })
    setNotes((prev) => prev.filter((n) => n.id !== id))
  }

  return (
    <main style={{ maxWidth: 600, margin: '2rem auto', padding: '0 1rem' }}>
      <h1>Minimal Notes MVP</h1>

      <form onSubmit={handleAdd} style={{ marginBottom: '1rem' }}>
        <textarea
          value={input}
          onChange={(e) => setInput(e.target.value)}
          rows={3}
          style={{ width: '100%', marginBottom: '0.5rem' }}
          placeholder="Schreib was..."
        />
        <button type="submit" disabled={loading}>
          {loading ? 'Wird gespeichert...' : 'Speichern'}
        </button>
      </form>

      <section>
        {notes.length === 0 && <p>Noch keine Notizen.</p>}
        {notes.map((note) => (
          <article
            key={note.id}
            style={{
              border: '1px solid #ddd',
              padding: '0.75rem',
              marginBottom: '0.75rem',
            }}
          >
            <p style={{ whiteSpace: 'pre-wrap' }}>{note.content}</p>
            <small style={{ color: '#666' }}>
              {new Date(note.createdAt).toLocaleString()}
            </small>
            <div>
              <button
                onClick={() => handleDelete(note.id)}
                style={{ marginTop: '0.25rem' }}
              >
                Löschen
              </button>
            </div>
          </article>
        ))}
      </section>
    </main>
  )
}

Diese Seite ist sehr „schlicht“: ein textarea, ein Button, eine Liste.

Aber sie hat bereits einen vollständigen Kreislauf geschlossen:

Aus MVP-Sicht reicht das bereits aus, um es 5–10 Testbenutzern zu geben und ihr tatsächliches Verhalten zu beobachten.

Welche MVP-Denkweise zeigt dieses Next.js-MVP-Beispiel?

Rückblickend auf die Implementierung können wir Folgendes feststellen:

Keine zusätzliche State-Management-Bibliothek, UI-Framework, komplexer Backend-Service.

Obwohl jetzt noch Arbeitsspeicher verwendet wird, ist der API-Pfad bereits festgelegt. Später kann die Datenbank ausgetauscht werden, indem nur die Implementierung in der Route geändert wird.

„Wird jemand bereit sein, eine kurze Notiz im Browser zu schreiben und am gleichen Einstiegspunkt zurückzukommen, um sie anzusehen/löschen?“

Für einen Ingenieur, der Next.js gut kennt, kann diese MVP-Implementierung an einem Tag fertiggestellt und auf Vercel bereitgestellt werden.

Von diesem Startpunkt aus kannst du basierend auf dem Benutzerverhalten die nächsten Schritte festlegen, z. B.:

Häufiger Irrtum: „Engineering-Perfektion“ als Ziel sehen

In echten Projekten sehen viele Ingenieure ein solches MVP als „vorläufiges Spielzeug“ an und haben ein schlechtes Gewissen:

Hier gibt es zwei realistische Überlegungen:

Ein MVP verneint nicht die Engineering-Qualität, sondern stellt die „qualitativ hochwertige Entwicklung“ nach der Validierung der Anforderung an.

Zum Schluss: Die MVP-Denkweise für Ingenieure

Betrachte die MVP-Denkweise als eine Form von Engineering-Risikomanagement:

Für erfahrene Entwickler ist ein praktischer Ansatz:

Teilen

Teilen

Diesen Artikel teilen.