Agila utvecklare måste även skriva sin kod på ett agilt sätt för att vara helt agila

”Writing good code is very challenging. Writing good code in an Agile environment is even harder. At least, that’s what it might look like. Because Agile teams have to be economic with their time, so they require strategies that allow them to maintain their flexibility throughout the sprint. Thankfully, many developers have gone before us and there’s a lot we can learn from their experiences”

Översikt över agila principer och strategier för agila team

Inom agilt jobbar man agilt med krav, arkitektur, design och utveckling då det är ett effektivt sätt att jobba på där man iterativ och inkrementellt steg för steg trängre ner djupare i problemet.

Inom agil design kan man på ett tidigt stadium ta fram en konceptuell övergripande arkitektur för en del av systemet som sedan vidareutvecklas, förändras och blir mer färdig allteftersom projektet framskrider och man gör färdigt fler delar.

Agil design även kallat emergent design

”No matter how much design we did on its own, as soon as we began to express it in code, the design needed to change. We expressed it as the code telling us what the design wanted to be.”

Emergent design

Vad gäller konceptet emergent design så innebär det inte att man aldrig ska göra någon design innan man sätter sig ner och börjar implementera för det är inte emergent design utan ad-hoc design (vilket man i.o.f. kan använda de gånger det gäller mindre komplexa system/applikationer som man har bra koll på hur man ska göra).

Med emergent design menas att det inte är någon ide att göra en för detaljerad och omfattande design innan implementeringen påbörjas eftersom man så gott som alltid blir tvungen att ändra på designen i efterhand när verkligheten tränger sig på.

Man gör därför en mer lättviktigt och konceptuell design som ligger på en högre nivå än man t.ex gjorde på den gamla RUP tiden, och sen tar man det del för del.

I vattenfallmetodologin (ex. RUP) försöker man ta fram alla krav för hela systemet så detaljerad som möjligt innan framtagande av arkitekturen påbörjas och gör sedan designen så detaljerad som möjligt för hela systemet innan utvecklingen sätter igång.

Att man sen kanske jobbar inkrementellt och iterativt inom varje fas i vattenfall är inte samma sak som att jobba agilt för agilt är så mycket mer än det.

För att ta klassdiagram som exempel så kan man göra dem med olika detaljnivå från att bara ha boxar med klassnamnen, ev interface och associationerna mellan dem till extremt detaljerade sådana med exakta associationstyperna, alla attribut och metoder för hela systemet på en gång som man sen kan generera skelettkod ifrån.

Inom RUP är det sistnämnda vanligast men inom agilt är det förstnämnda vanligast, för man gör inte designen mer detaljerad än den behöver vara och inte fler diagram än absolut nödvändigt för att ge en tillräckligt bra startpunkt för den del av systemet man kommer börja med, eftersom den ändå skulle behöva förändras under implementeringens gång.

”These strategies are critical for scaling agile software development to meet the real-world needs of modern IT organizations. The Agile approach to design is very different than the traditional approach, and apparently more effective too. It is important to understand:”

  • Agile Design Practices
  • Agile Design Philosophies
  • Design Throughout The Agile Lifecycle

Agile Design

Se ovan artikel för en översiktligt och pedagogisk introduktion till agil design och hur man kan jobba agilt med designen.

Agila arkitekter och agila team

”Alternatively, architects can be embedded in teams, either as a dedicated person #2) or distributed across team members via a shared responsibility #3). What doesn’t work is teams claiming that they are “doing architecture” but no one knows for sure how it’s done #4).”

Agile and Architecture: Friend, not Foe

Visst behövs arkitektur när man utveckla applikationer agilt med, men i hur hög grad beror helt på vilken sorts system man utvecklar.

Den stora skillnaden mot det traditionella sättet är att arkitekten inte äger arkitekturen och toppstyr utvecklarna, utan utvecklar arkitekturen tillsammans med dem som en medlem i teamet om det finns dedicerade arkitekter, och i agil anda allteftersom och inte som en big bang design i klassisk vattenfallsanda.

Sen kan nog en dedicerad arkitekt var medlem i många team samtidigt då design görs löpande i mindre portioner, och i så nära anslutning till implementationen av den delen eller komponenten som möjligt.

Inom agilt jobbar man även iterativt och inkrementell med alla faser parallellt och gör inte mer dokumentation än vad som är nödvändigt för just det projektet (t.ex. styrsystem för kärnkraftverk som är väldigt kritiska kommer kräva mer än ett inmatningsformulär för en konferensanmälan).

