Webblog

Zeven tekenen van rottende software

Zeven tekenen van rottende software

Hopelijk begin je een software ontwikkeling met een redelijk tot goed idee hoe de toekomstige software er uit moet zien. Een helder beeld hebben van de toekomstige software is belangrijk voor jezelf en voor je team. Als je geluk hebt, overleeft dit beeld het tot de eerste release. Maar na verloop van tijd gebeurt er iets, de software begint langzaam maar zeker te ruiken als een stuk bedorven vlees.

Hoewel geen enkele ontwikkelaar dit wil, is het een realiteit die ik maar bij al te veel ontwikkelaars tegenkom. In de loop van de tijd is onder druk van deadlines, wijzigende functionaliteit, wijzigende teamsamenstelling de software langzaam maar zeker steeds ondoorzichtiger geworden. In dit document ga ik in op zeven tekenen van software rot en wat je kunt doen om dit zoveel mogelijk te voorkomen.

Rigiditeit
Rigide software is software die moeilijk aan te passen is. Een op het eerste gezicht simpele aanpassing stuurt resulteert in een cascade van gevolgschade in diverse modules. Hoe meer plekken geraakt worden door aanpassingen, hoe meer rigide het systeem is. Veel ontwikkelaars herkennen hoe een simpele aanpassing een waterval van ellende over ze heen stort waardoor ze steeds meer code moeten aanpassen en de wijziging veel langer duurt dan oorspronkelijk was ingeschat. Als ze dan gevraagd wordt waarom hun inschatting zoveel te laag was, volgt het traditionele antwoord “het was een stuk complexer dan ik had verwacht.”

Breekbaarheid
De breekbaarheid van een systeem wordt bepaald door de kans dat een wijziging op één plek op vele andere plekken onverwachte fouten introduceert. Soms kan het voorkomen dat er fouten optreden op plekken die niet logischerwijs gerelateerd zijn aan de aangebrachte wijziging.

Immobiliteit
Een ontwerp is immobiel wanneer het componenten bevat die voor andere systemen nuttig zouden zijn, maar niet geïsoleerd kunnen worden omdat het risico en de kosten om ze uit het originele systeem te halen gewoonweg te groot zijn.

Viscositeit
Als er een wijziging in software moet worden aangebracht kan dit meestal op meerdere manieren. Sommige manieren zijn in lijn met het ontwerp en de architectuur van de software en andere niet (ook wel hacks genoemd). Een systeem heeft een hoge viscositeit wanneer een aanpassing in lijn met de architectuur meer tijd kost dan een hack. Naast de viscositeit van de software is er ook nog de viscositeit van de ontwikkelomgeving in zijn geheel. Wanneer het uitvoeren van geautomatiseerde tests heel veel tijd kost, is het waarschijnlijk dat de ontwikkelaar een wijziging doorvoert zonder de juiste testen op te zetten.

Nodeloze herhaling
Of ook wel het knippen en plakken van code genoemd. Meestal wordt dit veroorzaakt doordat het systeem niet de juiste abstracties implementeert en niet conform design patterns als SOLID is opgezet. Vaak is het een teken dat er te weinig tijd (of ervaring) binnen een team is om na te denken over architectuur. Wat overblijft, is veelal procedurele code die weliswaar functioneert, maar lastig te onderhouden is.

Duidelijkheid
De duidelijkheid van een module bepaald in hoeverre het eenvoudig is voor een ontwikkelaar om een module te begrijpen. Code die met de tijd doorontwikkeld is, heeft de neiging om steeds minder duidelijk te zijn.

Nodeloze complexiteit
Dit is misschien wel een van de lastigste punten om aan te pakken. Gepassioneerde ontwikkelaars zullen in hun inzet om de overige zes tekenen van software rot te voorkomen, mogelijk in de valkuil van deze zevende stappen. Een goed software ontwerp is lichtgewicht, flexibel, eenvoudig om te begrijpen en bovenal eenvoudig om aan te passen.

Omgaan met rottende software
Helaas is er geen “silver bullet” als het gaat om software rot. Ervaren ontwikkelaars zullen misschien minder snel in valkuilen stappen dan minder ervaren ontwikkelaars, maar uiteindelijk maken we allemaal fouten.

Er zijn wel een aantal zaken die helpen om software rot te voorkomen:

  • Zorg dat de software voldoende afgedekt is door automatische testen
  • Zorg bij iedere wijziging en nieuwe feature voor voldoende tijd om te refactoren
  • Peer review elkaars code
  • Pair program wanneer je een ingewikkeld stuk moet opzetten
  • Zorg voor heldere coding guidelines voor het team
  • Maak architectuurbeslissingen altijd met meerdere ontwikkelaars samen

“Last-but-not-least” zoals een collega van mij vaak mooi weet te zeggen: “perfect is the enemy of good”. Probeer niet de perfecte architectuur te maken, die bestaat niet, en waarschijnlijk wordt je systeem al snel nodeloos complex.

