Anti-mønstre, du bør undgå i din kode

Hver udvikler ønsker at skrive struktureret, simpelthen planlagt og pænt kommenteret kode. Der er endda et utal af designmønstre, der giver os klare regler at følge og en ramme, vi skal huske på.

Men vi kan stadig finde antimønstre i software, der blev skrevet et stykke tid eller blev skrevet for hurtigt.

Et harmløst grundlæggende hack for hurtigt at løse et problem kan skabe præcedens i din codebase. Det kan kopieres på tværs af flere steder og blive til et antimønster, du skal adressere.

Så hvad er et antimønster?

I software er anti-mønster et udtryk, der beskriver, hvordan IKKE løser tilbagevendende problemer i din kode. Antimønstre betragtes som dårligt softwaredesign og er normalt ineffektive eller uklare rettelser.  

De tilføjer generelt også "teknisk gæld" - hvilket er kode, du skal komme tilbage og rette ordentligt senere.

De seks antimønstre, jeg vil diskutere i denne artikel, er Spaghetti Code , Golden Hammer , Boat Anchor , Dead Code , Proliferation of Code og God Object .

Spaghetti-kode

Spaghetti Code er det mest kendte antimønster. Det er kode med ringe til nul struktur.

Intet er modulopbygget. Der er tilfældige filer strøet i tilfældige mapper. Hele strømmen er vanskelig at følge og er helt sammenflettet (som spaghetti).

Normalt er dette et problem, hvor nogen ikke på forhånd har tænkt igennem strømmen af ​​deres program og lige er begyndt at kode.

Hvad gør den?! Jeg kan ikke følge dette

image.png

Dette er ikke kun et vedligeholdelsesmareridt, men det gør det næsten umuligt at tilføje ny funktionalitet.

Du vil konstant bryde tingene, ikke forstå omfanget af dine ændringer eller give nogen nøjagtige skøn for dit arbejde, da det er umuligt at forudse de utallige problemer, der dukker op, når du laver sådan arkæologi / gætteri.

Du kan læse mere her om Spaghetti Code anti-mønster.

Golden Hammer

"Jeg formoder, at det er fristende, hvis det eneste værktøj, du har, er en hammer, at behandle alt som om det var et søm." Abraham Maslow

Forestil dig et scenarie med mig: dit team er meget, meget kompetent i den splinternye Hammer-arkitektur. Det har fungeret fantastisk i alle dine tidligere problemer. Du er verdens førende Hammer-arkitekturteam.

Men nu ender en eller anden måde altid med at bruge denne arkitektur. En flad skrue? Hammer. Phillips hovedskrue? Hammer. Har du brug for en unbrakonøgle? Nej det gør du ikke, hammer det.

Du begynder at anvende en arkitektonisk tilgang, der ikke helt passer, hvad du har brug for, men får opgaven. Du er over afhængig af et mønster og har brug for at lære det bedste værktøj til det bedste job.

Hele dit program kan ende med at få et seriøst præstationshit, fordi du prøver at ramme en firkant i en cirkelform. Du ved, at det tager dobbelt så lang tid at kode op og udføre et program ved hjælp af hammerarkitekturen til dette problem, men det er lettere, og det er det, du er fortrolig med.

Det er heller ikke meget forudsigeligt. Forskellige sprog har fælles rettelser til de problemer, de står over for, og deres egne standarder. Du kan ikke anvende hver eneste regel, der fungerede godt for dig på et sprog til det næste uden problemer.

Forsøm ikke konsekvent at lære i din karriere. Vælg det rigtige sprog til dit problem. Tænk over arkitekturen, og skub din komfortzone ud. Undersøg og undersøg nye værktøjer og nye måder at tackle de problemer, du står over for.

Du kan læse mere her om Golden Hammer -antimønsteret.

Bådanker

Den Boat Anker anti-mønster er, hvor programmører forlader kode i kodebase fordi de måske har brug for det senere.

De kodede noget lidt ud af specifikationen, og det er ikke nødvendigt endnu, men de er sikre på, at de gør det i næste måned. Så de vil ikke slette det. Send det til produktion, og senere når de har brug for det, kan de hurtigt få det til at fungere.

Men dette medfører vedligeholdelsesmareridt i kodebasen, der indeholder al den forældede kode. Det enorme problem er, at deres kolleger har svært ved at finde ud af, hvilken kode der er forældet og ikke ændrer strømmen i forhold til den kode, der gør.

Forestil dig, at du er på et hot fix og forsøger desperat at finde ud af, hvad der er ansvarligt for at sende kundernes kortoplysninger til API'en for at trække penge fra deres bank. Du kan spilde tid på at læse og debugge forældet kode uden at indse, at du ikke engang er på det rigtige sted i kodebasen.

Det sidste problem er, forældet kode forlænger din byggetid, og du kan blande arbejdet og forældet kode. Du kan endda begynde at utilsigtet "tænde det" i produktionen.

