Strategieën
Contents
Strategieën en Praktijken[edit]
“De praktijken die een software ontwikkelaar leert tijdens het toepassen van programmeer concepten.” Brennan en Resnick (2012)
Leren programmeren bestaat niet alleen uit het leren van programmeer concepten. Niet alleen wat een student leert, maar ook hoe hij zijn kennis toe past is belangrijk.
Strategieën en praktijken zijn de manieren hoe men met software development problemen om kan gaan. Het zijn terugkerende strategieën die los staan van specifieke technieken of programmeertalen. Het is de manier hoe een software developer problemen aan pakt.
Brennan en Resnick (2012) en ook Kong (2019) zien strategieën als een van de dimensies van computational thinking, terwijl Selby en Woolard (2013) dit juist ziet als de kern van comutational thinking.
Hieronder worden verschillende strategieën en praktijken besproken die in de wetenschappelijke literatuur als belangrijk worden gezien bij het leren programmeren en het toepassen van conceptuele kennis (Brennan & Resnick, 2012; Kong, 2019; Selby & Woolard 2013; Waller, 2016; Wing 2006, 2007, 2011; Cuny, Snyder, Wing, 2010; Gouws et al. 2013; Curzon et al., 2014; L’Heureux et al., 2012).
(probleem) Decompositie[edit]
Decompositie is het denken over problemen, algoritmes, artefacten, processen en systemen vanuit de elementen waaruit ze zijn opgebouwd (Curzon et al., 2014). Door problemen op te delen in kleinere stukken, worden taken makkelijker te behappen (Waller, 2016). Dit opdelen heeft niet alleen betrekking op grotere problemen, maar ook op complexe systemen of complexe taken en algoritme (Selby & Woolard 2013).
Oplossingen kunnen zo opgedeeld worden in chunks van functionaliteiten. Deze chunks kunnen in sequensen geplaatst worden, om zo tot de overkoepelende oplossing te komen (Selby & Woolard 2013). Elke chunk of deelfunctionaliteit kan los van het grotere geheel worden begrepen, opgelost en ontwikkeld (Curzon et al., 2014). Door op te delen in kleinere stukjes en deze stukje voor stukje op te lossen, is een software developer adaptief in het aanpakken van zijn probleem. Het ontwerpen van een software development project is geen strak, opeenvolgend proces van eerst een concept identificeren, vervolgens een plan voor het ontwerp ontwikkelen en het ontwerp vervolgens in code implementeren. Het is een adaptief proces, waarbij het plan kan veranderen als reactie op het benaderen van een oplossing in kleine stapjes Brennan en Resnick (2012). Een developer gaat vaak iteratief en incrementeel te werk.
Een aantal voorbeelden van decompositie zijn: • Het identificeren van informatie die nodig is om een probleem op te lossen • Het opdelen in sub-problemen, het identificeren van sub-informatie • Processen, oplossingen, objecten, systemen, abstracties etc. opdelen in stukken • Het begrijpen van de relaties tussen sub-problemen of sub-componenten • Divide & conquer strategieën • Recursieve strategieën
Abstraheren en modelering[edit]
Abstraheren is het versimpelen van problemen of systemen, om het makkelijker te maken om er over te redeneren(Curzon et al., 2014). Abstraheren bestaat voornamelijk uit het verbergen van complexiteit. In software development gaat het zelfs om het denken in verschillende lagen van abstracties (wing 2006), met elke laag het gepaste niveau van detail.
De vaardigheid van het abstraheren zit hem voornamelijk in het kiezen van de juiste details om te verbergen, zodat er geen kritieke informatie verloren gaat (Curzon et al., 2014).
Modulariseren is een vorm van abstraheren, waarbij we kleinere onderdelen bij elkaar verzamelen voor het ontwerpen van oplossingen en voor het oplossen van problemen Brennan en Resnick (2012). Deze strategie richt zich op de manier waarop problemen en oplossingen worden weergegeven. Dit omvat het vermogen om oplossingen elegant uit te drukken, gegevens abstract weer te geven, problemen herformuleren en te werken met de juiste notaties. Het vermogen om abstract te denken en te werken op verschillende abstractieniveaus is een belangrijk onderdeel van programmeren Gouws et al. (2013).
Een aantal voorbeelden van abstraheren zijn: • Het kiezen van een goede representatievorm (UML, PSD, Flowchart etc.) • Kiezen van een manier om artefacten te ontwikkelen (objecten, problemen, processen (sub)problemen) • Complexiteit verminderen door (onnodige)details te verbergen • Verbergen van volledige complexiteit van artefacten als objecten, problemen, processen (sub)problemen (functionele complexiteit verminderen) • Gebruik van data structuren om complexiteit te verminderen • Relaties tussen abstracties begrijpen • Het filteren van informatie tijdens het oplossen van problemen
Algoritmisch denken[edit]
Algoritmisch denken bestaat uit het ontwerpen van expliciete instructies voor het uitvoeren van taken (Selby & Woolard 2013). Hierbij moet nagedacht worden over de expliciete instructies die bij elke stap uitgevoerd moeten worden (Curzon et al., 2014). Het gaat daarbij niet alleen om het vinden van een juiste antwoord, maar vooral weten hoe je tot het antwoord gekomen bent. Belangrijk hierbij is het vermogen om patronen te herkennen en om te werken met repetitieve structuren zoals loops, recursie of functies Gouws et al. (2013).
Voorbeelden van algoritmisch denken zijn: • Het schrijven van instructies die, wanneer ze gevolgd worden in een juiste volgorde (sequenties) het gewenste effect geven • Het schrijven van instructies die gebruik maakt van wiskundige en logische operatoren (operatiors) • Het schrijven van instructies die data opslaat, bewerkt of ophaalt (data structuren) • Het schrijven van instructies die op basis van specifieke voorwaarden een gewenst effect laten zien (conditionals) • Het schrijven van instructies die bepaalde consistente instructies herhalen (loops) • Het schrijven van instructies die delen van zichzelf kopieert of hergebruikt om een gewenst effect te krijgen (recursie) • Het schrijven van instructies die tegelijkertijd door meerdere agents doorlopen kan worden (parallelisme)
Hergebruik en generaliseren[edit]
Voortbouwen op andermans werk is een al lang bestaande praktijk bij het programmeren. Dit is versterkt is door netwerktechnologieën die toegang bieden tot een breed scala aan werk van andere mensen om te hergebruiken. Hergebruik ondersteunt de ontwikkeling van kritische vaardigheden in het lezen van code Brennan en Resnick (2012).
Om andermans werk en eigen werk te kunnen hergebruiken moet men oplossingen kunnen generaliseren. Generaliseren is het snel vinden van nieuwe oplossingen op basis van problemen die al zijn opgelost (Curzon et al., 2014). Een software ontwikkelaar kan een algoritme gebruiken wat een specifiek probleem op lost en deze ombouwen om een heel ander probleem op te lossen. Verder kan men klassen van problemen te herkennen om oplossingen binnen deze klasse te generaliseren Gouws et al. (2013).
Voorbeelden van hergebruik en generaliseren zijn: • Het identificeren van overeenkomsten in problemen, processen, oplossingen of data • Oplossingen aanpassen zodat ze ook werken voor heel andere problemen • Transformeren van ideeën en oplossingen van een probleemgebied naar een ander • Stap voor stap door een algoritme lopen om te beoordelen wat hij doet
Testen, debuggen en evalueren[edit]
Dingen werken zelden (of nooit) zoals gedacht; het is van cruciaal belang voor ontwerpers om strategieën voor te ontwikkelen omgaan met - en anticiperen op - problemen Brennan en Resnick (2012). Het evalueren van de prestaties van een applicatie of algoritme is daarom een belangrijke vaardigheid (Curzon et al., 2014; Selby & Woolard 2013). Algoritme moeten continu worden geëvalueerd op verschillende eigenschappen (bijvoorbeeld: correctheid, snelheid, gebruik van middelen, gemak in gebruik en begrip). Omdat er zelden één ideale oplossing is voor alle situaties zullen er compromissen gesloten moeten worden tussen verschillende mogelijkheden en uitkomsten.
Het ontwikkelen van software is een adaptief proces van continue iteraties en verfijning, waarbij het plan kan veranderen in elke iteratie (Brennan & Resnick, 2012). Continu wordt er gekeken naar het verbeteren van kwaliteit en precisie. Design en implementatie kunnen veranderen naarmate het proces vordert (L’Heureux et al., 2012).
Voorbeelden van testen, debuggen en evalueren zijn: • Het evalueren of een algoritme zijn doel bereikt • Testen en interpreteren van resultaten • Testen of de prestaties van een algoritme voldoende zijn • Vergelijken van verschillende algoritme die hetzelfde doel hebben • Evalueren of een systeem makkelijk in gebruik te nemen is (usability) • Door algoritmes of code lopen om na te gaan wat ze doen (dry run, tracing) • Evalueren of een oplossing aan de specificaties voldoet