Auteur: Menno Jongerius © 2020 Bergler Competence Center

berglerZeven tekenen van rottende software
Lees meer

Kan Cloud Native On-Premises zijn?

Kan Cloud Native On-Premises zijn?

Nee, dit gaat niet over het On-Premises thuiswerken met behulp van Cloud Diensten in onheilspellende tijden van het Coronavirus. Dit gaat over vraag “kun je Cloud Native zijn met een On Premises serverpark?” Vreemde vraag leek mij. Volgens Wikipedia is Cloud Native een softwareontwikkeling aanpak die maximaal de mogelijkheden van Cloud Computing gebruikt. Dit strookt niet direct met een On Premises aanpak. Vanwaar dan toch deze vraag? Dit is naar aanleiding van het rapport van VMWare “The State of Kubernetes 2020.

Dit is het nieuwste onderzoeksrapport van VMWare onder een aantal grote organisaties naar de status van Kubernetes. Het rapport heeft wat verrassende uitkomsten zoals dat 64% van de ondervraagden Kubernetes On-Premises draaien, wat meer is dan vergelijkbare rapporten. Dit heeft waarschijnlijk te maken met het type organisaties dat VMWare in dit onderzoek heeft ondervraagd. Het zijn namelijk alleen organisatie met 1000 of meer medewerkers. Organisaties van deze omvang hebben wellicht zelf al veel infrastructuur staan, waardoor de switch naar de cloudproviders minder snel van belang is.

Het ligt voor de hand dat in het kader van de bovenstaande uitslag de onderstaande quote in het rapport is opgenomen:

“Cloud native isn’t about where you operate, it’s how you operate.”

(Joe Beda, Principal Engineer, VMware and co-creator of Kubernetes)

Dit is een uitspraak waar ik even van op mijn hoofd moest krabben. Is het zo dat de manier waarop je werkt bepaalt of je cloud native bent en niet de plek? Om dit te kunnen beantwoorden moet ik eerst antwoord hebben op de vraag:

Wat is eigenlijk cloud native?
Als we praten over cloud native dan is de Cloud Native Computing Foundation direct de organisatie waar je aan zult denken. Met de gang naar de cloud is het makkelijker geworden om open source projecten van verschillende bronnen te adopteren, waardoor je organisatie meer kan focussen op business logica en minder op het technische loodgieterswerk. De CNCF heeft als doel om deze open source projecten te beoordelen zodat jij als organisatie enige zekerheid hebt voor de continuïteit en dat je geen vendor lock-in hebt. Dit zijn projecten waarmee je comfortabel de cloud in kunt. Hiervoor heeft het CNCF een overzicht van al hun projecten op 1 plek: https://landscape.cncf.io/.

Het CNCF is de autoriteit op het gebied van cloud native en hebben ook de definitie voor cloud native opgesteld. Vrij vertaald is het ongeveer:
Cloud native technologieën geven organisaties de mogelijkheid om moderne schaalbare applicaties te ontwikkelen en te runnen, in dynamische omgevingen zoals de public, private en hybride clouds. Het gebruik van containers, service meshes, microservices, immutable infrastructuur en declaratieve API’s bevestigen deze aanpak.
Dan terug naar de vraag kan Cloud Native On-Premises zijn. Het antwoord zit hem in de Private Cloud definitie.

Private Cloud (!)= On-Premises
Private clouds kunnen er in vele verschijningsvormen zijn. Zo zijn er private hosted clouds waarbij niet gedeelde dedicated hardware door een cloud provider beschikbaar is gesteld. Of een internal hosted private cloud waarbij de omgeving op de interne infrastructuur van de organisatie geplaatst is. In dit laatste geval kan men spreken van een On-Premises omgeving.
Als men in een dergelijke omgeving gebruik maakt van cloud native projecten zoals door het CNCF worden ondersteund (bijv. Kubernetes) dan kan men spreken over Cloud Native op een On-Premises omgeving.

Wenselijk?
De vraag blijft dan: is het wenselijk om een Cloud Native On-Premise oplossing te ontwikkelen? Dit kan in veel gevallen een prima oplossing zijn. Door geen gebruik te maken van de public cloud kan men b.v. lastige vraagstukken voor legal & compliance ontwijken. Het kan een prima startpunt zijn om met cloud native projecten kennis te maken. Uiteindelijk kan het ook als startpunt functioneren om een hybrid cloud scenario te ontwikkelen.

Het heeft ook een keerzijde, zo ontneem jezelf de mogelijkheid tot het gebruik van managed public cloud diensten. Denk bijvoorbeeld aan AKS, GKE of EKS (managed Kubernetes), Azure SQL of Cosmos DB. Dit zorgt voor meer onderhoud op dergelijke producten of ze kunnen überhaupt niet On Premises worden afgenomen.
Dit zijn overwegingen die moeite waard zijn om te bekijken maar, uiteindelijk is het hebben van een cloud native strategie in een On Premise omgeving prima mogelijk.