Inom agilt kan man t.ex. ta fram en övergripande arkitektur iterativt och inkrementellt, och sedan detaljerade krav i form av user stories och kompletterande umldiagram (baserade på de formella kraven) för en del av systemet, som man sedan sätter igång med samtidigt som man fortsätter ta fram mer detaljerade krav på arkitekturen för nästa del av systemet.

Baserat på input från utveckling, test och user feedback kan sen kraven och arkitekturen förändras ända tills produkten är färdig vilket kanske låter osäkert, men i själva verket är det ett sätt att försäkra sig om att man gör rätt sak på rätt sätt så effektivt som möjligt.

Agil systemutveckling och programmering

Agila team som jobbar enligt t.ex. scrum och jobbar agilt avseende planering, kravhantering, och design, använder TDD och CI/CD kan lätt tro att de jobbar helt agilt, men det går att skriva överkomplicerad kod och göra överkomplicerade arkitekturer även då.

Det många utvecklare missat är att agil utveckling även innebär att man skriver sin kod och lösning på ett så enkelt sätt som möjligt, och inte gör överarbetade och överkomplicerade ”perfekta” lösningar som tar hänsyn till allt som kan behövas i framtiden och använder varenda designmönster och cool finess som finns, eller för den delen motsatsen och gör obegriplig spagettikod.

*Är ni nya inom systemutveckling eller kanske nyexade och i början av er karriär kan ni kan börja med att läsa igenom nedan artikel som går igenom de 22 vanligaste misstagen programmerare gör så ni har grunden klar för er.

The Mistakes I Made As a Beginner Programmer

3 grundprinciper för all systemutveckling och programmering

3 grundprinciper för agil systemutveckling är:

  1. Don’t Repeat Yourself (DRY)
  2. Keep it Simple Stupid (KISS)
  3. You ”Ain’t Gonna Need It (YAGNI)

3 Key Software Principles You Must Understand

DRY principen

Man ska försöka följa DRY principen som först nämndes i den klassiska boken The Pragmatic Programmer.

The DRY Principle Explained: Its Benefit and Cost with Examples

När det gäller DRY principen ska ni vara pragmatiska och inte dogmatiska så det inte blir för mycket av det goda, för lagom är bäst, men i de allra flesta fall är duplicerad kod inte bra.

When to avoid the DRY principle

KISS och YAGNI principerna

En agil utvecklare ska inte heller sub-optimera sin kod in i absurdum och försöka göra bästa möjliga tekniska lösning för alla tänkbara framtida scenarion eller osannolika scenarion med liten risk att inträffa, utan låta tiden utvisa om det verkligen behövs.

Tillkommer nya krav eller omständigheter i framtiden så löser man dem då.

KISS och YAGNI principerna

Din kod ska vara enkel att förstå

”A good developer creates things that are easy to understand so that it’s really easy to shake out all the bugs.”

KISS och YAGNI principerna är ingen ursäkt för att skriva obegriplig spagettikod så din kod ska även vara enkel att förstå och förvalta.

Learn the fundamentals of a good developer mindset in 15 minutes

The Zen of Pythons 20 regler

Tycker även själv The Zen of Pythons 20 regler ger en bra bild av hur man kan skriva enkel kod på ett bra sätt, och ser dem som ett komplement till de tidigare nämnda principerna.

What do different aphorisms in The Zen of Python mean?

When programming in Python, you should…

PEP 20 (The Zen of Python) by example

Sträva inte efter att skriva återanvändningsbar kod

”Code reuse is not a worthwhile goal. Avoiding duplication is a worthwhile goal. Avoiding waste is a worthwhile goal. And you do both of these things by looking out for and eliminating repetition of your labor and of functionality in code. So write the code you need and keep doing that, right up to the point that you start repetitively solving the same problem. Then refactor that solution out into a common place and refer to it. When you do this, you’re not reusing code — you’re reusing valuable functionality.”

Code Reuse is Not a Good Goal

Inom agilt ska man ska inte göra mer än vad som behövs för att lösa problemet just nu med rimlig hänsyn tagen till förvaltningsbarhet, utökningsbarhet och återanvändbarhet.

Återanvändbarhet är däremot oftast svårt att uppnå, så skriv för det specifika fallet och återanvänd det som råkar passa till det enligt råden i artikeln, om det inte är uppenbart att något är återanvändningsbart från början.

Fem huvudprinciper för agil systemutveckling och programmering

