Skip to content

Latest commit

 

History

History
144 lines (111 loc) · 4.64 KB

File metadata and controls

144 lines (111 loc) · 4.64 KB

Single-Responsibility-Prinzip

Zurück


Wesentliche Merkmale

Kategorie: Programmier-Idiom

Ziel / Absicht:

„Eine Klasse sollte nur einen Grund haben, geändert zu werden”.

In anderen Worten:

  • Das Prinzip der „Single Responsibility” legt Wert auf Einfachheit, also „ein Objekt, eine Aufgabe”.

  • Es geht darum, die Funktionalität von Objekten und deren Beziehungskomplexität zu reduzieren.

  • Man hat Sorge dafür zu tragen, dass jedes Objekt eine Verantwortung hat, auch wenn es nicht immer einfach ist, ein komplexes Objekt in kleinere und einfachere Komponenten zu zerlegen.

  • Es geht folglich nicht darum, nur eine Methode in einer Klasse zu haben – es geht darum, eine Klasse für eine Sache verantwortlich zu machen.

Beispiel: Violating the Single Responsibility Principle

01: class Journal
02: {
03: private:
04:     std::string              m_title;
05:     std::vector<std::string> m_entries;
06:     std::size_t              m_count;
07: 
08: public:
09:     Journal(const std::string& title) 
10:         : m_title{ title }, m_count{}
11:     {}
12: 
13:     void addEntry(const std::string& entry) {
14:         m_count++;
15:         std::string text { std::to_string(m_count) + ": " + entry };
16:         m_entries.push_back(text);
17:     }
18: 
19:     const auto& getEntries() const { return m_entries; }
20: 
21:     void save(std::ostream& os) {
22: 
23:         for (const auto& entry : m_entries) {
24:             os << entry << std::endl;
25:         }
26:     }
27: };
  • Das obige C++-Beispiel könnte in Ordnung zu sein, solange es nur eine einzige Domänenklasse gibt, hier die Klasse Journal. Dies ist jedoch in einer realen Anwendung normalerweise eher selten der Fall.
  • Wenn wir beginnen, weitere Domänenklassen wie Book, File usw. hinzuzufügen, ist die Speichermethode save für alle Domänenklassen separat zu implementieren.
  • Das eigentliche Problem entsteht, wenn die Funktionalität für die Datenablage geändert werden soll. Zum Beispiel wäre es denkbar, dass die Daten an Stelle in Dateien in einer Datenbank abgelegt werden sollen. In diesem Fall müsste man jede Domänenklassenimplementierung durchlaufen und den gesamten Code ändern. Eine derartige Vorgehensweise ist nicht empehlenswert!
  • Der Verstoß gegen das Single-Responsibility-Prinzip in diesem Beispiel ist offensichtlich: Die Klasse Journal besitzt zwei Gründe, um geändert zu werden:
    • Änderungen im Zusammenhang mit der Journal-Klasse selbst.
    • Änderungen im Zusammenhang mit der Persistenz (Datenablage) der Journal-Klasse.

Beispiel: Respecting the Single Responsibility Principle

Wir betrachten eine Überarbeitung des letzten Beispiels. Man könnte sie auch unter der Begrifflichkeit „Separation of Concerns” einordnen:

01: class Journal 
02: {
03: private:
04:     std::string              m_title;
05:     std::vector<std::string> m_entries;
06:     std::size_t              m_count;
07: 
08: public:
09:     Journal(const std::string& title)
10:         : m_title{ title }, m_count{}
11:     {}
12: 
13:     void addEntry(const std::string& entry) {
14:         m_count++;
15:         std::string text { std::to_string(m_count) + ": " + entry };
16:         m_entries.push_back(text);
17:     }
18: 
19:     const auto& getTitle() const { return m_title; }
20:     const auto& getEntries() const { return m_entries; }
21: };
22: 
23: struct SavingManager
24: {
25:     static void save(const Journal& journal, std::ostream& os) {
26: 
27:         os << journal.getTitle() << std::endl;
28:         for (const auto& entry : journal.getEntries()) {
29:             os << entry << std::endl;
30:         }
31:     }
32: };
  • Die Klasse Journal kümmert sich jetzt nur um ihre Daten und Funktionen, die mit dem Journal zusammenhängen.
  • Der Aspekt des Sicherns von Journaldaten ist an einer anderen, zentralen Stelle zusammengefasst: Klasse SavingManager.
  • Wenn Änderungen an der Klasse SavingManager notwendig sind, ist ihr gesamter Code an einer Stelle vorhanden.

Vorteile des Single-Responsibility-Prinzips:

  • Expressiveness – Ausdruckskraft
  • Maintainability – Wartbarkeit
  • Reusability – Wiederverwendbarkeit

Conceptual Example:

Quellcode


Literaturhinweise

Die Anregungen zu diesem Beispiel finden Sie in

Single Responsibility Principle in C++

von Vishal Chovatija.


Zurück