Bronnen:
https://k8s.vmware.com
https://www.cncf.io
https://www.capgemini.com
https://github.com

Auteur:
Patrick Bes, Bergler Competence Center © 2020

berglerKan Cloud Native On-Premises zijn?
Lees meer

Threat Modeling

Threat Modeling

In het huidige software ontwikkelingslandschap is het steeds sneller opleveren van software een belangrijk issue. Organisaties moeten mee in de DevOps beweging om hun concurrentiepositie te behouden of te verbeteren. Om dit goed en veilig te kunnen doen is het van belang om zo vroeg mogelijk in het ontwikkelproces al feedback te verzamelen, om snel te kunnen bijsturen. Dit vatten we vaak samen in de zogenaamde Shift Left beweging. Shift Left is een verzameling van kwaliteitsborging methodieken zoals o.a. unittesting, performancetesting & componenttesting.

Naast deze belangrijke testfeedback is ook op het gebied van security een van belang dat men zo vroeg mogelijk een helder beeld heeft van de potentiele security risico’s. De wolf in schaapskleren moet al vroeg worden geïdentificeerd. Hiervoor zijn er al tientallen geleden jaren methodieken bedacht, welke helaas vaak over het hoofd worden gezien. DevOps is een manier om een kortere “time to market” te bewerkstelligen, maar daarnaast ook een lager faalpercentage bij opleveringen. Het beperken van security issues in productie is hier natuurlijk ook onderdeel van. Threat Modeling is bij uitstek een methodiek om bij dit laatste te helpen.

Deze methodiek bestaat uit 5 stappen die zich herhalen binnen de Software Applicatie LifeCycle. Het herhalende karakter past ook prima in het herhalende karakter van DevOps,. Of bij het gebruik van deze methodiek wellicht wel DevSecOps, omdat security nu een prominentere rol krijgt. De stappen die men kan ondernemen zijn:

Define: Vastleggen van de securityeisen.
Niet in elke app zullen de securityeisen gelijk zijn. Indien er met persoonlijke data wordt gewerkt zullen er vast eisen zijn vanuit wetgeving c.q. beleid van uit de organisatie zelf. Zorg ervoor dat deze duidelijk zijn.

Diagram: Het maken van een applicatiediagram
Om inzicht te krijgen in de potentiële dreigingen is het makkelijk om de flow van de betreffende applicatie te modelleren. Dit kan men doen in specifieke Threat modeling tooling zoals bijvoorbeeld Thread Dragon: https://threatdragon.org/login.

Hierin kan men de applicatie weergeven via een eenvoudige Data Flow Diagram bestaande uit Processen, Stores, Actors en/of DataFlows zoals hier weergegeven.

Identity: Het identificeren van de potentiële bedreigingen
Na het opstellen van het diagram kan men met Trust boundaries koppelvlakken aangeven waar men risico’s herkend. Het model kan na deze stap er als volgt uit zien (De groene stippellijnen representeren de Trust Boundaries):

Mitigate: Het mitigeren van de bedreigingen
In 1999 hebben Praerit Garg and Loren Kohnfelder bij Microsoft het STRIDE Model ontwikkeld. Met dit model kan men per trust boundary de specifieke kwetsbaarheden classificeren. STRIDE is een acroniem voor:

Men kan nu per trust boundary inventariseren welke onderdelen van STRIDE hier een bedreiging vormen. In het eerdere voorbeeld kunnen wij aangeven dat Spoofing Identity tussen de browser en webapplicatie een potentieel risico is. Dit risico kan in dit geval bijvoorbeeld gemitigeerd zijn door het gebruik van een signed authenticatie token. Zo kan men alle trust boundaries langs lopen en aan de hand van STRIDE de risico’s inventariseren en bepalen of deze adequaat zijn gemitigeerd.

Validate: Het valideren of alle bedreigingen zijn gemitigeerd
Na het mitigeren van de potentiële bedreigingen is het nog steeds van belang dat men valideert of er toch geen security leaks of kwetsbaarheden in de applicatie zijn geslopen. Het hebben van geautomatiseerde security scans, dependency checks in de pipeline en real time is nog steeds van belang. Daarnaast kunnen er, nu inzichtelijk is waar de potentiele grootste risico’s zitten, abuse cases worden opgesteld. Op basis hiervan kunnen weer specifieke test scenario’s worden bedacht om de gemitigeerde bedreigingen te valideren.

Tot slot
Het kan goed zijn om deze modellering techniek in je DevOps proces op te nemen. Hierdoor kunnen potentiële security leaks al vroegtijdig worden geïdentificeerd en kan hierop worden geacteerd. Het neemt initieel niet veel extra tijd in beslag en kan veel opleveren. Het vergroot in ieder geval de security awareness bij alle betrokkenen en dat is altijd winst.

