Uitgangpunten technisch ontwerp
Luteijn Automatisering
(KvK: 60276037, BtwNr: NL062594862B01)
Artikelen over automatisering
Toekomstige softwareontwikkeling, Datamodules, Databaseontwerp, SQL-Server en Hoofdpagina,
Het is een beetje tobben met technische ontwerpen. In de praktijk krijgt de projectleider niet de tijd rustig na te denken over de aanpak van een project. Een goed technisch ontwerp kan enorm schelen in de doorlooptijd. Het naderhand overnieuw moeten bouwen van allerlei functies is jammer. Veel programmeurs proberen de vorige oorlog te winnen. Een probleem is, dat bij de start van het project het functioneel ontwerp vaak nog niet af is. Dat gaande het project allerlei veranderingen van inzichten veelbelovende technische opzetten om zeep helpen. Het is de gouden vraag, hoe je een technisch ontwerp maakt, dat bestand is tegen de wispelturigheid van de klant en dat tevens in staat is echt het werk te doen. Voortdurend zie je na een veelbelovend begin een project stokken op wezenlijke zaken, waarvoor eerder geen tijd was. Wat is een goed en wat is een slecht ontwerp. Dat is een moeilijke vraag. Voor ieder project is het antwoord anders. Toch heb je behoefte aan soort universeel antwoord. Analyse van de factoren, die bepalend zijn voor succes en mislukking is gewenst. Vier belangrijke factoren spelen bij ieder project een rol:
Bewerkelijkheid
Complexiteit
Performance
Onderhoud
Dit zijn termen, die gedeeltelijk functies zij van elkaar. Wanneer je de bewerkelijkheid terugbrengt neemt vaak de complexiteit toe. Performance verbetering is zowel bewerkelijk als complex. Onderhoud is verschrikkelijk moeilijk als de technische oplossingen complex zijn. Complexiteit gaat kwadratisch, terwijl bewerkelijkheid een lineair proces is. Het is altijd schipperen tussen oplossingen, die de bewerkelijkheid terugbrengen, maar de complexiteit opvoeren. Een klein beetje meer complexiteit kan gemakkelijk het voordeel van minder bewerkelijkheid teniet doen. Performance is nooit een keus. Zodra een programma onaanvaardbaar lang gaat doen over een proces, zal je er iets aan moeten doen met als consequentie, dat de complexiteit en bewerkelijkheid omhoog gaat. Sommige ingrepen laten aanvankelijk de complexiteit dalen om vervolgens voorbij een bepaald omslagpunt opeens sterk te stijgen. Businesslogica op de database brengen heeft vaak dat effect. De kunst is om alle kwaden op een zo gunstig mogelijk manier te verenigen tot een zo goed mogelijk resultaat. Een goed programma krijg je nooit zonder inspanning. Bij het minimaliseren van deze inspanning is het belangrijk om goed naar randvoorwaarden te kijken als onderhoud, beschikbare programmeurs en doorlooptijd.
Onderhoud is een cruciale factor. Tijdens het ontwikkelen wil men het vaak niet zien. Het is iets voor de toekomst, voor anderen. Maar in feite begint het onderhoud al als de functie nog maar net gebouwd is. Testen en aanpassen is feitelijk een onderhoudsproces. Vaak is een functie al een maand na dato tien keer over de kop geweest. Vooral primaire processen hebben de neiging onvoorstelbaar veel onderhoud op te roepen. Niemand klaagt over onderhoud, als het gaat om de bestaansreden van het hele project. Desalniettemin kan enorm verdiend worden bij primaire processen door tijdig te anticiperen op deze te verwachten lawine van onderhoud.
Een proces begint meestal als exacte kopie van bestaande werkwijzen of een eerder programma. De extra technische mogelijkheden en moeilijkheden leiden al kort na het realiseren van de eerste opzet tot veranderingen van inzicht. Niet altijd zijn de randvoorwaarden volstrekt helder. De eerste wijzigingen kunnen vaak nog opgevangen worden binnen het eerste ontwerp, maar gaandeweg ontstaat een onontwarbare kluwen. Weerstand bestaat bij de eerste ontwerper en zijn opvolgers om te sleutelen aan de flow. Zelfs als het volstrekt duidelijk zou moeten zijn, dat de gewenste nieuwe inzichten niet zijn te realiseren binnen de bestaande oplossing wordt wanhopig voortgemodderd i.p.v. het verlies te nemen en alles eventjes opnieuw op te zetten. Het helder houden van de flow zou m.i. veel eerder tot herschrijven mogen leiden, dan nu vaak het geval is.
Performance is vaak een vergeten aspect tot het vaak te laat is om er goedkoop en gemakkelijk nog wat aan te doen. De huidige technische ontwerpers hebben vaak het vak geleerd in een tijd, dat record georiënteerde databases algemeen waren. Het is niet gemakkelijk om je los te rukken uit de automatismen, die daar aanleiding toe geven. Tien jaar geleden kwam het objectgeoriënteerde programmeren opeens bovendrijven. Een ontwikkeling was de logica eenmalig in een object te zetten en vervolgens via het object overal in het programma zonder enige inspanning deze ter beschikking te hebben. Dat is leuk als je zestig keer dezelfde browser of onderhoudscherm nodig hebt met telkens net iets andere velden. Maar zodra je echter processen krijgt, die veel data moeten rondschoppen, dan beginnen objecten in samenhang met een SQL database een ernstige bedreiging te vormen voor de performance.
In een recordgeoriënteerde database is een object, dat weet hoe hij informatie moet ophalen uit gerelateerde tabellen een logische ontwerpconstructie. Immers het ophalen van een record duurt altijd even lang. Als je na het ophalen van een hoofdobject nog eventjes tien keer een zoekactie moet doen op andere tabellen om alles compleet te hebben, dan is dat niet anders. Het kan gewoon niet sneller. In een SQL database is een dergelijk werkwijze problematisch. SQL is goed in veel data tegelijk. Een dozijn losse zoekacties zijn uitermate kostbaar. Wanneer je tijdens een proces, wat eigenschappen van een object moet hebben, dan is één grote query met alle gewenste informatie uit meerdere tabellen verre superieur. Dat speelt nog niet zo bij simpele onderhoudschermen. Echter wanneer je van 30000 debiteuren, adres, debetstand en nog wat andere zaken wilt hebben, dan is de objectgeoriënteerde benadering met 30000 maal een dozijn losse queries rampzalig voor de performance.
Object georiënteerd programmeren heeft meer bezwaren in een normale projectorganisatie. Objecten zijn slecht bestand tegen functionele veranderingen van inzicht. Objecten zijn moeilijk in te leren voor andere programmeurs. Het maken van een object is werk voor kunstenaars. Objecten zijn het summum van complexiteit. Pas als de schaal voldoende is, verdient de inspanning zich terug. Men wil zo graag van die prachtige objecten maken, dat men zelfs in situaties, die zich daar totaal niet voor lenen allerlei prachtige base classes begint te maken. Talrijk zijn de mensen, die besloten om inkoop en verkoopfacturen in een wolk van gemeenschappelijke objecten te begraven om aan het einde tot de ontdekking te komen, dat de enige gelijkenis tussen beide primaire processen de 12 letters van de naam zijn en dat een onontwarbare spaghetti is ontstaan. Iedere wijziging in de een dwingt de testafdeling beide processen van onder tot boven door te testen.
Primaire processen en zeker die waarvan je verwachten kunt, dat ze getroffen zullen worden door talrijke veranderingen van inzicht bij de klant, kun je het beste initieel maar zo eenvoudig en plat mogelijk schrijven. Elk primair proces in zijn eigen source. Elke stap van het proces netjes in een eigen functie. Je moet wel van het eerste moment aan de performance denken, maar je moet vooral geen complexe query schrijven als het ook met twee of drie eenvoudiger queries kan. Als je een prachtig "do-all" query hebt geschreven en de eerste verandering van inzicht, moet je weer uren ploeteren om een nieuwe "do-all" query te bakken. In de praktijk moet iemand anders het doen. Hij ziet de gordiaanse knoop. Hij wil in een half uurtje klaar zijn. Dus hij plaatst vlak achter de gordiaanse knoop een eigen functie om de resultaatset aan te passen aan de jongste inzichten.
Ik heb sources gezien, die al een maand na het eerste bouwen voorzien waren van een half dozijn van dit soort patches. Elke keer kwadratisch meer tijd vergend van programmeur en tester, terwijl het eigenlijk gewoon helemaal niet meer doet, wat het doen moet. Uiteindelijk krijgt de projectleider het allemaal op zijn bordje. De een probeert na elke mislukte ingreep de boel weer een beetje overeind te zetten. De ander begint direct driftig te hakken en herschrijft de functie compleet onder het motto slechter kan het niet meer worden. Vanaf het allereerste begin proberen complexiteit binnen te perken te houden, is het geheim om exploderend onderhoud onder controle te houden. Dan maar wat minder mooi. Dan maar wat meer regels source. Als de boel maar toegankelijk blijft voor iedereen binnen het project.