Wenn du Software entwickelst, stolperst du früher oder später über die Begriffe "funktionale Anforderungen" und "nicht funktionale Anforderungen". Diese tauchen in Fachbüchern, in Tickets und in Meetings auf, oft so, als wäre das alles selbstverständlich. Ist es aber nicht - gerade als Einsteiger fühlt sich das schnell nach Theorie-Kauderwelsch an.
In diesem Artikel schauen wir uns in Ruhe an, was diese beiden Begriffe bedeuten, wo sie herkommen, wie du sie im Alltag erkennst und halbwegs sauber definierst. Ziel ist nicht, dass du jede DIN-Norm auswendig kennst, sondern dass du beim nächsten Ticket oder Fachkonzept klarer siehst: Was soll das System tun - und wie gut soll es das tun?
Was sind Anforderungen überhaupt?
Eine Anforderung beschreibt, was ein System leisten soll. Punkt. Das können ganz einfache Sätze sein wie "Der Benutzer kann sich einloggen" oder "Das System exportiert Daten als CSV-Datei".
In der Softwaretechnik hat man irgendwann gemerkt: Es reicht nicht, nur zu sagen, was das System macht. Es ist auch wichtig, wie gut es das macht. Also z.B. wie schnell, wie sicher, wie stabil, wie benutzbar. Daraus sind die zwei grossen Kategorien entstanden:
- Funktionale Anforderungen: Was soll das System fachlich tun?
- Nicht funktionale Anforderungen: Unter welchen Rahmenbedingungen und mit welcher Qualität soll es das tun?
Beide sind wichtig. Funktionale Anforderungen ohne Qualitätskriterien führen zu Software, die zwar irgendwie funktioniert, aber langsam, unsicher oder nervig in der Bedienung ist. Nur nicht funktionale Anforderungen ohne konkrete Funktionen sind dagegen reine Luftnummern.
Woher kommt die Unterscheidung?
Die Begriffe kommen aus dem Requirements Engineering, also dem systematischen Umgang mit Anforderungen. In der klassischen Software- und Systementwicklung hat man früh versucht, Ordnung in das Chaos aus Wünschen, Ideen und Fachbegriffen zu bringen.
Man hat also getrennt zwischen:
- dem beobachtbaren Verhalten eines Systems ("Das System tut X, wenn Y passiert")
- und den Eigenschaften, die dieses Verhalten überspannen ("Das Ganze soll performant, sicher, wartbar sein")
Diese Trennung ist nicht nur Theorie. Sie hilft dir im Alltag: Du kannst so Anforderungen sauberer diskutieren, Testfälle daraus ableiten und später auch besser prüfen, ob deine Umsetzung wirklich das liefert, was vereinbart war.
Funktionale Anforderungen: Was soll das System tun?
Funktionale Anforderungen beschreiben konkrete Fähigkeiten des Systems. Also alles, was du beobachten kannst, wenn du mit der Anwendung arbeitest oder eine API aufrufst.
Beispiele:
- "Der Benutzer kann sich mit E-Mail und Passwort anmelden."
- "Das System berechnet den Gesamtpreis einer Bestellung inklusive Mehrwertsteuer."
- "Die REST-API liefert für /customers/{id} die Kundendaten im JSON-Format."
Typisch ist: Es gibt einen Auslöser (Benutzeraktion, Timer, Request) und eine Reaktion des Systems. Du kannst dazu recht einfach direkt Testfälle definieren.
Ein kleines Java-Schnipsel als Beispiel für eine funktionale Anforderung könnte so aussehen:
// Funktionale Anforderung:
// "Das System berechnet fuer einen Warenkorb die Summe aller Positionen."
public class CartService {
```
public BigDecimal calculateTotal(Cart cart) {
return cart.getItems().stream()
.map(item -> item.getPrice().multiply(
BigDecimal.valueOf(item.getQuantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
```
}
Die Anforderung sagt hier ganz konkret, was passieren soll. Ob das nun schnell ist, gut strukturiert, sicher usw. - das ist eine andere Frage. Und damit sind wir auch direkt bei den nicht funktionalen Anforderungen.
Nicht funktionale Anforderungen: Wie gut soll das System sein?
Nicht funktionale Anforderungen beschreiben Qualitätsmerkmale und Rahmenbedingungen. Sie sagen nicht, welche Funktion es gibt, sondern wie diese Funktionen sich verhalten sollen.
Typische Bereiche sind:
- Performance: "Die Antwortzeit der Login-Funktion darf im Durchschnitt 500 ms nicht überschreiten."
- Sicherheit: "Alle Benutzer-Passwörter müssen gehasht gespeichert werden."
- Zuverlässigkeit: "Das System soll eine Verfügbarkeit von 99,5 % im Monat haben."
- Usability: "Fehlermeldungen sollen in verständlicher Sprache angezeigt werden."
- Wartbarkeit: "Code soll nach Clean-Code-Prinzipien strukturiert werden."
Du siehst: Das sind oft Dinge, die nicht nur eine einzelne Methode betreffen, sondern das Gesamtsystem oder grössere Teile davon. Trotzdem lassen sich auch daraus Tests und Metriken ableiten.
Ein einfaches Beispiel im Code-Kontext könnte so aussehen:
// Nicht funktionale Anforderung:
// "Alle REST-Endpunkte muessen in unter 1 Sekunde antworten
// bei bis zu 100 gleichzeitigen Anfragen."
// In Tests koennte man das zum Beispiel mit einem Lasttest pruefen.
// Pseudocode, kein produktiver Test:
@Test
void endpoint_should_respond_fast_under_load() {
// 100 parallele Requests gegen /api/orders ausfuehren
// und sicherstellen, dass 95% davon <= 1000 ms brauchen
}
Die konkrete Umsetzung dieser Anforderung passiert nicht in einer Methode, sondern durch Architekturentscheidungen, Caching, Datenbankdesign und sauberen Code. Aber die Anforderung selbst ist erst mal nur eine klare Aussage über das gewünschte Verhalten des Gesamtssystems.
Wie erkennst du den Unterschied in der Praxis?
Gerade am Anfang ist die Grenze zwischen funktional und nicht funktional nicht immer glasklar. Ein paar einfache Fragen helfen Dir beim Einsortieren:
- Beschreibt der Satz eine konkrete Aktion oder Funktion? Dann ist es meist funktional.
- Beschreibt der Satz eine Eigenschaft über mehrere Funktionen hinweg (schnell, sicher, stabil, einfach bedienbar)? Dann ist es meist nicht funktional.
Beispiel:
- "Der Benutzer kann nach Kundenname suchen." – funktional.
- "Die Suche soll maximal 2 Sekunden dauern." – nicht funktional.
Oft tauchen beide Seiten direkt nebeneinander auf. In einem Ticket könnte das z.B. so aussehen:
// Funktionale Anforderung:
// "Benutzer koennen Kunden nach Namen, Kundennummer und Ort suchen."
// Nicht funktionale Anforderungen:
// "Die Suchergebnisse sollen nach Relevanz sortiert werden."
// "Die Suche soll innerhalb von 2 Sekunden Ergebnisse liefern."
// "Die Suchabfrage darf keine SQL-Injection ermoeglichen."
Gerade die nicht funktionalen Anforderungen werden gerne weggelassen oder sehr allgemein formuliert ("schnell", "benutzerfreundlich"). Hier lohnt es sich, nachzufragen und zu präzisieren.
Wie definierst du gute Anforderungen?
Du brauchst dafür kein riesiges Methodenset, aber ein paar einfache Regeln helfen:
- Schreibe möglichst spezifisch: "Der Benutzer kann..." statt "Es sollte möglich sein...".
- Vermeide schwammige Wörter wie "schnell" oder "einfach" ohne konkrete Zahlen oder Beispiele.
- Jede Anforderung sollte prinzipiell prüfbar sein. Wenn du dir keinen Testfall dafür vorstellen kannst, ist sie wahrscheinlich zu unklar.
Aus "Die Seite soll schnell laden" wird zum Beispiel:
- funktional: "Die Startseite zeigt nach dem Login eine Übersicht der letzten Bestellungen an."
- nicht funktional: "Die Startseite soll bei normaler Last in 1 Sekunde geladen sein (Time to First Byte <= 500 ms)."
Je klarer du formulierst, desto weniger Missverständnisse hast du später in der Implementierung und im Review.
Warum das Ganze für dich als Anfänger wichtig ist
Vielleicht denkst du dir: "Ich will doch erst mal nur programmieren, wozu brauche ich das alles?" Die Antwort ist simpel: Anforderungen sind die Grundlage deiner Arbeit. Jede Zeile Code soll am Ende eine oder mehrere Anforderungen erfüllen.
Wenn du verstehst, ob eine Aussage funktional oder nicht funktional ist, kannst du:
- besser abschätzen, was konkret zu tun ist,
- sauberere Testfälle ableiten,
- bewusster Architektur- und Technologieentscheidungen treffen,
- zielgerichteter nachfragen, wenn etwas unklar ist.
Du musst die Begriffe nicht dogmatisch verwenden, aber es hilft dir, in Diskussionen klarer unterwegs zu sein. Und irgendwann schreibst du deine Tickets und Konzepte selbst - spätestens dann zahlt sich das aus.
Fazit
Funktionale Anforderungen beschreiben, was dein System tun soll. Nicht funktionale Anforderungen beschreiben, wie gut es das tun soll und unter welchen Rahmenbedingungen. Die Unterscheidung kommt aus dem Requirements Engineering, ist aber alles andere als reine Theorie: Sie hilft dir ganz konkret, Software gezielter zu planen, zu bauen und zu testen.
Wenn Du beim nächsten Ticket oder Fachdokument übers Lesen stolperst, geh einfach die Fragen durch: Reden wir hier gerade über eine Funktion oder über eine Eigenschaft des Systems? Kann ich das später irgendwie testen oder messen? Wenn du das sauber einsortierst, hast du einen grossen Schritt in Richtung professioneller Softwareentwicklung gemacht - egal, ob du seit drei Monaten oder seit zehn Jahren im Job bist.