Auteur: Patrick Bes © Bergler Competence Center 2020

berglerThreat Modeling
Lees meer

Domain Driven Design (DDD) in gewoon Nederlands

Domain Driven Design (DDD) in gewoon Nederlands

Introductie naar Domain Driven Design (DDD)

Als Lead Developer ben ik betrokken bij het opmaken van business cases, uitwerken van ideeën en het implementeren van softwareoplossingen. Een steeds vaker terugkomend thema is dat mijn relaties hun applicatie landschap willen moderniseren zonder opnieuw het wiel te willen uitvinden.

berglerDomain Driven Design (DDD) in gewoon Nederlands
Lees meer

Valkuilen in async/await

Valkuilen in async/await

Het is inmiddels alweer behoorlijk wat jaren geleden dat Microsoft async/await introduceerde in het .NET Framework. Het gebruik van async/await heeft het mogelijk gemaakt om met heel weinig code asynchroon te programmeren. Helaas betekent dit niet dat het eenvoudig is om asynchroon te programmeren, en ik heb mijzelf meermalen in de voet geschoten doordat ik te kort door te bocht wilde gaan. Bij deze wat valkuilen waar ik tegenaan ben gelopen, maar eerst even de twee belangrijkste redenen om asynchroon te programmeren.

Waarom async/await een goede zaak is

Er zijn eigenlijk twee belangrijke redenen om async/await toe te passen. In webapplicaties zal de webserver (afhankelijk van de gekozen technologie) maar een beperkt aantal threads tegelijk in een workerprocess afhandelen. Dit betekent dat bij een groot aantal gelijktijdige verzoeken de webserver processen in de wacht gaat zetten. Door gebruik te maken van async/await, wordt de calling thread van het workerprocess vrijwel direct vrijgegeven, terwijl een background thread de bulk van het werk uitvoert. In client applicaties (Windows en apps) zijn asynchrone processen vooral van belang omdat de UI-thread wordt vrijgegeven en de applicatie dus goed blijft reageren op de gebruiker, terwijl processen op de achtergrond worden afgehandeld. Elke langlopende taak (database, I/O of zware berekening) leent zich om in een asynchrone taak af te handelen.

Valkuil 1: Deadlocks

In het voorbeeld hieronder wordt het resultaat van een taak uitgevraagd. Stel dat dit een asynchrone methode is, die zelf ook gebruik maakt van async/await, dan creëer je een deadlock. Dat komt omdat het aanroepen van Result, de UI-thread in de wacht zet totdat het resultaat van de methode terugkomt. Als de methode zelf een await commando gebruikt, zal deze een thread opstarten en na afloop het werk willen teruggeven aan de UI-thread. Dat kan echter niet omdat deze UI-thread aan het wachten is op het resultaat van de functie die hij nu zelf zou moeten uitvoeren.

Ofschoon dit fenomeen vooral voor zal komen in een Windows applicatie of app, is het niet uit te sluiten dat deadlocks voorkomen in een webapplicatie wanneer je zelf de asynchrone taken beheert en niet gebruik maakt van de asynchrone controllers van ASP.NET.

Oplossing

Zorg dat de methode nadat deze gereed is, wordt opgevolgd door een nieuwe asynchrone taak die het resterende werk uitvoert. In de praktijk is het aan te raden om een class op te zetten die alle uitkomsten van een taak correct afhandelt, want er komt nogal wat bij kijken om alle foutafhandeling en cancellation scenario’s in te bouwen.

Valkuil 2: UI werk op een niet-UI-thread

In het voorbeeld hierboven werd het resultaat van een taak gebruikt in op een label de content te veranderen. Dit gaat fout in Windowsapplicaties en apps wanneer een andere thread dan de UI-thread deze code uitvoert.

Oplossing

Stuur het werk dat naar de UI-thread moet via de Dispatcher naar de UI-thread. Deze is toegankelijk vanaf een window/usercontrol of via het Application object. In de praktijk schijf ik er altijd een proxy met interface voor, zodat ik de code ook kan unittesten.

Valkuil 3: incorrecte/geen foutafhandeling

Binnen een async/await context worden fouten netjes doorgegeven aan de aanroepende thread. Wanneer je aan het einde van de call-chain aankomt, is het heel gemakkelijk om de foutafhandeling te vergeten.

Bovenstaande code zal zonder problemen draaien, maar indien er in de ExecuteAsync een fout plaatsvindt zal deze niet zichtbaar worden in de aanroepende thread. Gebruik om dezelfde reden geen async void (tenzij je zeker weet wat je doet), maar retourneer altijd een taak zodat eventuele fouten afgehandeld kunnen worden. Wanneer je de code aanpast naar ExecuteAsync().Wait() zal er wel een fout optreden, echter dan krijg je weer deadlock problemen.

