Objektorientiertes Design - Prinzipien

Es gibt eine Reihe wichtiger Grundprinzipien, die man beim Design von Objektorientierten Programmen beachten sollte.

Zentraler Punkt: Abhängigkeiten minimieren

Object-oriented programming’s most important benefit is that it lets us reduce software complexity by managing code interdependencies.
(Herb Sutter, Exceptional C++)


In der Literatur werden die wichtigen Designprinzipien mit mehr oder weniger griffigen Akronymen aufgeführt ... ein kurzer Überblick:

KISS
Keep It Simple, Stupid
Allgemeines Grundprinzip, Programmieren, insbesondere in C++, ist schon schwierig genug.
DRY
Don't Repeat Yourself
Komponenten sollten eindeutig und klar erkennbar genau einmal vorhanden sein. Keine mehrfachen, leicht unterschiedlichen Variationen
Gegensatz = WET - Write Everything Twice


SOLID
Akronym aus Akronymen
SRP
Single Responsibilty Principle Klasse soll genau eine wohl-definierte Aufgabe haben.
OCP
Open-Closed Principle Offen für Erweiterung, geschlossen für Veränderung
LSP
Liskov Substitution Principle Wenn Programm mit Objekt einer Basisklasse funktionert sollte es auch genauso mit Objekt einer davon abgeleiteten Klasse funktionieren (aber nicht umgekehrt)
ISP
Interface Segregation Principle Besser klein-teilige Interface Klassen als große General-Purpose Interface Klassen
DIP
Dependency Inversion Principle Software Komponenten sollten von Interfaces abhängen, nicht von konkreten Implemntierungen.


SRP - Single Responsibilty Principle
Klasse soll genau eine wohl-definierte Aufgabe haben.

Beispiel wie man's nicht machen soll:


class Circle {
private:
  Position p;
  double radius;
  Color c;
  FillArea f;
public:
  double getArea();
  double getCirumference();
  double move(Position np);
  // ...
  void setColor(Color nc);
  void setFillArea(FillArea fa);
  void draw();
  //..
}

Klasse Circle ist zuständig sowohl für geometrische Daten und Methoden (Position, Radius, Fläche) als auch für die Darstellung (Color, draw(), ...)
\bgroup\color{green}\ensuremath{\Rightarrow}\egroup getrennte Klassen

Siehe auch Beispiel copy Funktion.


LSP - Liskov Substitution Principle
Verhalten von Objekten aus abgeleiteten Klassen muss konsistent mit Verhalten von Objekt aus Basisklasse sein, d.h. überall wo Basisklassenobjekt verwendet wird kann genauso auch abgeleitetes Objekt verwendet werden.

Siehe Beispiel Rechteck vs Quadrat


DIP - Dependency Inversion Principle

Wieder Minimierung von Abhängigkeiten:
Anwendungscode soll möglichst vermeiden direkt konkrete Klassen/Funktionen von externen Tools zu rufen, sonst extreme Abhängigkeit zwischen Anwendung und Tools-Lib.

  1. Adapterklasse/funktion dazwischen schalten \bgroup\color{green}\ensuremath{\Rightarrow}\egroup Abhängigkeiten in dieser Klasse konzentriert
  2. Weiteren Interface-Layer \bgroup\color{green}\ensuremath{\Rightarrow}\egroup Anwendungscode kennt/nutzt nur Interface, Adapterklasse implementiert Interface. Damit keine direkte Abhängigkeit mehr zwischen Anwendungscode und Tools-Lib.
  3. Damit vglw. einfach auf alternative Tools-Lib umzustellen, nur ensprechende Adapterklasse nötig.


Image DIP1

Image DIP2

Image DIP3

Image DIP4


GDuckeck 2019-08-01