Er is geen database!

 
21 januari 2011

“Do not try to bend the spoon — that’s impossible. Instead, only try to realize the truth: there is no spoon.”

Er kwam ooit eens een vriend naar mij toe, hij zei dat hij een database nodig had. Hij had een database nodig om het voorraadbeheer te automatiseren in zijn metaalbouwbedrijf. Dit gebeurde nog met de hand, en veranderingen in de voorraad werden handmatig bijgehouden op papier. Maar waarom denkt hij een “database” nodig te hebben? Hij bedoelt eerder een applicatie die enkele zaken bijhoudt, en waarvan de state bewaard blijft als de computer uitgezet wordt. Voor een simpele CRUD applicatie is een database inderdaad zeer geschikt, maar wat doe je met complexere scenario’s? Het kan zo zijn dat bijvoorbeeld bepaalde producten niet in een sectie opgeslagen mogen worden, omdat die sectie alleen producten van een bepaald gewicht aankan. Waar specificeer je dergelijke logica? Je zou dat kunnen valideren met een trigger of een stored procedure. Maar je gaat je dan toch afvragen of tabellen, kolommen en SQL de beste middelen zijn om je probleemdomein te beschrijven. Complexe logica schreeuwt om een andere aanpak. Er zijn maar zelden applicaties die alleen maar CRUD doen.

Toch is de datagedreven aanpak zeer populair. Powerusers hebben al enige ervaring met Microsoft Access en Excel, en kunnen snel een datagedreven tooltje in elkaar draaien om hun eigen probleempje op te lossen. Op een HBO opleiding Bedrijfskundige Informatica wordt geen programmeren als vak gegeven, maar wel vakken zoals: “Databases en datamining” en “business intelligence”. Microsoft steekt vervolgens veel tijd in tools om het leven van de “business intelligence expert” makkelijker te maken. Als ontwikkelaar krijg je dus met deze mensen te maken, en ze zullen je een rijp genormaliseerd datamodel voorschotelen zodra je aan een project begint. In grote bureaucratische organisaties lopen ook nog DBA’s (Database administrator) rond die voor de data integriteit moeten zorgen. Zij zijn verantwoordelijk voor het “Datawarehousing” verhaal, en als ontwikkelaar zul je heel netjes moeten vragen of je alsjeblieft een tabel mag benaderen.

Op een gegeven moment ga je je dan afvragen waarom we dan nog bezig zijn met object georiënteerd programmeren, weleens de onderstaande code gezien?

Sterker nog, je ziet het waarschijnlijk heel vaak. Onze applicatie is niks anders dan een wrappertje om de database heen. Onze applicatie haalt data op, presenteert het, voert wat business rules uit, en slaat het weer op. Echte OOP concepten worden niet gebruikt, en onze domein logica is een beetje verspreidt over de applicatie en de database. Ted Neward schrijft in zijn klassieke blogpost “The vietnam of computer science
over de onoverbrugbaarheid van de “Object-Relational Impedence Mismatch”. Een mogelijke oplossing:

Wholehearted acceptance. Developers simply give up on relational storage entirely, and use a storage model that fitsthe way their languages of choice look at the world. Object-storage systems, such as thedb4o project, solve the problem neatly by storing objects directly to disk, eliminating many (but not all) of the aforementioned issues; there is no “second schema”, for example, because the only schema used is that of the object definitions themselves. While many DBAs will faint dead away at the thought, in an increasingly service-oriented world, which eschews the idea ofdirect data access but instead requires all access go through the service gateway thus encapsulating the storage mechanism away from prying eyes, it becomes entirely feasible to imagine developers storing data in a form that’s much easier for them to use, rather than DBAs.

De bovenstaande code overtreedt encapsulatie regels die beschreven zijn in Code Complete van Steve McConnell. En dan doemt de vraag op: Wat willen we encapsuleren? Het is raar dat we objecten gebruiken als data containers, dat is niet waar objecten voor bedoeld zijn. Wat we willen is het encapsuleren van gedrag. Uit dat gedrag komt de nodige data voort. De data is dus een bijkomst, niet het doel. We willen het gedrag van onze applicatie specificeren, en niet de data. Middels methoden kunnen we de intentie weergeven van het gewenste gedrag. Een voorbeeld:

Een datagedreven aanpak:

Deze code geeft niet weer wat we nou werkelijk aan het doen zijn, namelijk een persoon verhuizen. We hebben extra commentaar nodig om onze code duidelijk te maken. Een betere aanpak:

We hebben onze code duidelijk gemaakt door de intentie van de code te expliciet te maken. De methode “Move” encapsuleert het gewenste gedrag. De code is nu zelfdocumenterend. Eveneens dwingen we middels de constructor een bepaalde state af. Een adres kan niet bestaan zonder stad.

Wil dit nou zeggen dat de database helemaal weg moet? Nee! Persistentie kan een eis zijn, maar dat kun je isoleren in het persistentie subsysteem. Daar kun je dus gebruik maken van een database, en eveneens kijken naar performance middels indexen en foreign-keys. Het is nog beter om te kijken naar een object database.

Om gedraggedreven te ontwikkelen zijn er een aantal tools beschikbaar om je gedrag uit te specificeren en te testen: RSpec, Cucumber, SpecFlow en StoryQ. In conclusie, wil ik af van de database? Nee, dat hoeft niet, databases hebben een rol. Maar dat wil niet zeggen dat je applicatie een slaaf is van de database, integendeel. Maak gebruik van de tools die je tot je beschikking hebt op de respectievelijke laag. Gebruik OO concepten om gedrag uit te modelleren en te specificeren, en gebruik de database alleen voor persistentie en indexering.


Werken met ?
Kijk dan bij onze mogelijkheden voor zowel starters als ervaren engineers.


Categorieën: Development