Oplossing

Schrijf, zoals in een eerder voorbeeld, een juiste continuatie taak waarin eventuele fouten worden afgehandeld.

Schrijf wat er moet gebeuren wanneer er een fout optreedt (bij voorkeur wat charmanter dan MessageBox.Show).

Valkuil 4: await alleen als het nodig is

In het bovenstaande voorbeeld wordt de ReadFileAsync methode aangeroepen. De aanroepende methode zal bij het await keyword een nieuwe thread opstarten om het asynchrone werk op te pakken. De ReadFileAsync methode zal nogmaals een thread opstarten bij het await keyword. Deze laatste is onnodig omdat de waarde van ReadToEndAsync in deze methode niet gebruikt wordt. In dit geval is het beter om geen async/await te gebruiken, maar rechtstreeks een Task te retourneren.

Oplossing

Geef een taak terug zodat er slechts een thread opgestart wordt bij de eerste await. Let wel op dat je in dit geval de boundaries van de code goed in acht neemt. De using statements moeten hier binnen de taak liggen en niet erbuiten anders zijn deze objecten al opgeruimd terwijl de taak nog draait.

Valkuil 5: start niet onnodig threads op

Los van de zaken die in bovenstaande code niet juist zijn, zoals het niet afhandelen van fouten en onhandig aanmaken van de HttpClient, wordt er voor elke parallelle actie nu een extra thread gemaakt voor het uitvoeren van de post. Dat betekent een thread vanuit de task parallel library en een vanuit async/await.

Oplossing

Bij een groot aantal url’s is de beste oplossing om wel de task parallel library te gebruiken, maar hierbinnen de post synchroon te houden. Bij een klein aantal url’s kun je beter een lijst van taken retourneren waar je de code op laat wachten.

Auteur: Menno Jongerius, Bergler Competence Center © 2020

berglerValkuilen in async/await
Lees meer

Stoornissen van teams, impact op de kernwaarden van het Agile gedachtengoed

Stoornissen van teams, impact op de kernwaarden van het Agile gedachtengoed

De Scrum Master van een team houdt zich onder andere bezig met het welzijn en functioneren van het ontwikkelteam. Welke signalen moet je herkennen en waarom zijn deze belangrijk? Mijn ervaring in de rol van Scrum Master gebruik ik om deze vraag via dit blog artikel te beantwoorden.

Patrick Lencioni heeft een boek geschreven over de “5 dysfunctions of a team”. In de stijl van De Phoenix Project beschrijft hij een fictief team in Silicon Valley die onvoldoende presteert. Het boek hanteert de volgende stoornissen in het gedrag van het team:

  • Ontbreken van vertrouwen tussen de teamleden
  • Bang om conflicten aan te gaan
  • Ontbreken van motivatie
  • Ontwijken van verantwoordelijkheid
  • Onvoldoende aandacht voor resultaat

Het is de taak voor de Scrum Master of coach om dit gedrag te herkennen. Daarover gaat dit blog artikel.

Waarom leidt dit gedrag tot het falen van Agile & Scrum toepassingen in organisaties. Veel organisaties komen namelijk in de verleiding om het raamwerk van Scrum en het Agile denken de schuld te geven bij het ontbreken van resultaat. Eigenlijk moet de oorzaak worden gezocht in de basale principes van teamwork en menselijke interacties.

Het agile gedachtengoed is gebaseerd op de volgende principes:

  • Inspectie, de opgeleverde software is altijd de interpretatie van het ontwikkelteam van de verzameling van user story’s. Interpretaties zijn aannames deze moeten altijd worden gevalideerd. Bij softwareprojecten wordt dit gedaan door het testen van de oplevering op verschillende niveaus van detail (unit testen, integratie testen, acceptatie testen, etc.)
  • Aanpassing, het resultaat van de inspectie moet worden toegepast op het product in ontwikkeling. Het gaat hierbij niet alleen om het verhelpen van bevindingen, maar ook over het ontwikkelproces. Veranderen is dus nodig om het product te verbeteren en de snelheid van het beschikbaar krijgen ervan te optimaliseren
  • Transparantie, het ontwikkelteam moet altijd de voortgang van de ontwikkeling kunnen presenteren aan de stakeholders. Hierdoor worden verwachtingen uitgewisseld, verrassingen voorkomen en oplossingen voor leerpunten zichtbaar gemaakt

Het beantwoorden van de vraag waarom stoornissen een bedreiging zijn voor een succesvolle toepassing van agile gedachtengoed doe ik middels de introductie van de “Agile stoornis matrix”.


Tabel 1: Bedreigingen van stoornissen op de pijlers van Agile werken en denken

