Bij softwareontwikkeling speelt kwaliteit een grote rol. Je kunt dat nog onderscheiden in de kwaliteit van het eindproduct, dus zoals die voor de gebruiker zichtbaar is, en in de kwaliteit van de broncode. Vooral het laatste wil ik in dit artikel belichten.
De meeste programmeurs hebben zo hun eigen manier van werken ontwikkeld in de soms jarenlange ervaring met een ontwikkeltaal als Visual FoxPro.
Maar de vraag is: wat is een kwalitatief goede manier? Dat is een moeilijk te beantwoorden vraag, vooral omdat elk bedrijf of (erger nog) elke programmeur zweert bij de manier waarop zijn of haar code is opgezet. Het zou handig kunnen zijn, als we over de gehele wereld een standaard manier zouden afspreken, zodat elk project dezelfde “look and feel” heeft. Maar zoals je begrijpt, is dat praktisch onmogelijk.
Onder kwaliteit in code versta ik in ieder geval code die dusdanig overzichtelijk is opgezet, dat een andere programmeur dan de maker goed in staat is om de werkzaamheden voort te zetten. Maar behalve voor een andere programmeur doe je zoiets natuurlijk ook voor jezelf. Als je een project enige tijd niet hebt aangeraakt, is het voor jezelf natuurlijk ook erg prettig als de code overzichtelijk is.
Ik zal hier een paar onderwerpen belichten waaraan ik vind dat kwalitatief goede FoxPro code moet voldoen.
Naamgeving (Naming Conventions)
Hoe noem je variabelen, objecten, tabellen, velden, methods, etc. ?
Hierover zijn ongeveer net zoveel meningen als programmeurs, waarbij sommige hun werkwijze als heilig beschouwen. Mijn voorkeur gaat uit naar de afspraken die worden voorgesteld in de help van FoxPro. Deze afspraken worden reeds door heel veel programmeurs gebruikt.
Algemeen geldt:
- Gebruik bij voorkeur één taal (of Engels of Nederlands) .
- Gebruik altijd logische namen. Variabelen als “lnA1” en “lnA2” zijn echt uit den boze!
- Probeer zoveel mogelijk om enkelvoud- en meervoudsnamen niet door elkaar te gebruiken.
- Als een naam een combinatie is van meerdere woorden, begin dan elk woord met een hoofdletter (zogenaamde Camel-case), bijvoorbeeld “cCustomerAddress”. Helaas werkt dat alleen maar in code. FoxPro houdt geen rekening met de caption, waarin je bijvoorbeeld een property of method opslaat.
Variabelen
Als je in de foxhelp naar “naming conventions” zoekt, vind je daar het volgende voorbeeld voor naamgeving van variabelen:
|
Scope |
Description |
Example |
|
L |
Local |
lnCounter |
|
P |
Private (default) |
pnStatus |
|
G |
Public (global) |
gnOldRecno |
|
T |
Parameter |
tnRecNo |
Met andere woorden: begin de naam met de scope van de variabele, gevolgd door het type van de data die je er in wilt opslaan, bijvoorbeeld ‘c’ voor character en ‘n’ voor numeriek, ‘l’ voor logical, etc.
Daarbij raad ik ook aan om variabelen altijd te declareren. Dus ook als ze private zijn, al is dat de default als je ze niet declareert.
Sinds FoxPro 7 is het mogelijk om achter een declaratie het type op te geven, bijvoorbeeld “LOCAL lcName as String”. Dit dwingt echter niet af dat er ook alleen maar strings in deze variabele kunnen worden opgeslagen, m.a.w. FoxPro is niet “strong typing”.
Ik raad aan om variabelen altijd te declareren
Waar je nog een afspraak over kunt maken is: waar zet ik mijn declaraties? Allemaal bovenin je code of pas op de plaats waar je ’t nodig hebt? Mijn voorkeur gaat naar het eerste uit, zodat je in één oogopslag alle declaraties overziet. Het nadeel is dat sommige gedeclareerde variabelen niet gebruikt worden in je code omdat daar bijvoorbeeld een IF / ENDIF omheen staat. Overigens kun je in FoxPro 8 vrij eenvoudig opzoeken waar een variabele gedeclareerd is door de nieuwe “view definition” functie. Deze kun je terugvinden in het context menu van je code window.
Enigszins off topic kan ik je nog aanraden om eens naar de nieuwe intellisence scripts “ZLOC” en “ZDEF” te kijken waarmee je in één keer alle gedeclareerde variabelen of constanten uit je code voorgeschoteld krijgt.
Objecten
Als je een object op bijvoorbeeld een form zet, krijgt deze automatisch de naam van de class met een volgnummer. Ik zou aanraden elk object een logische naam te geven, zeker objecten die je ergens in een stukje code gebruikt.
Aangeraden wordt om voor de eerste drie letters van de naam een prefix te gebruiken die het type object aangeeft, bijvoorbeeld “chk” voor checkbox en “cmd” voor een commandbutton. Zie voor een overzicht van alle prefixes de FoxPro help.
Natuurlijk is het ook verstandig om de classes in je class libraries een logische naam te geven.
Veldnamen
Al een stuk minder programmeurs gebruiken in de veldnamen van tabellen een standaardisering. De FoxPro help raadt wel aan om voor de naam het type van het veld op te geven, bijvoorbeeld “cCustomer”. Wij wijken daar echter iets vanaf door aan het veld een drie letterige prefix van de tabel toe te voegen, dus als je bijvoorbeeld de tabel “customers” hebt, dan zou je bij ons “cus_cCustomer” als veldnaam aantreffen. Het voordeel is dat elke veldnaam uniek is waardoor je bijvoorbeeld in joins met andere tabellen nooit te maken krijgt met dubbele veldnamen die je moet onderscheiden.
Daarnaast kun je overwegen om je sleutelveld altijd “ID” of “PK” te noemen. Afhankelijk van het type en de tabel wordt het bijvoorbeeld: “cus_cpk”
Method en properties
Nog minder dan bij veldnamen het geval is, worden er afspraken gemaakt over het benoemen van methods en properties. Ik zelf gebruik geen speciale naamgeving voor methods, maar er gaan stemmen op om de scope (Protected (p), Public (g) en Hidden (h)) en het type van de return waarde in de methodenaam op te nemen. In het geval van properties wordt veelal het data type als prefix gebruikt, dus bijvoorbeeld “cPassword” of in het geval van een object “oDataservice”.
Documentatie
Documenteren van software, moet dat nu? JA! Nu hebben slechts weinig programmeurs daar zin in, maar als je een professioneel product wilt opleveren, hoort daar nu eenmaal documentatie bij.
Naast eindgebruikersdocumentatie en technische documentatie kun je in FoxPro ook al het één en ander aan documentatie doen. Zo kan (en moet) je commentaar regels toevoegen aan de code; ik heb zelf de gewoonte om elk blokje code van minimaal 1 regel commentaar te voorzien. Naast het feit dat het commentaar zelf een hoop waarde toevoegt, ziet je code er door de (meestal) groene stukjes commentaar al snel overzichtelijker uit. Het lijkt zo een beetje op paragraafjes.
Sinds FoxPro 8 is het overigens ook mogelijk om je source code in kleur uit te printen.
Gebruik ook altijd de description velden van properties, methods en classes om in het kort aan te geven waar deze voor dienen.
Om het documenteren wat te vereenvoudigen zijn er diverse tools beschikbaar die je een stuk werk uit handen nemen, waaronder de documentation wizard van FoxPro zelf.
Maar als je eens naar een hele mooie tool wilt kijken, moet je een blik werpen op de HTML help builder van West-Wind Technologies. Deze kan een gedeelte van je commentaar in de source automatisch omzetten naar een chm (gecompileerde html) file, zodoende bijvoorbeeld een heel mooi stukje documentatie makend van je gehele database.
Waar plaats je de code?
Op de eerste plaats zul je generieke code natuurlijk netjes in class libraries moeten onderbrengen, zodat je een optimale herbruikbaarheid hebt.
Visual Foxpo biedt je de mogelijkheid om bij elk control die op een form of container staat, code te schrijven. Er is niet één grote lap code, zoals dat bijvoorbeeld wel bij Visual Basic het geval is. Om het overzichtelijk te houden raad ik aan om, indien je van plan bent meer dan +/- drie regels code in een event/method van een control te schrijven, een method op het form aan te maken welke je aanroept vanuit het event van de control.
M.a.w. ga niet in het click event van de save button een lap code schrijven, maar schrijf daar slechts thisform.Save() en maak vervolgens je code in de save method op het form zelf.
Als je een composite class maakt, geldt hetzelfde; alleen plaats je dan de code in de container op het hoogste niveau.
Voorkom dat je een event aanroept vanuit een andere method of event
Voorkom zoveel mogelijk dat je een event aanroept vanuit een andere method of event. Als je bijvoorbeeld code in het interactivechange event van een textbox hebt staan, is het sterk af te raden vanuit een andere methode dit event aan te roepen. Dit leidt tot spaghetti. Maak gewoon een method op form niveau aan, welke je vanuit beide plaatsen aanroept.
Raamwerk
Wanneer wij een project beginnen en het ontwerp is klaar, zullen we eerst een raamwerk (framework) opzetten waarin de fundering van de applicatie komt te liggen. Hierbij moet je denken aan een menu-manager, toolbar-manager, form-manager, dataclasses, structurele foutafhandeling, etc.
Je kunt je eigen raamwerk maken, maar er is ook een aantal commerciële FoxPro raamwerken op de markt.
Object Oriëntatie Overwegingen
Over OOP valt heel veel te vertellen en er zijn vele boeken geschreven hoe je zo efficiënt mogelijk van OO gebruik kunt maken. Een aanrader op dit gebied – eentje die eigenlijk iedere programmeur op de plank moet hebben - is het boek “Design Patterns” van Gamma, Helm, Johnson, en Vlissides.
Visual FoxPro blinkt uit in OOP. Als je goed om weet te gaan met OOP, zal dat de kwaliteit van je applicatie absoluut ten goede komen. Er zijn een paar dingetjes die ik in ieder geval in dit artikel kwijt wil.
Maak geen rechtstreeks gebruik van de FoxPro base classes. Maak eerst je eigen class library waarin alle basis controls van Visual FoxPro gesubclassed worden. Gebruik vervolgens deze controls als basis voor al je andere classes. Op deze manier hou je je project zo flexibel mogelijk. Stel bijvoorbeeld dat een klant niet tevreden is over het font dat je in alle textboxen hebt gebruikt? Als je gebruik hebt gemaakt van de FoxPro baseclasses in plaats van je eigen subclass, dan heb je even wat werk om alle textboxes af te lopen en daar het font van te wijzigen.
M.a.w. het geeft je een mogelijkheid om een gewenste standaard te integreren in de “root” van alle classes.
Indien je gebruik maakt van 3rd party classes, bijvoorbeeld een raamwerk als Visual Maxframe, maak dan geen aanpassingen in deze 3rd party classes, maar subclass ze naar je eigen classes en maak daar de aanpassingen. Zo voorkom je dat wanneer - in dit voorbeeld - Visual Maxframe met een update komt, je eigen wijzigingen in het raamwerk verloren gaan.
Probeer overigens je class library overzichtelijk in te delen. Het is aan te raden om het aantal classes per class library klein te houden. Je kunt namelijk niet aan de ene class werken, terwijl een ander aan de andere werkt als beide in dezelfde class library zijn opgeslagen.
Je kunt voor een indeling kiezen waarbij forms in een classlibrary staan en bijvoorbeeld composite classes in een andere. Wat je ook moet voorkomen is dat base classes en custom classes in dezelfde library worden opgeslagen, zodat als je de base classes in een ander project wilt gebruiken, je geen onnodige bagage mee hoeft te nemen.
Met de naamgeving van je class libraries kun je nog rekening houden met het feit dat ze in de projectmanager alfabetisch worden weergegeven, waardoor het handig kan zijn om je base classes met een bepaalde letter of underscore te laten beginnen. Hierdoor blijven ze netjes bij elkaar staan.
Slotwoord
In dit artikel heb ik getracht een paar zaken te belichten die van belang zijn als je kwalitatief goede FoxPro code wilt maken. Ik realiseer me dat niet iedereen het met me/je eens zal zijn, maar gebruik dit artikel dan als discussiestuk, met als doel je software kwalitatief beter te maken.
Daarnaast is dit slechts een druppel op een gloeiende plaat, er zijn nog genoeg onderwerpen onbesproken gebleven. Wie weet in een volgend artikel…