Programming Prinziples and GRASP Patterns

Programming Principles

KISS (Keep It Simple Stupid)

KISS ist ein Akronym für “Keep it Simple Stupid” und bedeutet soviel wie, dass das System immer verständlich sein soll. Das heisst, dass eher mehrere kleine Methoden mit wenig funktionalitäten implementiert werden, als wenige grosse Methoden.

YAGNI (You Aren’t Gonna Need It)

YAGNI ist ein Akronym für “You Aren’t Gonna Need It”. Funktionalitäten sollten nur dann implementiert werden, wenn sie wirklich gebraucht werden und auch nötig sind.

SOLID

Solid ist ein Akronym für folgendes:

Single responsibility: Jede Klasse sollte nur eine Verantwortung haben.

Open-Closed: Entitäten sollten erweitert werden können (offen), aber auch nicht veränderbar sein (geschlossen).

Liskov substitution: Objekte sollten durch ihre Subklassen ersetzt werden können und immer noch vollständig funktionieren.

Interface segregation: Es ist besser, viele spezifische Interfaces zu verwenden als nur ein generalisiertes Interface.

Dependency inversion: Man sollte sich auf Abstraktionen verlassen können, nicht auf Konkretionen.

DRY (Don’t Repeat Yourself)

Wenn man eine Funktion schon einmal implementiert hat, sollte man nicht mehrmals das Gleiche implementieren. Man sollte Funktionen so schreiben, dass sie mehrmals wiederverwendet werden könnten.

Divide and Conquer

Mit Divide and Conquer meint man, dass das Projekt in kleineren Teilen aufgeteilt werden muss, die einfacher zu verstehen sind. Danach vereinfacht man jedes Teil, bis nur noch das gut verständliche übrig bleibt.

 

GRASP Patterns

High Cohesion

High cohesion ist das Prinzip, dass man ähnliche Funktionalitäten zusammenstellt, um eine gewisse Struktur im Programm zu schaffen. Dies führt auch zu einer höheren Wiederverwendbarkeit des Codes

Beispiel: REST Request Controller Funktionen werden vom Service (Businesslogik) getrennt

Low Coupling

Im Low Coupling geht es darum, dass eine einzelne Funktion auch wirklich nur eine einzelne Funktionalität besitzt und nichts anderes macht. 

Beispiel:  “sortArray()” sollte nur ein Array sortieren und nicht zusätzlich noch das Array an die Konsole ausgeben

Information expert

Beim Information Expert geht es darum, dass man beachtet, welcher Teil vom Code den Überblick über einen anderen hat, um herauszufinden, wo mögliche Variablen / Methoden geschrieben werden müssen.

BeispielBei einem Schachspiel sollte der Ort einer Figur auf dem Brett nicht in der Figur gespeichert werden, sondern im Brett.

Creator

Beim Creator geht es darum, dass man entscheiden muss, in welcher Klasse ein neues Objekt der Klasse A kreiert werden soll. Hier sollte für eine Klasse B mindestens einer dieser 4 Fälle zutreffen:

  • Klasse B kann nicht ohne eine Instanz der Klasse A existieren (Komposition)
  • Klasse B haltet eine / mehrere Instanz(en) der Klasse A als Daten
  • Klasse B arbeitet eng mit der Klasse A zusammen
  • Klasse B haltet Initialisierungsdaten der Klasse A

Beispiel: Bei einer Klasse “Kunde” und einer Klasse “Bestellungen” wird der Kunde als “Bestellungsmacher” angesehen, weil eine Bestellung nicht ohne einen Kunden existieren kann (Komposition)

Controller

Eine Controller Klasse verwaltet alle Teile eines spezifischen Use-Cases. Der Controller ist typischerweise der einzige Layer, welches das UI anspricht.

Beispiel: Wenn man Benutzer verwalten will, könnte man eine “UserController” Klasse haben. Dieser Controller würde alle requests bearbeiten, welche mit dem User zu tun haben.

Polymorphismus

Wenn man etwas anhand eines Datentyps entscheiden muss, sollte diese Entscheidung von dem Datentyp verarbeitet werden. Anstatt, dass man eine explizite abzweigung anhand des Datentyps macht, sollte der Datentyp Polymorphistische Operationen einsetzen.

Beispiel: Wenn man eine Superklasse “Shape”mit zwei Subklassen “Triangle” und “Square” hat und man eine Methode schreiben will um die Fläche zu berechnen, dann sollte es nicht einen If-Statement haben, um zu sehen welche Art von “Shape” es ist. Man sollte in den “Triangle” und “Square” Klassen eine “Area()” Methode geben, welche die “Area()” Methode von der “Shape” Superklasse überschreibt. Dann wird die Überprüfung des Datentyps schon durch Polymorphismus verwaltet.