Het doel van de bovenstaande tabel is om inspiratie te geven voor herkenning van gedrag en gebeurtenissen in het veld en het gevolg daarvan op agile werken en denken. Ongetwijfeld zijn er meer voorbeelden te bedenken. Graag verneem ik de reacties hierop. Ook sta ik open voor constructieve feedback over dit onderwerp en de inhoud van dit artikel.

Bron: The Great Scrum Master by Zuzana Sochova
Bron: The 5 dysfunctions of a team by Patrick Lencioni

Auteur: Arjen Kraak, Bergler Competence Center © 2019

berglerStoornissen van teams, impact op de kernwaarden van het Agile gedachtengoed
Lees meer

Omgaan met & begeleiden van tegenstellingen in Scrum- en culturele waarden

Omgaan met & begeleiden van tegenstellingen in Scrum- en culturele waarden

Agile werkprocessen, in het bijzonder Scrum is tegenwoordig de standaard voor softwareontwikkelteams. Deze aanpak benadrukt menselijke samenwerking en zelfsturing. Zodra de samenstelling van het team bestaat uit leden afkomstig uit verschillende continenten, ontstaat op deze thema’s een tegenstelling van normen en waarden. Dit artikel beschrijft mijn ervaringen over hoe ik hiermee ben omgegaan.

Dit artikel gebruikt de officiële Scrum waarden als leidraad. De ervaringen komen voort uit situaties waarin ik als Scrum Master te maken heb gehad. Het gaat hier vooral om teams met teamleden uit Europa en Azië. De tegenstellingen en hoe hiermee om te gaan richten zich op de culturen van continenten. Als samenvatting van elke waarde geef ik een samenvatting in de vorm van een “goody-bag” statement.

Scrum.Org beschrijft kernwaarden in haar documentatie van het raamwerk. Deze kernwaarden zijn niet alleen van toepassing op Scrum, maar eigenlijk in elke team. Met andere woorden; om teams optimaal te laten presteren zijn deze kernwaarden essentieel.

“Openness”
In gewoon Nederlands, transparantie. Vooral de Scrum Master heeft hier een grote rol. De Scrum Master faciliteert de continue actualiteit van het overzicht van de voortgang en de belemmeringen. Voor teamleden uit het Aziatische werelddeel is dit een uitdaging omdat men niet gewend is openheid van knelpunten te geven. Men voelt dat als een falen in prestatie en verlies van arbeidsethos / eer. Met name het bang zijn te falen komt voort uit een historische “afrekencultuur”. De belangrijke taak van de Scrum Master is om deze cultuur binnen de context van het ontwikkelteam te elimineren. Belemmeringen, ook bugs/fouten, zijn een integraal onderdeel van het programmeren; tijdens de retrospective of andere evaluatie momenten, moet de Scrum Master niet de vraag stellen van “wie heeft….”, maar “wat is de oorzaak?”, “hoe gaan we het oplossen?” en “hoe borgen we de oplossing?” De nadruk op we is met opzet. Het team heeft de kans om te leren van de belemmering.

“Goody-bag item”: stel de vraag “Wat” en “Hoe”. “Wie” is niet interessant

“Respect”
Bij elke menselijke samenwerking, is dit onmisbaar. Komt zeer in de buurt van het verkrijgen van onderling vertrouwen. Europese en vooral Nederlandse cultuur is om recht door zee en direct te zijn. In samenwerking met Aziatische collega’s wordt deze benadering respectloos gevonden. Het is vooral de facilitering van de Scrum Master om deze directe bejegening zeker in aanvang, te voorkomen. Het is beter om 1 op 1 met elkaar van gedachten te wisselen en te appelleren op de kennis en kunde van de collega overzees. Door deze persoonlijke interactie wordt vertrouwen gekweekt die verder uitgebouwd kan worden zodra weer in team verband wordt gewerkt. Het vertrouwen geeft een bijkomstig effect van het hebben van een veilige omgeving om transparant te communiceren in het team. Tijdens plenaire overleggen moeten de West-Europese teamleden zich bewust zijn van het feit dat grappen niet altijd als zodanig worden ervaren. Humor heeft in Azië een wezenlijk andere beleving dan in Europa.

“Goody-bag item”: begin persoonlijke interactie, wissel ervaringen uit. Appeleer aan kennis & kunde

“Courage”
In gewoon Nederlands, moed. Men zou dit in de context van software ontwikkelteams ook kunnen interpreteren als proactief. Zodra “respect” en “openness” zich ontwikkelen, komt deze waarde langzaam tot ontwikkeling. De Aziatische teamleden zullen initiatief nemen om product backlog items op te pakken en voorstellen te doen voor verbeteringen in Retrospectives. Om dit voor elkaar te krijgen moet de Scrum Master de organisatie rondom het team transformeren meer zelf organiserend te worden. Vooral in Aziatische culturen is het gemeengoed, dat de “baas” vertelt wie op welk moment welke taak krijgt toegedicht. Op het moment dat het team de Scrum Master vertelt wat hij moet doen, dan is de Scrum Master succesvol. Dit kan hij doen door vraag te stellen: “welke product backlog items kan je volgende periode oppakken, rekening houdend met de prioriteit?” Ook de vragen als “wat heb je nodig?”, “wat zijn de afhankelijkheden?” zijn van belang. De Scrum Master mag vooral niet in de valkuil trappen van het delegeren van werk. Ook moet hij erop toezien dat de Product Owner niet hierop aanstuurt of beïnvloedt.

