So besagt z.B. das sogenannte Offen-Geschlossen-Prinzip (Open/Closed Principle; OCP), das Software (Klassen, Module, Prozeduren usw.) für Erweiterungen offen und für Modifikationen geschlossen sein sollen. Dieses Ziel erreicht man vor allem durch Abstraktion (z.B.: Einführen von abstrakten (Basis-)Klassen, abstrakte Methoden, Interfaces). So weit, so gut...Abstraktion ist toll...ja, wenn man es damit nicht übertreibt!
In der Praxis erlebe ich immer wieder wie auf Krampf versucht wird, Software für verschiedene, denkbare Anwendungsfälle und Einsatzbereiche quasi "vorzubereiten", obwohl zum Zeitpunkt der Entwicklung dieser Software nur ein konkreter, realer Anwendungsfall vorliegt! Das kann z.B. dadurch passieren, das überambitionierte Entwickler (...dieser Zustand ist bei Software-Entwicklern eigentlich der Normalfall) an einer allgemeineren (generischen) Lösung für ein Problem entwickeln, als es im Anwendungsfall oder in der Spezifikation vorgesehen ist („Man könnte ja vielleicht so etwas später mal gebrauchen…“). Auch kommt es vor, das die Entwicklung einer generischen Lösung durch das Management vorgegeben wird, z.B. die Präparierung einer Software für verschiedene fachliche Domänen oder Einsatzbereiche (Quasi die "eierlegende Wollmilchsau", siehe Bild links), obwohl es für die zu erstellende Software zum Zeitpunkt der Realisierung keinen, oder vielleicht nur einen Auftraggeber/Kunden gibt. Dieses passiert häufig bei einem Wechsel von einer projekt-orientierten zu einer produkt-orientierten Unternehmensstrategie. Der Hintergrund eines solchen Management-Ziels ist klar und von einem betriebswirtschaftlichen Standpunkt aus betrachtet durchaus verständlich: Software-Entwicklung ist aufwändig, teuer und mit Risiken behaftet, und man möchte natürlich nicht immer wieder das Rad neu erfinden.
Um dieses Ziel zu erreichen kommen dann häufig ein sehr hohes Maß an Abstraktion und diverse generische Lösungsansätze zum Einsatz, weil man schon jetzt das beherrschen möchte, was denn da vielleicht irgendwann einmal an Anforderungen an die Software gestellt werden könnte. Diese spekulative Verallgemeinerung verursacht meist einen nicht zu unterschätzenden Overhead in Design und Implementierung der Software. Zudem führt zu viel Abstraktion zu ungewollter Komplexität und verringert die Verständlichkeit, Testbarkeit und Wartbarkeit. Darüber hinaus können derartige Entwürfe auch unerwünschte Nebeneffekte haben, beispielsweise sich ungünstig auf die Performanz der Software auswirken. Ein gutes Negativbeispiel aus dem Bereich der Datenmodellierung sind Modelle, die fast vollständig auf Key-Value-Pairs basieren, d.h. die Datenhaltung - auch in der Persistenzschicht - wird reduziert auf Schlüssel-zu-Wert-Paaren. Eine solche Struktur ist zwar sehr einfach und überaus generisch, auch auf das Wesentliche reduziert, aber mit Sicherheit alles andere als leicht verständlich! Der Vorteil eines guten Datenmodells mit einer sauberen Beziehungssemantik geht hierbei fast vollständig verloren.
Die große Ernüchterung setzt dann ein, wenn das einstmals so sorgfältig und mit viel Zeit- und Geldaufwand ausgedachte, vermeintlich vielseitige, generische und abstrakte Modell mit einem weiteren, konkreten Anwendungsfall konfrontiert wird, und man feststellen muss, dass es doch nicht so gut zu den neuen Anforderungen paßt wie einstmals erhofft. Es ist so wie mit den sprichwörtlichen Außerirdischen: man kann sich darauf vorbereiten, das vielleicht eines Tages Außerirdische auf der Erde landen könnten. Tritt dieser sehr unwahrscheinliche Fall dann tatsächlich ein, so sehen diese Außerirdischen dann vermutlich ganz anders aus, als wie wir sie uns vorgestellt hatten.
Mit der Abstraktion ist es also wie mit so vielem im Leben: zuviel des Guten kann auch hier schädlich sein. Wie aber geht man nun vor? Eine gute Regel ist meines Erachtens die sogenannte Dreier-Heuristik sowie eine Orientierung am KISS-Prinzip. Die Dreier-Heuristik besagt, das man erst beim dritten konkreten Anwendungsfall einer Software selbige nach Gemeinsamkeiten und Unterschieden untersuchen soll, um dann mit Mitteln der Abstraktion Verallgemeinerungen zu schaffen. Das Designprinzip KISS (Keep it simple and stupid) besagt, das zunächst eine einfache und gute Lösung ohne Schnick-Schnack, dafür aber mit einer geringeren Komplexität gewählt werden sollte, da eine solche Lösung meistens als optimal angesehen wird. Wird dieselbe Software mit leicht veränderten Anforderungen auch für andere Auftraggeber in anderen Projekten verwendet, so wird weiterer Code einfach später ergänzt und Abstraktionen ggf. durch Refactorings eingezogen. Durch diese Vorgehensweise wird auch der Tatsache Rechnung getragen, dass der gesamte Software-Entwicklungsprozess ein dynamischer Prozess ist. Begünstigt und erleichtert wird ein solcher Prozess durch ein agiles Vorgehensmodell, wie z.B. SCRUM.




