# Implementing for Maintainability

> **We are NOT DONE when the code works!**

>_Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live_
>
> ~_John F. Woods_


## Materials
- [Refactoring _by Martin Fowler_](https://learning.oreilly.com/library/view/refactoring-wie/9783958459434/)
  - [refactoring catalog](https://refactoring.com/catalog/)
- [Clean Code _by Uncle Bob_](https://learning.oreilly.com/library/view/clean-code/9783826655487/)


## Introduction
- Code wird häufiger gelesen als geschrieben
- **Refactoring** ist ein
  - Prozess, der die Struktur des Codes verbessert, ohne die Funktion zu verändern
  - disziplinierter Weg den Code zu bereinigen und so die Chance auf Bugs zu minimieren
- **Code Smells**
  - Charakteristik im Code, das etwas falsch sein könnte
  - Nicht alle Zeichen von Code Smells sind zwingend ein Zeichen von schlechtem Code

## Refactoring
### Rename Variables
```c++
    double a = height * width
    ↓
    double area = height * width
```

### Replace magic literals
```c++
    2 * 3.14 * radius
    ↓
    2 * pi * radius
```

### Extract Variable
```c++
    void renderBanner(){
      if((platform.toUpperCase().indexOf("MAC") > -1) &&
        (browser.toUpperCase().indexOf("IE") > -1) &&
        wasInitialized() && resize > 0){
          //do something
      }
    }
    
    ↓
    
    void renderBanner() {
      final bool isMacOs = platform.toUpperCase().indexOf("MAC"") > -1;
      final bool isIE = browser.toUpperCase().indexOf("IE") > -1;
      final bool wasResized = resize > 0;
      
      if (isMacOs && isIE && wasResized){
        //do something
      }
    }
```

### Extract Function
```c++
void printOwing(){
  printBanner();
  
  //prinz details
  std::cout << "name: " << name << std::endl;
  std::cout << "amount: " << getOutstanding() << std::endl;
}

↓

void printOwing(){
  printBanner();
  printDetails(getOutstanding());
}

void printDetails(double outstanding){
  std::cout << "name: " << name << std::endl;
  std::cout << "amount: " << outstanding << std::endl;
}
```

## Meaningful Names
- Namen im Code sollten immer die Intention der Variable/Funktion/Klasse zeigen
- Umbenennen, falls nicht
- Ein Wort pro Konzept
  - immer getName() bspw.

| Solution Domain Names | Problem Domain Names                                                 |
|-----------------------|----------------------------------------------------------------------|
| Developer-Sprache     | Code mit Kundenkontakt sollte verständlich für nicht-Entwickler sein |

## Functions
- Sollten klein sein
  - Nur eine Zeile im body von:
    - if/else
    - for-loop
    - while-loop
- Sollten nur eine Aufgabe haben
  - Geschafft, wenn 
    - es nicht möglich ist eine Funktion daraus zu extrahieren
    - sie keine Side-Effects haben
    - sie entweder auf etwas antworten ODER etwas tun
- switch-Statements nur, wenn
  - sie nur einmal vorkommen
  - sie polymorphe Objekte erzeugen
  - sie nicht für den Rest des Systems sichtbar sind

> **Don't Repeat Yourself! (DRY)**

### Arguments
- Weniger Argumente machen den Code lesbarer
- **Flag arguments are ugly**
  - Boolean in Funktion mitgeben zeigt, dass die Funktion mehrere Sachen macht → :(
- Ideale Anzahl an Argumenten ist 0
  - 1 Argument (**monadic**)
    - Fragen an ein Argument
      - _bspw. ```boolean file exists(String fileName)```_
    - Operation an argument ausführen und Ergebnis zurückgeben
    - Events
      - Kein Rückgabewert
  - 2 Argumente (**dyadic**)
    - schwieriger zu verstehen
    - Sind manchmal trotzdem sinnvoll
      - _bspw. wenn man einen Punkt (x, y) mitgibt_
  - 3 Argumente (**triadic**) (_sollten, wenn möglich, vermieden werden_)
    - sollten vermieden werden
  - Mehr Argumente (**polyadic**) (_sollten vermieden werden_)

### Argument Objects
- Wenn eine Funktion mehr als 2-3 Argumente braucht
  - Objekt erstellen, welches mehrere Argumente zusammenfasst
    - _bspw. ```double x, double y → Point center```

### Argument Lists
- Falls beliebig viele Argumente mitgegeben werden sollen, diese aber identisch behandelt werden
  - Zählen als "ein" Argument
  - _bspw. ```String.format("\%s worked \%.2 hours.", name, hours)```
    - Ist dyadic


## Comments

> **Don't comment bad code - rewrite it!**
> ~_B.W. Kernighan and P.J. Plaugher_

### Good comments
- gibt es, aber die besten sind die, die du nicht mehr schreiben musst

#### Legal comments
- sind häufig nötig und verständlich
- sollten trotzdem vermieden werden, indem auf ein Lizenz-File verwiesen wird
  - _bspw. Copyright etc._ 

#### Informative comments
- manchmal sollte man basic Informationen mitgeben, um die Sprache zu verstehen
- _bspw. ```//format matched kk:mm:ss``` ```"\\d*:\\d*:\\d*```_

#### Explanation of Intent
- _bspw._ ![image_49.png](image_49.png)

#### Clarification
- _bspw._ ![image_50.png](image_50.png)

#### Warning of Consequences
- _bspw._ ![image_51.png](image_51.png)

#### TODO Comments
- Sollten auch vermieden werden, einfach fertig machen :)

#### Amplification
- Manchmal zeigen Kommentare wie wichtig etwas ist
- _bspw._ ![image_52.png](image_52.png)

### Bad Comments
- Wenn der Code eh schon verständlich genug ist
- Zu viele Informationen
- Auskommentierter Code
- Nicht verständliche Verbindung zwischen Code und Kommentar


## Formatting / Style Guides
> Der beste Stil ist der, der durchgängig ist


## Classes
- Sollten klein sein
  - Wird gemessen in Responsibilities
  - **Single Responsibility Principle (SRP)**
    - Klassen sollten nur EINE Aufgabe haben
    - Führt zu high cohesion

| low cohesion                                                           | high cohesion                                                           |
|------------------------------------------------------------------------|-------------------------------------------------------------------------|
| bewirbt Schwierigkeit zu warten, testen, wiederverwenden, zu verstehen | bewirbt Robustheit, Verständlichkeit, Wiederverwendbarkeit, Reliability |


## Loose Coupling
> **Law of Demeter**
> 
> _Talk to Friends, not to Strangers_

- Ein Freund eines Freundes ist ein Fremder

![image_82.png](image_82.png)

- Minimiere den Grad von Interdependencies

![image_53.png](image_53.png)