Onderhoudbare software: Het S.O.L.I.D. principe

Het S.O.L.I.D. principe is eigenlijk geen op zichzelf staand principe maar een verzameling van principes. Wanneer je deze principes juist hanteert bij het maken van je object georienteerd ontwerp, dan verbeter je de onderhoudbaarheid van je applicatie. Ook wordt het eenvoudiger om je applicatie beter testbaar te maken.

Single Responsibility Principle
Eigenlijk een heel simpel principe, maar wel lastig om goed door te voeren.
De basis: elke class heeft slechts een verantwoordelijkheid. Wanneer een class meer dan één verantwoordelijkheid heeft dan geeft dat problemen wanneer één van deze verantwoordelijkheden wijzigt, de andere verantwoordelijkheden kunnen dan onbedoeld ook wijzigen.
Een veel gelezen zin: 'A class should have one reason to change'

Classes die hier aan lijden zijn makkelijk te herkennen: ze doen te veel, zijn te groot of te complex. Het opsplitsen van een dergelijk class schept veel duidelijkheid en vergroot de onderhoudbaarheid.

Open Closed Principle
Een class moet open staan voor uitbreiding, maar moet gesloten zijn voor wijziging.

Met andere woorden: het gedrag van een class moet kunnen worden uitgebreid door een afgeleide zonder daarvoor bestaande functionaliteit te hoeven wijzigen.

Liskov Substitution Principle
Wanneer je een bepaalde class gebruikt dan moet het ook mogelijk zijn om elke willekeurige afgeleide van deze class te gebruiken, zonder dat je hoeft te weten welke afgeleide het is.

Interface Segregation Principle
Houd interfaces (en abstracte classes) klein en specifiek voor één gebruik. Wanneer een interface te groot wordt, wordt ook vaak het 'Single responsibilty principle' geschonden.

Vaak worden interfaces steeds verder uitgebreid waardoor ze groot en onoverzichtelijk worden. De interfaces bieden dan functionaliteit voor meerdere gebruiken van deze class (en meestal weer een schending van het single responsibilty principe).

Een voorbeeld:
Een class met de naam Document bevat zowel de methods  'LoadFromXml' en 'SaveToXml' als methods 'LoadFromDatabase' en 'SaveToDatabase'. Al deze methods zijn opgenomen in een interface IDocument die door de Document class is geimplementeerd.
Een andere class die deze Document class gebruikt heeft alleen de XML-functionaliteit nodig maar krijgt via IDocument toch alle methods en functionaliteit.

Het zou dus beter zijn om de interface te splitsen in een IXmlDocument en een IDatabaseDocument interface. Hierdoor is er een specifiek interface per gebruik beschikbaar.

Dependency Inversion Principle
Door het toepassen van dit principe zijn creëer je minder afhankelijkheden tussen classes (en dus tussen je applicatielagen) Bij n-tier applicaties is het vaak zo dat elke bovenliggende laag gekoppeld is aan de onderliggende, je kunt deze niet zomaar vervangen.

"High-level modules should not depend on low-level modules. Both should depend on abstractions."

De oplossing hiervoor is redelijk simpel: de bovenliggende laag gebruikt geen concrete classen maar abstracties (abstracte classes of beter: interfaces) De onderliggende laag gebruikt op zijn manier ook een abstractie om een koppeling naar de bovenliggende laag te voorkomen.

Ronald Harmsen

I'm a software developer. When I'm not developing software I'm training & coaching other developers, speaking on a conference or fiddling with some technical stuff.

Arnhem, The Netherlands

Subscribe to Ronald to the cloud

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!