Webinar programmeren c# java php python c++ r nodejs
Programmeer techniek
1. Programmeer technieken in de praktijk
Auteur: R.J.M.Bakker ~ Electro Abi BV 19-5-2014 16:13:00 goede codeer.docx
[ … heeft nog geen opmaak …]
Goede programmeer technieken zijn de kenmerken van een professionele programmeur . Het grootste
deel van de programmering bestaat uit het maken van een groot aantal kleine keuzes om een grotere
groep van problemen op te lossen . Hoe verstandig die keuzes worden gemaakt , hangt grotendeels af
van vaardigheden en expertise van de programmeur .
In dit document wordt een aantal fundamentele programmeer technieken besproken met een paar
practische voorbeelden. De programmeer standaarden zijn er vooral op gericht om de leesbaarheid en
onderhoudbaarheid van de code te verbeteren. Hoewel de besproken programmeer techniek universeel
toepasbaar zijn op de meeste programmeer talen, wordt hier de focus gelegd op PLCOpen programmeer
taal voor de machinebouw, gestandaardiseerd onder IEC 6-1131.
De leesbaarheid van de software code heeft een directe invloed op hoe goed een ontwikkelaar het
software systeem kan begrijpen. Software onderhoudbaarheid verwijst naar hoe makkelijk een software
systeem kan worden aangepast, nieuwe functies kunnen worden toegevoegd , bestaande functies
kunnen worden gewijzigd , bugfixes worden uitgevoerd , of prestaties worden verbeterd . Hoewel
leesbaarheid en onderhoudbaarheid wordt bepaald door vele factoren , zijn goede programmeer
technieken en standaarden hierop van grote invloed.
Een uitgebreide programmeer standaard omvat alle aspecten van het programma code schrijven en ,
hoewel de programmeur het toepassen ervan met beleid moet uitvoeren, moet deze evenwel
consequent worden uitgevoerd . De voltooide programma code moet een geharmoniseerde stijl
weerspiegelen. Het volgen van een programmeer standaard kan alleen haalbaar zijn als dit in de gehele
software project van begin tot einde wordt gevolgd.
Codeer en programmeer technieken omvatten vele facetten van het software ontwikkelings proces en,
hoewel ze meestal geen invloed hebben op de functionaliteit van de applicatie, dragen ze bij aan een
verbeterde begrip van de programma code. Gezien de doelstelling van dit document, worden alle
aspecten van programmering besproken.
De programmeer technieken die hier besproken worden dienen niet om een starre set van programmeer
normen te diceteren. In plaats daarvan zijn ze bedoeld om te dienen als leidraad voor de ontwikkeling
van een codering standaard voor een specifieke software project.
Coderings technieken zijn onder te verdelen in drie secties:
Naamgeving (naming)
Commentaar (comment)
Formats
Architectuur
Naamgeving:
Wellicht een van de meest invloedrijke elementen voor het begrijpen van de logische afloop van een
software applicatie is hoe de verschillende elementen van de software applicatie worden genoemd. Een
2. Programmeer technieken in de praktijk
Auteur: R.J.M.Bakker ~ Electro Abi BV 19-5-2014 16:13:00 goede codeer.docx
naam moet vertellen "wat" in plaats van "hoe." Door het vermijden van namen die de onderliggende
implementatie (die kan veranderen) weergeven, behoud je een zekere abstractie die de complexiteit
vereenvoudigd. Gebruik bijvoorbeeld “LoadLastRecipe” i.p.v. “LoadVariables”
Een basisregel van de naamgeving is dat: bij moeilijkheden bij het bedenken van een zinvolle variabelen
of POU naam, het er op kan wijzen dat je het doel van een item beter moet analyseren. Maak namen
lang genoeg om betekenisvol te zijn, maar kort genoeg om te voorkomen dat ze langdradig worden.
Programmatisch gezien dient een unieke naam alleen om een item te onderscheiden van een andere.
Expressieve namen functioneren als een hulpmiddel voor de menselijke lezer; Daarom is het zinvol om
een naam te bedenken die de menselijke lezer kan begrijpen. Echter, wees er zeker van zijn dat de
gekozen namen in overeenstemming zijn met de regels en normen van de programmeer standaard.
Goede naamgeving regels zijn:
Bouwstenen (POU’s):
Vermijd onbegrijpelijke namen waarbij subjectieve interpretatie mogelijk is, zoals “Analyseer()” voor een
functie, of xxK8 voor een variabele. Dergelijke namen zorgen eerder voor meer dubbelzinnigheid dan
voor abstractie.
Bij Functions (FUN): gebruik het werkwoord-naamwoord methode voor het benoemen van Functions
die een bewerking uitvoeren op een bepaald object, zoals “FT_ReadModulo()” of “FT_ResetErrorList()”.
Functie bouwstenen (FB’s) bevatten doorgaans te veel intrinsieke functionaliteit om te kunnen
weergeven in naamgeving. Tevens worden FB’s geïnstantieerd weergegeven in de programma code.
Gebruik voor de FB juist een korte naamgeving, bijvoorbeeld voor een Axis bouwsteen: “FB_Axis” of
voor een Equipment module: “FB_EqModule”. De instances kunnen dan genoemd worden: “AxisX,
AxisY, AxisZ” resp. “EM_Infeed, EM_Pack, EM_Outfeed”.
Programma bouwstenen (PRG) worden tweeledig gebruikt: Als ‘task-call’ en als ‘single-code’ bouwsteen
(waar geen instantiering nodig/mogelijk is). In het eerste geval dient de PRG als ‘wrapper’ voor overige
applicatie code. Dit dient in een algemene naam te worden weerspiegeld, bijv.: “Main_Robot” en
“Main_Appl”. In de single-code toepassing bevat de PRG meestal een autonoom stuk functionaliteit die
in de naamgeving naar voren moet komen, bijv.: “PG_JobManager” of “PG_PalletConveyor”.
Variabelen:
Variabelen die gebruikt worden bij berekeningen: voeg qualifiers toe aan de naam als achtervoegsel:
(Avg, Sum, Min, Max, Index)
Gebruik logische tegenovergestelde paren in wisselende namen , zoals min / max , begin / einde , en
open / dicht
Geef Boolse variabelen betekenisvolle namen die geen twijfel opwekken:
Onduidelijk: bHand, bHandOpen
Duidelijk: bSelectHandMode, bDoeHandOpen
3. Programmeer technieken in de praktijk
Auteur: R.J.M.Bakker ~ Electro Abi BV 19-5-2014 16:13:00 goede codeer.docx
Bij situatie, gebruik de ‘Is’ toevoeging: ‘bDoosIsAanwezig’
Bij commando, gebruik de ‘Doe’ (Do) toevoeging: ‘ bDoeRobotNaarPickpositie’
Bij ruimtelijk, gebruik de ‘Op’ (On) toevoeging: ‘bRobotOpPickpositie’
Aangezien de meeste namen worden geconstrueerd door het samenvoegen van meerdere woorden aan
elkaar , gebruiken mixed -case opmaak om het lezen te vereenvoudigen, bijv: “NrOfRequestingStations”.
Gebruik ook voor een kortstondige variabele, die kunnen voorkomen in slechts een paar regels code, een
betekenisvolle naam . Gebruik enkel letter variabele namen , zoals i of j , voor korte FOR_TO_NEXT,
WHILE en REPEAT lus indexen.
Gebruik de prefix “g_” om aan te geven dat de variabele als Global_Variable is gedeclareerd. Verder is
het belangrijk een sub-prefix toe te passen die verwijst naar het variabele type. Een bruikbare norm
hiervoor is de “Hongarian Notation” conform de CAA-standaard:
Data type Prefix
BOOL b
BYTE by
WORD w
DWORD dw
LWORD lw
SINT si
USINT usi
INT i
UINT ui
DINT di
UDINT udi
REAL r
LREAL lr
STRING s
WSTRING ws
TIME t
TIME_OF_DAY tod
ENUM e
CONSTANT c
STRUCT st
Pointer p
Array a
Voorbeelden:
bySubIndex :BYTE
g_sFileName :STRING (global)
udiCounter :UDINT
g_astRecipeData : ARRAY[0..19] OF RecipeType (global)
pabyLogData : POINTER TO ARRAY [0..255] OF BYTE
c_uisyncID : UINT (constant)
4. Programmeer technieken in de praktijk
Auteur: R.J.M.Bakker ~ Electro Abi BV 19-5-2014 16:13:00 goede codeer.docx
Een structure is een instance type. De structurenaam moet altijd eindigen met het achtervoegsel:
“…Type”.
Voorbeeld: “RecipeType”, “JobListType”. De declaraties kunnen dan heten: “RecipeSmall,
RecipeMedium, RecipeLarge”, resp.: “astJobList: Array[0..20] OF JobListType”.
Commentaar
Software documentatie bestaat in twee vormen, externe en interne. Externe documentatie is
beschikbaar buiten de programmacode, zoals specificaties, helpbestanden en ontwerpdocumenten.
Interne documentatie is samengesteld uit commentaren die ontwikkelaars schrijven binnen de
programmacode tijdens het programmeren.
Een van de uitdagingen van software documentatie is ervoor te zorgen dat de commentaren worden
bijgehouden en bijgewerkt tijdens het schrijven/ontwikkelen van de programmacode. Hoewel
commentaar in de programmacode geen doel dient tijdens het runnen van de code, is het van
onschatbare waarde voor een ontwikkelaar die een bijzonder ingewikkeld of omslachtig stuk software
moet schrijven.
Goede commentaar technieken zijn:
Zorg voor ruimschoots commentaar in de programma code. Commentaar is zelden teveel, maar meestal
te weinig.
Bij het aanpassen van de code: vergeet niet het commentaar mee aan tepassen.
Bij het begin van een POU is het verstandig een korte omschrijving te geven wat de routine beoogt, met
eventuele aannamens en beperkingen.
Bij end-of-line commentaren; probeer alle commentaren zoveel mogelijk in dezelfde kolom te laten
beginnen, dit oogt een stuk rustiger voor de lezer.
Bij formule berekeningen; maak een end-of-line commentaar met de wiskundige notatie van de
formule. Deze kan eventueel verwijzen naar een formule in een extern document.
Wees spaarzaam of vermijd het gebruik van stippellijnen en asterixen. Gebruik liever lege regels om de
code delen te scheiden en leesbaar te maken.
Vermijd typografische lijnen rond commentaar blokken. Het ziet er in het begin leuk uit, maar het is
moeilijk te onderhouden. Bovendien is het gevoelig voor toepassing van verschillende letter fonts.
Vermijd het toevoegen van programmeur initialen bij wijzigingen in de code. Eventuele andere
programmeurs kunnen er niets mee. Houd liever een ‘changes’ log bij ergens in de applicatie met
toevoeging van revisie datum, auteur en doel van de wijziging.
Zorg voor informatief commentaar wat niet multi-interpretabel is en daardoor meer verwarring schept
dan duidelijkheid. Probeer je te verplaatsen in de “andere” programmeur die weinig of geen voorkennis
heeft omtrent de applicatie software.
Voeg het commentaar meteen toe tijdens het programmeren van de code. Waarschijnlijk is er achteraf
geen tijd meer voor. Bovendien, wat tijdens het programmeren vanzelfsprekend lijkt is het over 6 weken
niet meer.
Vermijd het gebruik van overbodige of ongepaste opmerkingen , zoals humoristische of subjectieve
5. Programmeer technieken in de praktijk
Auteur: R.J.M.Bakker ~ Electro Abi BV 19-5-2014 16:13:00 goede codeer.docx
commentaren.
Bugfixes moeten altijd voorzien worden van commentaar (“Bfix: avoid division by zero”).
Loops en Case-statements altijd voorzien van commentaar betreffende de loop-exit voorwaarde(n).
Hierdoor wordt de programma flow voor een buitenstaander een stuk eenvoudiger.
Programma format:
In CoDeSys worden POU’s gerangschikt in de “devices-tree”. Maak een zo plat mogelijke folder structuur
om de POU’s te rangschikken. De folder structuur weerspiegeld zelden de software architectuur en biedt
dus geen voordelen om de software te begrijpen.
Bij het schrijven van software code; zorg voor een geharmoniseerde stijl met uniforme ‘inspringing’
(indent) en ‘uitlijning’ (alignment), ‘tussenruimtes’ (spacing).
Gebruik bij voorkeur een mono-space lettertype (Courier New).
Gebruik vooral ‘mixed-case’ voor naamgeving beter dan ‘under-scores’ om de leesbaarheid te vergroten
(bDoos_is_aanwezig => bDoosIsAanwezig)
Bij geneste programma-flow directieven (If..Then..Else, Do..While.., Case…) maak gebruik van
inspringingen (indents) om de verschillende loops te onderscheiden.
Bij het schrijven van wiskundige en booleaanse formules : maak intensief gebruik van haakjes (brackets).
Maar gebruik geen haakjes als ze evident overbodig zijn: (IF (bDoosIsAanwezig) THEN).
Vermijd diep-geneste wiskundige notaties. Verpak de berekening dan liever in een aparte functie.
Over het gebruik van al dan niet PRG’s, FB’s of FUN’s kan lang worden gediscussieerd. In tegenstelling
tot andere PLC programmeer systemen biedt CoDeSys veel vrijheid in de keuze. De enige restrictie is dat
FUN’s geen ‘geheugen capaciteit’ hebben en FB’s en PRG’s wel. FB’s moeten evenwel geïnstantieerd
worden, PRG’s niet. De beste leidraad voor een keuze is wellicht:
Gebruik FUN’s voor algoritmische bewerkingen (berekeningen): FT_CyMin_Avg()
Gebruik FB’s voor abstracte programmeer code, die in principe universeel en op meer plaatsen in het
programma gebruikt: FB_Axis, FB_EqModule.
Gebruik PRG’s voor specifieke en unieke programma code: Main_Appl, PG_PalletConveyor
Daarnaast zijn er nog een aantal afwegingen te maken:
Zorg er voor dat FB’s ook abstract zijn en blijven. Dat wil zeggen; NOOIT binnen in de FB programma
code variabelen gebruiken die niet gedeclareerd zijn in de FB zelf (globale variabelen). Wanneer externe
variabelen nodig zijn, deze toewijzen via VARIN-/VAROUT-/VARIN-OUT variabelen, of pointers. Wanneer
er erg veel variabelen data moeten worden uitgewisseld, gebruik dan structure’s om deze in de
‘verpakken’.
Declareer variabelen zoveel mogelijk lokaal in de POU. Vermijd variabelen declaraties in het Global_Var
bereik zoveel mogelijk: een goed geschreven software applicatie bevat een beperkte hoeveelheid
‘Globals’.
6. Programmeer technieken in de praktijk
Auteur: R.J.M.Bakker ~ Electro Abi BV 19-5-2014 16:13:00 goede codeer.docx
Wanneer er in een applicatie erg veel instances van eenzelfde FB moet worden gemaakt (>10), dan levert
dit erg veel routinematige programma code op, immers alle VARIN/OUT/INOUT moeten worden
gecodeerd. Het kan dan zinvol zijn de code te ‘verpakken’ in een FUN in een FOR-TO-STEP-NEXT loop.
Het probleem dat een FUN geen geheugen capaciteit bezit kan worden omzeilt door een ‘data-
structure’ te maken. Het is bekend dat een structure geïnstantieerd moet worden en als zodanig in een
array kan worden verpakt. De array index loopt mee in de FOR-loop. Toegang tot de data-array moet
plaatsvinden met een pointer. Wat men in feite doet is de data scheiden van de code en alleen de data
instantieerd. Een nadeel van deze techniek is dat ‘online-debugging’ niet goed mogelijk is. Bovendien
levert het gebruik van pointers risico’s op bij een ‘online-change’ (door de compiler niet volledig
bijgewerkte adressering).
Architectuur:
Elk goed geschreven stuk applicatie software maakt gebruik van een bepaalde architectuur. Om het
programma overzichtelijk te houden wordt de software vaak opgedeeld in ‘layers’. Hierbij geldt een top-
down benadering, waarbij het abstractie niveau toeneemt bij hogere layers. Een bekende standaard voor
het opzetten van een software model is de S88 batch processing standaard. Hierover is veel literatuur te
vinden op het internet. Een afgeleide hiervan die in de food- and packaging industrie veel gebruikt is het
OMAC Pack-ML model. Dit beschrijft een universeel state-model voor op machine (plant) niveau, wat als
startpunt kan dienen voor het ontwikkelen van een software applicatie. Ook hiervan is rijkelijk informatie
voorhanden op het internet.