Svaki programer želi napisati strukturirani, jednostavno planirani i lijepo komentirani kod. Postoji čak i bezbroj dizajnerskih obrazaca koji nam daju jasna pravila kojih se moramo pridržavati i okvir koji moramo imati na umu.
Ali još uvijek možemo pronaći anti-obrasce u softveru koji je napisan neko vrijeme ili je napisan prebrzo.
Bezopasno osnovno hakiranje za brzo rješavanje problema može stvoriti presedan u vašoj bazi koda. Može se kopirati na više mjesta i pretvoriti u anti-obrazac kojem se trebate obratiti.
Pa, što je anti-obrazac?
U softveru je anti-pattern pojam koji opisuje kako NE rješavati ponavljajuće probleme u kodu. Protu uzorci se smatraju lošim dizajnom softvera i obično su neučinkoviti ili nejasni popravci.
Oni obično također dodati „tehnički dug” - što je kod vas morati vratiti i popraviti ispravno kasnije.
Šest anti-obrazaca o kojima ću raspravljati u ovom članku su Špageti , Zlatni čekić , Sidro za brod , Mrtvi zakonik , Proliferacija koda i Božji objekt .
Kod špageta
Špageti kod je najpoznatiji anti-obrazac. To je kod s malo prema nuli strukturi.
Ništa nije modularno. Postoje slučajne datoteke razbacane u slučajnim direktorijima. Cijeli je tok teško pratiti i potpuno je zapetljan (poput špageta).
Obično se radi o problemu u kojem netko prethodno nije pažljivo razmislio o toku svog programa i već je počeo kodirati.
Što to radi?! Ne mogu ovo slijediti

Ovo nije samo noćna mora za održavanje, već čini nemogućim dodavanje nove funkcionalnosti.
Stalno ćete lomiti stvari, nećete razumjeti opseg vaših promjena ili ćete dati bilo kakve točne procjene za svoj rad, jer je nemoguće predvidjeti bezbroj problema koji se pojavljuju kad radite takvu arheologiju / nagađanja.
Ovdje možete pročitati više o anti-uzorku Spaghetti Code .
Zlatni čekić
"Pretpostavljam da je primamljivo, ako je jedini alat koji imate čekić, prema svemu se ponašati kao da je čavao." Abraham MaslowZamislite scenarij sa mnom: vaš razvojni tim je vrlo, vrlo kompetentan u potpuno novoj Hammer arhitekturi. Djelovao je fantastično za sve vaše prošle probleme. Vi ste vodeći svjetski tim za arhitekturu Hammera.
Ali sada nekako sve uvijek završi koristeći ovu arhitekturu. Vijak s ravnom glavom? Čekić. Vijak s Phillips glavom? Čekić. Treba vam imbus ključ? Ne, ne, čekić.
Počinjete primjenjivati arhitektonski pristup koji ne odgovara baš onome što vam treba, ali obavlja posao. Previše se oslanjate na jedan obrazac i morate naučiti najbolji alat za najbolji posao.
Čitav vaš program mogao bi na kraju dobiti ozbiljan hit izvedbe jer pokušavate kvadrat nabiti u oblik kruga. Znate da je potrebno dvostruko više vremena za kodiranje i izvršavanje programa pomoću arhitekture čekića za ovaj problem, ali to je lakše i ono je što vam odgovara.
Također nije baš predvidljivo. Različiti jezici imaju zajedničke popravke za probleme s kojima se susreću i vlastite standarde. Ne možete primijeniti svako pojedinačno pravilo koje vam je dobro funkcioniralo na jednom jeziku na drugi, bez problema.
Ne zanemarujte stalno učenje u svojoj karijeri. Odaberite pravi jezik za svoj problem. Razmislite o arhitekturi i potisnite svoju zonu udobnosti. Istražite i istražite nove alate i nove načine pristupanja problemima s kojima se suočavate.
Ovdje možete pročitati više o anti-uzorku Golden Hammer .
Sidro za brod
Protiv uzorka Boat Anchor programeri ostavljaju kôd u bazi koda jer će im kasnije zatrebati.
Kodirali su nešto pomalo izvan specifikacije i to još nije potrebno, ali sigurni su da hoće sljedeći mjesec. Dakle, ne žele ga izbrisati. Pošaljite ga u proizvodnju i kasnije kad zatrebaju, mogu ga brzo pokrenuti.
Ali to uzrokuje noćne more održavanja u bazi kodova koja sadrži sav zastarjeli kôd. Ogromno je pitanje u tome što će njihovi kolege teško razraditi koji je kod zastario i ne mijenja protok u odnosu na kod koji to čini.
Imagine you are on a hot fix, and are desperately trying to work out what is responsible for sending customers' card details to the API to withdraw funds from their bank. You could waste time reading and debugging obsolete code, without realising you aren't even in the right place in the codebase.
The final issue is, obsolete code makes your build time longer and you may mix-up working and obsolete code. You could even start to inadvertently "turn it on" in production.
Now you can probably see why it's called the boat anchor anti-pattern – it is heavy to carry (adds technical debt) but doesn't do anything (quite literally, the code serves no purpose, it doesn't work).
You can read more here about the Boat anchor anti-pattern.
Dead code
Have you ever had to look at code written by someone who doesn't work at your company any longer? There's a function that doesn't look like it is doing anything. But it is called from everywhere! You ask around and no-one else is quite sure what it's doing, but everyone's too worried to delete it.
Sometimes you can see what it's doing, but the context is missing. You are able to read and understand the flow, but why? It doesn't look like we need to hit that endpoint anymore. The response is always the same response for every different user.
This is commonly described as the Dead code anti-pattern. When you can't see what is "actual" code necessary to the flow and successful execution of your program, versus what was only needed 3 years ago, and not now.
This particular anti-pattern is more common in proof on concept or research code that ended up in production.
One time at a tech meet up I met a guy who had this exact problem. He had tons of dead code, which he knew was dead, and lots he suspected was dead. But he could not get permission from management to ever remove all the dead code.
He referred to his approach as Monkey testing, where he started to comment out and turn off things to see what blew up in production. Maybe a little too risky!
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.
Ovdje možete pročitati više o anti-uzorku predmeta Bog .
Zaključak
U bilo kojoj velikoj bazi kodova postoji stalna ravnoteža između upravljanja tehničkim dugom, pokretanja novog razvoja i upravljanja redom programskih pogrešaka za vaš proizvod.
Nadam se da vam je ovaj članak dao oko za uočavanje kada se možda spuštate kroz zečju rupu anti-uzorka i neke alate za njegovo čisto rješavanje.
Dijelim svoja pisanja na Twitteru ako ste uživali u ovom članku i želite vidjeti više.