Open Closed Principle

Einführung

Das Open-Closed-Prinzip (Prinzip der Offen- und Verschlossenheit) kurz OCP wird von Bertrand Meyer wie folgt beschrieben:

„Module sollten sowohl offen für Erweiterungen,
als auch verschlossen für Modifikationen sein“.

Dies bedeutet, dass das Verhalten eines Moduls (Klasse, Methode …) erweitert werden kann, ohne den Ursprünglichen Quellcode verändern zu müssen. Die ursprüngliche Version eines Moduls wird demnach nicht mehr bearbeitet sondern das Verhalten in künftigen Versionen lediglich erweitert.

Am Beispiel einer kompilierten Klassenbibliothek würde eine Erweiterung durch eine Ableitung stattfinden. Die ursprüngliche Klasse bleibt dabei für Modifikationen verschlossen. Dadurch werden nötige Anpassungen an allen Klassen, welche die Bibliothek verwenden, verhindert.

Beispiel

In diesem Beispiel wird das OCP anhand von Abstraktion gezeigt:

C#

public class Cat
{
    public enum CatBreeds { Bengal, MaineCoon, ScottishFold  }

    public string GetCatColor(CatBreeds breed)
    {
        switch(breed)
        {
            case CatBreeds.Bengal:
                return "Silver Spotted";
            case CatBreeds.MaineCoon:
                return "Light Brown";
            case CatBreeds.ScottishFold:
                return "Grey";
            default:
                return "Unkown color";
        }
    }        
}

Java

public class Cat {
    public enum CatBreeds { Bengal, MaineCoon, ScottishFold  }

    public String GetCatColor(CatBreeds breed) {
        switch(breed)  {
            case Bengal:
                return "Silver Spotted";
            case MaineCoon:
                return "Light Brown";
            case ScottishFold:
                return "Grey";
            default:
                return "Unkown color";
        }
    }  
}

Die Funktion GetColor der Cat-Klasse gibt für jede übergebene Katzenrasse die zugehörige Farbe zurück. Realisiert wurde dies über eine einfach Switch-Anweisung. Eine recht gängige Lösung für eine solche Aufgabe. Problematisch wird es nun, wenn neue Katzenrassen hinzugefügt werden. Für jede neue Rasse muss ein neuer Fall geprüft werden und durch diese Änderungen an der bestehende Methode wird das OCP missachtet. Eine einzelne Änderung mag nicht viel Arbeit machen, müssen jedoch mehrere Funktionen erweitert werden, bspw. Größe, Lieblingsfutter etc., wird der Arbeitsaufwand steigen und es können leicht einzelne Swicth-Anweisungen übersehen werden was später zu unerwünschtem Verhalten führt.

Um nun dem OCP zu entsprechen wird, statt eine Konkrete Klasse, eine abstrakte Klasse verwendet:

C#

    public abstract class Cat
    {
       public abstract string GetCatColor();
    }

    public class Bengal : Cat
    {
        public override string GetCatColor()
        {
            return "Silver Spotted";
        }
    }

    public class MaineCoon : Cat
    {
        public override string GetCatColor()
        {
            return "Light Brown";
        }
    }

Java

    public abstract class Cat {
       public abstract String GetCatColor();
    }

    public class Bengal extends Cat {
    	@Override
        public String GetCatColor() {
            return "Silver Spotted";
        }
    }

    public class MaineCoon extends Cat {
    	@Override
        public String GetCatColor() {
            return "Light Brown";
        }
    }

Für zukünftige Katzenrassen wir nun einfach die Cat-Klasse erweitert und es sind keine Änderungen an anderer Stelle mehr nötig. Das OCP ist damit angewendet – Basisklasse Cat ist für Veränderungen geschlossen aber für Erweiterungen offen.

C# bietet, neben abstrakten Klassen, auch Interfaces die für denselben Zweck verwendet werden können.

Leave a Reply

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>