IT-Berufe-Podcast

Open Closed Principle (OCP) – Wissenshäppchen #4


Listen Later

Mein viertes Wissenshäppchen hat das Open Closed Principle zum Thema.

Inhalt

Das OCP ist das zweite der SOLID-Prinzipien. Es wurde vor Robert „Uncle Bob“ Martin bereits 1988 von Bertrand Meyer definiert:

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

Ursprünglich ging es darum, durch Vererbung die Anpassung („modification“) bereits bestehender Klassen zu verhindern, indem Subklassen abgeleitet werden, die die vorhandene Funktionalität erweitern („extension“). Heutzutage ist Vererbung aber eher nicht mehr so gerne gesehen, da es eine starke Kopplung an die Basisklasse zur Folge hat, was das Design inflexibel macht. Stattdessen sollte man besser von vornherein Interfaces mit potentiell verschiedenen Implementierungen einsetzen.

Erklärung
  • Bei Änderungen an einem Programm sollen bestehende Komponenten bestenfalls gar nicht angepasst werden müssen, da diese Anpassungen Fehler nach sich ziehen können, die auch das bereits bestehende Verhalten betreffen.
  • Neue Funktionalität wird dem Programm immer durch neue Komponenten hinzugefügt, also z.B. indem neue Klassen oder Methoden ergänzt werden.
  • Fallunterscheidungen auf Basis von Typen (z.B. mit instanceof in Java) oder Enumerations (insb. wenn diese in einem switch verwendet werden) sind oft ein Hinweis auf Verletzung des OCP und sollten durch Polymorphie ersetzt werden.
  • Beispiel
    class Manager
    end
    class Developer
    end
    class Payroll
    def self.calculate_bonus(employee)
    if employee.is_a?(Manager)
    return 1000
    end
    if employee.is_a?(Developer)
    return 500
    end
    end
    end
    puts Payroll.calculate_bonus(Manager.new) # 1000
    puts Payroll.calculate_bonus(Developer.new) #500

    Wenn diese Bonusberechnung um einen neuen Mitarbeitertyp Administrator erweitert werden soll, muss die bestehende Implementierung von calculate_bonus() angepasst werden:

    def self.calculate_bonus(employee)
    if employee.is_a?(Manager)
    return 1000
    end
    if employee.is_a?(Developer)
    return 500
    end
    if employee.is_a?(Administrator)
    return 250
    end
    end

    Stattdessen sollte von Anfang an die Berechnung des Bonuses an die Mitarbeiterklassen delegiert werden.

    class Manager
    def bonus
    1000
    end
    end
    class Developer
    def bonus
    500
    end
    end
    class Payroll
    def self.calculate_bonus(employee)
    employee.bonus
    end
    end
    puts Payroll.calculate_bonus(Manager.new) # 1000
    puts Payroll.calculate_bonus(Developer.new) # 500

    Dadurch ist eine spätere Erweiterung um neue Mitarbeitertypen ohne Anpassung des bisherigen Codes möglich:

    class Administrator
    def bonus
    250
    end
    end
    puts Payroll.calculate_bonus(Administrator.new) # 250

    In dynamisch typisierten Sprachen (wie im Beispiel Ruby) ist das OCP übrigens meist noch einfacher umzusetzen als in statisch typisierten, da durch das Duck-Typing umfangreiche Klassenhierarchien oder Interfaces unnötig werden. Dies sieht man auch im Beispiel oben: Manager und Developer haben keinerlei Beziehung zueinander. Trotzdem funktioniert der Code, da beide Klassen die Methode bonus() anbieten.

    Vorteile
    • Bei Erweiterungen der Funktionalität sinkt die Wahrscheinlichkeit, Fehler in den bereits funktionierenden Code einzubauen.
    • Klassen behalten ihre Aufgabe „ein Leben lang“. Abhängige Klassen können sich darauf verlassen, dass sich die Funktionalität nicht ändert.
    • Erweiterungen sind ggfs. einfacher zu implementieren, da nicht an mehreren Stellen Code angepasst, sondern „nur“ neuer Code geschrieben werden muss.
    • Nachteile
      • Meist ist gar nicht im Voraus bekannt, welche Stellen im Code später einmal erweitert werden müssen. Einfach nur noch mit Abstraktionen zu arbeiten, macht den Code aber schwer verständlich. Außerdem verletzten wir damit das YAGNI-Prinzip.
      • Literaturempfehlungen

        Da Uncle Bob die SOLID-Prinzipien so schön aufgeschrieben hat, kann ich wieder einmal seinen Klassiker Clean Code* empfehlen.

        *

        Links
        • Permalink zu dieser Podcast-Episode
        • RSS-Feed des Podcasts
        • Open Closed Principle
        • ArticleS.UncleBob.PrinciplesOfOod (Artikel von Uncle Bob, Beispiel in C++)
        • Open-Closed-Prinzip – Wikipedia
        • SOLID – Das Open Closed Principle | Informatik Aktuell (ausführliche Diskussion der Nachteile, Beispiel in C#)
        • SOLID Design Principles Explained – The Open/Closed Principle with Code Examples (Beispiel in Java)
        • ...more
          View all episodesView all episodes
          Download on the App Store

          IT-Berufe-PodcastBy Stefan Macke

          • 5
          • 5
          • 5
          • 5
          • 5

          5

          1 ratings


          More shows like IT-Berufe-Podcast

          View all
          Streitkräfte und Strategien by NDR Info

          Streitkräfte und Strategien

          45 Listeners

          Sternengeschichten by Florian Freistetter

          Sternengeschichten

          45 Listeners

          Geschichten aus der Geschichte by Richard Hemmer und Daniel Meßner

          Geschichten aus der Geschichte

          196 Listeners

          c’t uplink - der IT-Podcast aus Nerdistan by c’t Magazin

          c’t uplink - der IT-Podcast aus Nerdistan

          6 Listeners

          MORD AUF EX by Leonie Bartsch & Linn Schütze

          MORD AUF EX

          128 Listeners

          {ungeskriptet} - Gespräche, die dich weiter bringen by Ben Berndt

          {ungeskriptet} - Gespräche, die dich weiter bringen

          23 Listeners