“Goody-bag item”: stel faciliterende vragen i.p.v. controlerende vragen. Daag het team uit om naar de Scrum Master te delegeren

“Commitment”
De drang om werk op tijd gereed te krijgen wordt versterkt door de verantwoordelijkheid bij het team te leggen, niet bij het individu. De Scrum Master moet dit faciliteren vooral tijdens de Sprint Planning meeting door het team te bevragen over wat er nodig is om de backlog items tot een goed einde te brengen. De Scrum Master ziet erop toe dat iedereen voldoende bijdraagt in de discussie over inschattingen. Het is van belang dat de van nature terughoudende Aziatische teamleden voldoende aan het woord komen. Het doel is immers dat het discussiëren over een inschatting belangrijker is dan het verkrijgen van de schatting zelf. Tijdens het plannen is het van belang dat de Scrum Master het team stuurt naar verantwoording nemen als team en niet een individu te identificeren die het werk uitvoert.

“Goody-bag item”: delegeer niet het werk. Laat het team het werk verdelen. Inschattingen van het team zijn niet onderhandelbaar. Teamleden moeten hun inschatting toelichten.

“Focus”
Context switchen is een belangrijke oorzaak van verlies van productiviteit en kwaliteit van de opleveringen van de softwareontwikkelaar. Dit heeft dus ook effect op het ontwikkelteam. Het effect van context switchen ontstaat bijvoorbeeld wanneer een teamlid moet wisselen tussen operationele werkzaamheden en vernieuwing. Ook zijn er organisaties waar “alle projecten prioriteit 1 zijn”. Wetenschappelijk bewezen is dat na elke context switch een persoon tijd nodig heeft weer de snelheid en kwaliteit op te pakken die hij had voor de switch. Het onderstaande overzicht geeft het effect weer.

Duidelijk is dat het idee van “alles is belangrijk en moet meteen” niet resulteert in een snellere oplevering. Daarnaast is er een verborgen “waste” van verlies aan kwaliteit. Dit zijn dus bugs die worden geïntroduceerd die herstelwerkzaamheden vergen die als een boemerang later terugkomen.

Context switchen heeft nog een ander ernstig neveneffect. Veel ontwikkelaars vinden dit in het begin van hun carrière interessant en uitdagend. Het geeft hen een gevoel van onmisbaar te zijn. Echter, eerst onbewust, maar sluipend bewust kost context switchen zeer veel energie wat niet zelden leidt tot een burn-out. De Scrum Master moet het proces faciliteren van “stop starting, start finishing”. Dit kan hij doen door bijvoorbeeld te zorgen dat antwoorden worden gegeven op redenen van blokkades. Tijdens 1 op 1 gesprekken, kunnen de Aziatische teamleden worden geholpen bij het formuleren van hun belemmeringen zodat de Scrum Master deze kan adresseren. Tijdens de persoonlijke gesprekken zijn zij over het algemeen opener mits de Scrum Master zich faciliterend en niet controlerend opstelt.

“Goody-bag item”: Stel de vraag “waarom kan dit nu niet worden afgemaakt?”, “waar wacht je op?”. “Waarmee kan ik je helpen”. De Scrum Master moet niet het werk overnemen van het teamlid.

Auteur: Arjen Kraak, Bergler Competence Center © 2019

berglerOmgaan met & begeleiden van tegenstellingen in Scrum- en culturele waarden
Lees meer

Progressive Web Apps

Progressive Web Apps

Met de opkomst van allerlei verschillende apparaten, is het voor aanbieders van applicaties best een uitdaging om te bepalen welke technologie het beste past bij hun applicatie. Sommige organisaties kiezen voor responsive webapplicaties, veelal gebruik makend van een single page framework, anderen kiezen voor native applicaties. Een webapplicatie biedt de mogelijkheid om met één code base te werken en is eenvoudig te onderhouden, maar draait in de sandbox van de browser en is dus gelimiteerd in de mogelijkheden tot wat een browser ondersteunt. Een native app heeft betere performance en kan alle mogelijkheden van het besturingssysteem benutten, maar is lastig te onderhouden en code hergebruiken is slechts gedeeltelijk mogelijk.

Voor organisaties die kiezen voor een webapplicatie, maar toch dichter tegen de beleving van een app willen kruipen, biedt de progressive web app mogelijkheden. Een progressive web app, draait in de browser, maar in de belevenis van de gebruiker wordt deze ‘geïnstalleerd’.

