Proti vzorci, ki se jim morate izogibati v kodi

Vsak razvijalec želi napisati strukturirano, preprosto načrtovano in lepo komentirano kodo. Obstaja celo nešteto vzorcev oblikovanja, ki nam dajejo jasna pravila, ki jih je treba upoštevati, in okvir, ki ga moramo upoštevati.

Še vedno pa lahko najdemo vzorce v programski opremi, ki je bila napisana nekaj časa ali pa je bila napisana prehitro.

Neškodljiv osnovni kramp za hitro rešitev težave lahko ustvari precedens v vaši bazi kod. Lahko ga kopirate na več krajev in spremenite v vzorec, ki ga morate nasloviti.

Torej, kaj je anti-vzorec?

V programski opremi je anti-pattern izraz, ki opisuje, kako NE reševati ponavljajočih se težav v kodi. Proti vzorci veljajo za slabo programsko zasnovo in so ponavadi neučinkoviti ali nejasni popravki.  

Na splošno lahko dodate tudi "tehnično dolg" - ki je koda, ki jo imajo, da pridejo nazaj in popraviti pravilno kasneje.

Šest proti vzorcev, o katerih bom razpravljal v tem članku, so Špageti zakonik , Zlato kladivo , Sidro čolna , Mrtva koda , Proliferacija kode in Bog predmet .

Špageti zakonik

Špageti zakonik je najbolj znan anti-vzorec. To je koda z malo do nič strukturo.

Nič ni modularno. V naključnih imenikih so posnete naključne datoteke. Celoten tok je težko slediti in je popolnoma zapleten (kot špageti).

Običajno gre za težavo, pri kateri nekdo predhodno ni natančno premislil pretoka svojega programa in je pravkar začel kodirati.

Kaj to naredi?! Ne morem slediti temu

image.png

To ni samo nočna mora vzdrževanja, temveč je skoraj nemogoče dodati novo funkcionalnost.

Nenehno boste lomili stvari, ne boste razumeli obsega sprememb ali podali natančnih ocen svojega dela, saj je nemogoče predvideti nešteto vprašanj, ki se pojavijo pri takšni arheologiji / ugibanju.

Tu lahko preberete več o anti-vzorcu špageti .

Zlati kladivo

"Predvidevam, da je skušnjava, če je edino orodje, ki ga imate, kladivo, da se z vsem ravnate kot z žebljem." Abraham Maslow

Zamislite si scenarij z mano: vaša ekipa razvijalcev je zelo, zelo kompetentna za povsem novo Hammerjevo arhitekturo. Fantastično je delovala pri vseh vaših preteklih sklopih vprašanj. Ste vodilna svetovna ekipa za arhitekturo Hammer.

Zdaj pa se nekako vse konča z uporabo te arhitekture. Vijak z ravno glavo? Kladivo. Phillips vijak z glavo? Kladivo. Potrebuješ imbus ključ? Ne, ne, udari.

Začnete uporabljati arhitekturni pristop, ki ni povsem primeren za tisto, kar potrebujete, a delo konča. Preveč se zanašate na en vzorec in se morate naučiti najboljšega orodja za najboljše delo.

Celoten vaš program bi lahko na koncu dosegel resen hit uspešnosti, ker poskušate kvadrat zabiti v obliko kroga. Veste, da za kodiranje in izvajanje programa, ki uporablja arhitekturo kladiva, traja dvakrat več časa, vendar je to lažje in to je tisto, kar vam ustreza.

Prav tako ni zelo predvidljivo. Različni jeziki imajo skupne rešitve težav, s katerimi se soočajo, in svoje standarde. Vsakega pravila, ki vam je v enem jeziku dobro uspelo, ne morete uporabiti za drugega, brez težav.

V svoji karieri ne zanemarjajte doslednega učenja. Izberite pravi jezik za svojo težavo. Razmislite o arhitekturi in potisnite območje udobja. Raziskujte in preiskujte nova orodja in nove načine za reševanje težav, s katerimi se soočate.

