DG1: Refactoring-Techniken aufzählen

Ich kann einige Refactoring-Techniken aufzählen, die einen Code lesbarer und verständlicher machen.

Lernziele

# Lernziel Beantwortet in
1 Ich kann mindestens 3 Refactoring-Techniken benennen. Gängige Refactoring-Techniken (7 Techniken)
2 Ich kann für jede Technik erklären, welches Problem sie löst und wie sie die Lesbarkeit verbessert. Problem und Wie es die Lesbarkeit verbessert bei jeder Technik
3 Ich kann in gegebenem Code typische Code Smells identifizieren, die auf Refactoring-Bedarf hinweisen. Code Smells

Was ist Refactoring?

Refactoring ist die Umstrukturierung von bestehendem Code, ohne dessen Verhalten zu ändern. Das Ziel ist es, den Code lesbarer, wartbarer und verständlicher zu machen.


Gängige Refactoring-Techniken

1. Extract Function

Problem: Eine Funktion ist zu lang und macht mehrere Dinge gleichzeitig. Man muss den gesamten Code lesen, um zu verstehen, was passiert.

Wie es die Lesbarkeit verbessert: Jeder Codeblock bekommt einen sprechenden Funktionsnamen. Die Hauptfunktion liest sich danach wie eine Zusammenfassung.

# Vorher
def process_order(order):
    # Preis berechnen
    total = 0
    for item in order["items"]:
        total += item["price"] * item["quantity"]
    if order["discount"]:
        total *= 0.9
    # Rechnung drucken
    print(f"Kunde: {order['customer']}")
    print(f"Total: {total}")

# Nachher
def calculate_total(items, has_discount):
    total = sum(item["price"] * item["quantity"] for item in items)
    return total * 0.9 if has_discount else total

def print_invoice(customer, total):
    print(f"Kunde: {customer}")
    print(f"Total: {total}")

def process_order(order):
    total = calculate_total(order["items"], order["discount"])
    print_invoice(order["customer"], total)

2. Rename Variable / Rename Function

Problem: Variablen und Funktionen haben nichtssagende Namen wie x, tmp, calc. Man muss den umliegenden Code lesen, um zu verstehen, was sie bedeuten.

Wie es die Lesbarkeit verbessert: Der Name allein verrät den Zweck. Code wird selbstdokumentierend.

# Vorher
def calc(x, y, z):
    return x * y - z

# Nachher
def calculate_net_price(unit_price, quantity, discount):
    return unit_price * quantity - discount

3. Inline Function

Problem: Eine triviale Funktion, die nur einmal aufgerufen wird, erzeugt unnötige Indirektion. Man muss zur Funktionsdefinition springen, nur um eine Zeile zu lesen.

Wie es die Lesbarkeit verbessert: Der Code ist direkt sichtbar, ohne Sprünge. Weniger Abstraktionsebenen.

# Vorher
def is_adult(age):
    return age >= 18

def can_vote(person):
    return is_adult(person["age"])

# Nachher
def can_vote(person):
    return person["age"] >= 18

4. Remove Dead Code

Problem: Auskommentierter oder unerreichbarer Code lenkt ab und suggeriert, dass er noch relevant ist. Entwickler trauen sich nicht, ihn zu löschen, weil unklar ist, ob er gebraucht wird.

Wie es die Lesbarkeit verbessert: Weniger Code bedeutet weniger zu lesen. Alles, was im File steht, ist auch tatsächlich relevant.

# Vorher
def get_status(code):
    if code == 200:
        return "OK"
    elif code == 404:
        return "Not Found"
    # Diese Zeile wird nie erreicht, wenn alle Codes abgedeckt sind
    # old_status = legacy_lookup(code)
    return "Unknown"

5. Simplify Conditional

Problem: Verschachtelte oder lange if-Bedingungen sind schwer zu lesen. Man muss mehrere Teilbedingungen im Kopf behalten, um den Gesamtausdruck zu verstehen.

Wie es die Lesbarkeit verbessert: Die Bedingung bekommt einen sprechenden Namen (is_eligible). Die Geschäftslogik wird auf einen Blick klar.

# Vorher
if user.age >= 18 and user.has_id and not user.is_banned and user.email_verified:
    grant_access(user)

# Nachher
def is_eligible(user):
    return (user.age >= 18
            and user.has_id
            and not user.is_banned
            and user.email_verified)

if is_eligible(user):
    grant_access(user)

6. Replace Magic Number with Named Constant

Problem: Zahlen wie 120 oder 0.85 im Code haben keine erkennbare Bedeutung. Man muss raten oder den Kontext studieren, um zu verstehen, wofür sie stehen.

Wie es die Lesbarkeit verbessert: MAX_SPEED_LIMIT ist sofort verständlich. Ausserdem muss der Wert nur an einer Stelle geändert werden.

# Vorher
if speed > 120:
    issue_ticket()

# Nachher
MAX_SPEED_LIMIT = 120

if speed > MAX_SPEED_LIMIT:
    issue_ticket()

7. Introduce Explaining Variable

Problem: Ein komplexer Ausdruck in einer if-Bedingung oder Berechnung ist schwer zu parsen. Man muss ihn mental zerlegen, um zu verstehen, was geprüft wird.

Wie es die Lesbarkeit verbessert: Jeder Teilausdruck bekommt einen Namen, der seine Bedeutung erklärt. Die Bedingung liest sich danach wie natürliche Sprache.

# Vorher
if order.total() > 100 and order.customer.loyalty_years > 2:
    apply_discount(order)

# Nachher
is_large_order = order.total() > 100
is_loyal_customer = order.customer.loyalty_years > 2

if is_large_order and is_loyal_customer:
    apply_discount(order)

Code Smells: Wann braucht es Refactoring?

Code Smell Beschreibung Passende Technik
Long Method Funktion ist zu lang (>20 Zeilen) Extract Function
Magic Numbers Zahlen ohne Kontext im Code Named Constant
Duplicated Code Gleicher Code an mehreren Stellen Extract Function
Dead Code Unerreichbarer/unbenutzter Code Remove Dead Code
Poor Naming Variablen wie x, tmp, data Rename Variable
Complex Conditional Verschachtelte if/else-Ketten Simplify Conditional
Long Parameter List Funktion mit zu vielen Parametern Introduce Parameter Object

This site uses Just the Docs, a documentation theme for Jekyll.