Wat kun je doen met een progressive web app
Een progressive web app biedt alle mogelijkheden van een moderne browser en dat is momenteel behoorlijk veel. Zo kun je gebruik maken van verschillende local storage mechanismes, diverse api’s voor bijvoorbeeld locatie bepaling en push notifications (op dit moment alleen in android en windows). Daarnaast worden de bestanden van een progressive web app lokaal in de browser opgeslagen waardoor de app offline kan draaien.

Wat is nodig voor een progressive web app

Het is belangrijk dat de webapplicatie als één applicatie kan draaien. In de meeste gevallen betekend dit dat het een single page application is die met een API backend communiceert. Daarnaast moet je de volgende zaken inregelen:

  • De webapplicatie moet draaien op een https-domein.
  • De applicatie moet een manifest.json bevatten
  • De applicatie heeft een serviceworker.js waarin het versiebeheer en de lokale opslag van bestanden en bijvoorbeeld push notifications geregeld zijn.

Het manifest is niet veel meer dan een metadatabestand dat de browser vertelt wat voor een applicatie geïnstalleerd wordt:

Om de service worker toe te voegen zijn voor de meeste frameworks packages beschikbaar die een service worker genereren:

Vervolgens stel je de configuratie in van de service worker:

In dit voorbeeld zie je dat de index.html en alle js en css bestanden lokaal opgeslagen worden.

Als laatste definieer je een build waarin de service worker gegenereerd wordt:

Wil je meer weten over service workers en progressive web apps? Google heeft een uitgebreide tutorial beschikbaar: https://developers.google.com/web/ilt/pwa/introduction-to-service-worker

Wanneer gebruik je een native app

  • Wanneer toegang nodig is tot hardware die alleen via native apps toegankelijk is (meer en meer hardware wordt overigens toegankelijk gemaakt voor webapplicaties)
  • Wanneer het voor de gebruikerservaring meerwaarde bied om de app in een store te publiceren (een progressive web app wordt geïnstalleerd via de browser en niet via de store)
  • Wanneer een applicatie een grafisch rijke interface heeft en performance en werking via web een probleem is.

Voor meer informatie en voorbeeldcode in angular kun je kijken op: https://scotch.io/tutorials/how-to-build-progressive-web-apps-with-angular

 

berglerProgressive Web Apps
Lees meer

“Hello Newman…”

“Hello Newman…”

De liefhebbers van Seinfeld weten dan direct waar dit over gaat. De postbode Newman en aartsrivaal van Jerry Seinfeld. In dit geval hebben wij het over Newman de Postman add-on.  Deze add-on is een CLI om Postman collecties te runnen.  Postman is na de opkomst van REST de de-facto standaard voor het testen van je API’s en is in de loop der jaren flink uitgebreid. Newman geeft je dus de mogelijkheid om een collectie aan API’s op de commandline uit te voeren, hiermee kunnen we dan geautomatiseerd Postman script runnen in de CI/CD pipeline. Dit werkt als volgt.

Installeren Newman

Newman is te installeren van uit een npm package:

$ npm install -g newman

De interface is eenvoudig en doeltreffend. Het is mogelijk om naast een collectie ook een specifieke Postman environment mee te geven:

$ newman run .\TestCollection.postman_collection.json -e .\jsonplaceholder.postman_enviroment.json

Deze tool geeft je nu de mogelijkheid om dus ook Postman collections geautomatiseerd in een pipeline te kunnen starten door de integratie met Azure DevOps.

Integratie met Azure DevOps

Er is een specifieke task beschikbaar in Azure DevOps om Newman scripts te kunnen starten. Deze is te vinden op de Visual Studio Marketplace.

Voor men in de release pipeline gebruik kan maken van deze task dient wel eerst Newman op de build agent geïnstalleerd te worden. Dit kan gewoon op dezelfde manier als een lokale install met een custom npm command.

Vervolgens kan men aan deze nieuwe taak de Postman collection en environment meegeven. Let wel dat jUnit als reporter wordt geselecteerd mocht men de resultaten van een Postman test terug willen zien. Geef ook een directory op waar de resultaten van de rest naar toe moeten.

postman collection

De test resultaten van de Postman test kan men dan in Azure DevOps inzien.

postman testresultaten

Het gebruik van Newman CLI in combinatie met Postman is een vrij simpele, lichtgewicht  en doeltreffende oplossing voor het testen van API’s.  Deze zijn ook goed lokaal te bouwen en testen. Daarnaast sluit het ook nog eens goed aan huidige marktstandaard. Al met al een prima oplossing voor het ontwikkelen van een integratietest.

Auteur: Patrick Bes, Bergler Competence Center © 2019

bergler“Hello Newman…”
Lees meer