Följande artikel tycker jag på ett väldigt bra sätt summerar hur man kan tänka och jobba som agil utvecklare, för det är lika viktigt som att jobba agilt med kraven och den andra sidan av det agila myntet.

De 5 huvudprinciperna för agil systemutveckling är:

  1. Just in Time Design & coding
  2. Think, write, test, refactor
  3. Unit testing
  4. Write Object-Oriented code (OO), not procedural code
  5. Apply Agile Design Patterns and Principles

5 Principles for (Agile) Software Development that improve Agility (and make you a better developer)

Videos om de 5 SOLID principerna och DRY pricipen

Punkt 5 ovan handlar om SOLID principerna och nedan en bra videoserie på YouTube som förklarar de 5 SOLID principerna, och den 6:e och sista videon förklarar DRY principen.

Man kanske inte alltid ska följa alla SOLID principerna fullt ut som punkt 5 handlar om då det tenderar att skapa ett system som innehåller väldigt många små delar som kan bli svåra att överblicka och hantera, och kan vara overkill för mindre system som inte kommer ändras så mycket i framtiden.

Do SOLID design principles make code slow?

Man ska alltså vara pragmatisk och inte dogmatiskt när det gäller SOLID principerna, för det är inte alltid berättigat eller nödvändigt att använda dem alla fullt ut.

Viktigaste principerna att använda inom agil systemutveckling och programmering

Separation Of Concerns principen och Single Responsibility principen (som är S’et i SOLID) är de mest essentiella, så ni kan börja med att använda dem och klassisk OOP och ha det som miniminivå.

Försök även hålla er till composition before inheritance, max två nivåer av arv, god namnsättning och skriv så att koden blir lätt att förstå så följer ni i stort DRY, KISS & YAGNI principerna.

Separation of concerns

Rent praktiskt kan ni åstadkomma separation of concerns genom att designa era applikationer enligt antingen den klassiska N-tier eller N-layer arkitekturen

N-tier data applications overview

Eller MVC arkitekturen som är två olika sätt att åstadkomma det på.

Overview of ASP.NET Core MVC

Best practices för ASP.NET MVC arkitekturer

Genom att även tillämpa best practices för ASP.NET MVC arkitekturer uppnår ni en bra nivå på separation of concerns, single resonsibility principerna och lös koppling även för större system.

ASP.NET MVC Solution Architecture – Best Practices

För mindre applikationer som inte kommer förändras så mycket kan en enklare arkitektur räcka som till exempel det ni får out-of-the-box när ni skapar ett MVC projekt.

I andra fall kanske en microservice arkitektur, domain driven design eller eller ett razor pages projekt som använder den klassiska code behind arkitekturen är bättre, så allt beror på (kom ihåg KISS & YAGNI).

Common web application architectures

Dependency injection i C# och Asp.Net Core

I Asp.Net Core 2.1 och framåt finns redan en dependency injection container inbyggt så ni behöver inte alltid använda Autofac där, men det beror på hur avancerade behov ni har.

.NET Core project without Autofac. Is it viable?

Dependency injection in ASP.NET Core

Ibland behöver man inte använda IoC containar alls utan kan nöja sig med gammal hederlig manuell dependency injection i stället, eller kanske ingen dependency injection alls om applikationen är väldigt enkel eller inte behöver enhetstester.

Dependency Injection in C#

TDD och automatiserade enhetstester

”Whether you’re practicing TDD (Test-Driven Development) or writing your tests after your application code, there’s no doubt that unit testing is essential for web application development. ”

Unit Testing in ASP .NET Core

Sen ska man självklart ha bra tester som kan vara enhetstester, integrationstester eller acceptanstester som ska vara så automatiserade som möjligt.

När det gäller enhetstester finns två skolor.

Den dogmatiska TDD linjen som förespråkar att man alltid ska skriva enhetstester först och testa 100% av koden, och en pragmatisk som anser att man bara behöver testa den viktigaste affärslogiken med enhetstester, och kan skriva enhetstester efter man är klar med den initiala versionen av en metod eller klass och har fått bättre förståelse för problemet.

Hur omfattande tester som behövs beror också på, så även där ska ni tillämpa KISS och YAGNI.

Praktiska exempel på många av principerna

Här en artikel som i kod ger praktiska exempel på många av principerna så ni får en mer handfast förståelse. Kodexemplen är i TYPESCRIPT så det är lätt för er att testa dem själva oavsett vilket som är ert huvudspråk.

How to become a better programmer ?