Tu lahko preberete več o anti-vzorcu Golden Hammer .

Sidro čolna

Boat Anchor anti-vzorec, kjer programerji pusti kodo v codebase zato, ker bi jih potrebovali kasneje.

Nekaj ​​so kodirali izven specifikacij in še ni potrebno, vendar so prepričani, da bodo naslednji mesec. Zato je ne želijo izbrisati. Pošljite ga v proizvodnjo in pozneje, ko ga bodo potrebovali, ga bodo lahko hitro pripravili.

Toda to povzroča nočne more vzdrževanja v zbirki kod, ki vsebuje vso zastarelo kodo. Ogromno vprašanje je, da bodo njihovi kolegi težko ugotovili, katera koda je zastarela in ne spreminja toka v primerjavi s kodo, ki to počne.

Predstavljajte si, da imate hiter popravek in obupno poskušate ugotoviti, kaj je odgovorno za pošiljanje podatkov o karticah strank v API za dvig sredstev iz njihove banke. Lahko bi zapravili čas za branje in odpravljanje napak zastarele kode, ne da bi se zavedali, da niti niste na pravem mestu v zbirki kod.

Zadnja težava je, da zastarela koda podaljša vaš čas izdelave in lahko zamenjate delujočo in zastarelo kodo. Lahko bi ga celo nehote začeli "vklopiti" v proizvodnji.

Zdaj lahko verjetno vidite, zakaj se imenuje sidrni čoln proti vzorcu - težko ga je nositi (dodaja tehnični dolg), vendar ne naredi ničesar (povsem dobesedno, koda nima nobenega namena, ne deluje).

Tukaj lahko preberete več o vzorcu sidra za čoln .

Mrtva koda

Ste že kdaj morali pogledati kodo, ki jo je napisal nekdo, ki v vašem podjetju ne dela več? Obstaja funkcija, ki ni videti, kot da bi kaj počela. A kliče se od vsepovsod! Povprašate se in nihče drug ni povsem prepričan, kaj počne, toda vsi so preveč zaskrbljeni, da bi ga izbrisali.

Včasih lahko vidite, kaj počne, vendar kontekst manjka. Lahko preberete in razumete tok, toda zakaj? Videti je, da ne bi več morali doseči te končne točke. Odziv je vedno enak odziv za vsakega različnega uporabnika.

To se običajno opisuje kot anti-vzorec mrtve kode . Ko ne vidite, kaj je "dejanska" koda, ki je potrebna za pretok in uspešno izvajanje vašega programa, v primerjavi s tistim, kar je bilo potrebno šele pred tremi leti in ne zdaj.

Ta poseben vzorec je pogostejši pri dokazovanju koncepta ali raziskovalne kode, ki je končala v proizvodnji.

Enkrat sem na tehničnem srečanju srečal tipa, ki je imel ravno to težavo. Imel je na tone mrtve kode, za katero je vedel, da je mrtva, in veliko, za katere je sumil, da so mrtvi. Toda od vodstva ni mogel dobiti dovoljenja, da bi kdaj odstranil vso mrtvo kodo.

Svoj pristop je označil za opičje testiranje, kjer je začel komentirati in izključevati stvari, da bi ugotovil, kaj je pihalo v proizvodnji. Mogoče malo preveč tvegano!

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.

Tukaj lahko preberete več o vzorcu Boga .

Zaključek

V kateri koli veliki zbirki kod obstaja stalno ravnovesje med upravljanjem tehničnega dolga, zagonom novega razvoja in upravljanjem vrste napak za vaš izdelek.

Upam, da vam je ta članek dal oko za opazovanje, kdaj se spuščate po zajčji luknji proti vzorcu, in nekaj orodij za njegovo čisto rešitev.

Pisem na Twitterju, če ste uživali v tem članku in želite videti več.