Nu kan du sandsynligvis se, hvorfor det kaldes bådankerens antimønster - det er tungt at bære (tilføjer teknisk gæld), men gør ikke noget (bogstaveligt talt, koden tjener intet formål, det virker ikke).

Du kan læse mere her om bådankerens antimønster .

Død kode

Har du nogensinde været nødt til at se på kode skrevet af nogen, der ikke længere arbejder i din virksomhed? Der er en funktion, der ikke ser ud som om den gør noget. Men det kaldes fra overalt! Du spørger rundt, og ingen andre er helt sikre på, hvad det laver, men alle er for bekymrede til at slette det.

Nogle gange kan du se, hvad det laver, men konteksten mangler. Du er i stand til at læse og forstå strømmen, men hvorfor? Det ser ikke ud til, at vi længere skal ramme dette slutpunkt. Svaret er altid det samme svar for hver anden bruger.

Dette beskrives almindeligvis som det døde kode -antimønster. Når du ikke kan se, hvad der er "faktisk" kode, der er nødvendig for flowet og en vellykket udførelse af dit program, i forhold til hvad der kun var nødvendigt for 3 år siden, og ikke nu.

Dette særlige antimønster er mere almindeligt i bevis på koncept eller forskningskode, der endte i produktion.

En gang på et teknisk møde mødte jeg en fyr, der havde netop dette problem. Han havde masser af død kode, som han vidste var død, og partier han mistænkte var døde. Men han kunne ikke få tilladelse fra ledelsen til nogensinde at fjerne al den døde kode.

Han henviste til sin tilgang som Monkey-test, hvor han begyndte at kommentere og slukke for ting for at se, hvad der sprang i produktionen. Måske lidt for risikabelt!

If you don't fancy Monkey testing your production app, try to frame technical debt to management as "technical risk" to better explain why you think it's so important to tidy up.

Or even write down everything your particular module/section does you want to re-write, and take an iterative approach to remove piece by piece the dead code. Checking every time you haven't broken anything.

You don't have to drop a huge rewrite with thousands of changes. But you will either understand why it's so crucial and document why it's needed, or delete the dead code as you desired.

You can read more here about the Dead code anti-pattern.

Proliferation of Code

Objects or modules regularly communicate with others. If you have a clean, modularised codebase you often will need to call into other separate modules and call new functions.

The Proliferation of Code anti-pattern is when you have objects in your codebase that only exist to invoke another more important object. Its purpose is only as a middleman.

This adds an unnecessary level of abstraction (adds something that you have to remember) and serves no purpose, other than to confuse people who need to understand the flow and execution of your codebase.

A simple fix here is to just remove it. Move the responsibility of invoking the object you really want to the calling object.

You can read more here about the Proliferation of Code anti-pattern.

God Object

If everywhere in your codebase needs access to one object, it might be a God object.

God objects do too much. They are responsible for the user id, the transaction id, the customer's first and last name, the total sum of the transaction, the item/s the user is purchasing...you get the picture.

It is sometimes called the Swiss Army Knife anti-pattern because you only really need it to cut some twine, but it also can be a nail file, saw, pair of tweezers, scissors, bottle opener and a cork screw too.

In this instance you need to separate out and modularise your code better.

Programmers often compare this problem to asking for a banana, but receiving a gorilla holding a banana. You got what you asked for, but more than what you need.

The SOLID principles explicitly discuss this in object orientated languages, to help us model our software better (if you don't know what the SOLID principles are, you can read this article).

The S in the acronym stands for Single Responsibility - every class/module/function should have responsibility over one part of the system, not multiple.

You can see this problem over and over again, how about the below interface?

interface Animal { numOfLegs: string; weight: number; engine: string; model: string; sound: string; claws: boolean; wingspan: string; customerId: string; } 

Can you see by even just briefly scanning this interface that the responsibility of this is far too broad, and needs refactoring? Whatever implements this has the potential to be a God object.

How about this?

 interface Animal { numOfLegs: string; weight: number; sound: string; claws: boolean; } interface Car { engine: string; model: string; } interface Bird { wingspan: string; } interface Transaction { customerId: string; } 

Interface segregation will keep your code clear about where the responsibilities lie, and stop forcing classes that only need wingspan to also implement the engine, customerId and model  and so on.

Du kan læse mere her om Guds objekt mod mønster.

Konklusion

I enhver stor kodebase er der en konstant balance mellem styring af teknisk gæld, start af nyudvikling og administration af en bugs-kø til dit produkt.

Jeg håber, at denne artikel har givet dig øje med at få øje på, når du måske går ned ad kaninhullet i et antimønster og nogle værktøjer til at løse det rent.

Jeg deler min skrivning på Twitter, hvis du kunne lide denne artikel og vil se mere.