Anti-modelli da evitare nel codice

Ogni sviluppatore desidera scrivere codice strutturato, pianificato in modo semplice e ben commentato. Esistono persino una miriade di modelli di progettazione che ci danno regole chiare da seguire e un quadro da tenere a mente.

Ma possiamo ancora trovare anti-pattern nel software che è stato scritto un po 'di tempo fa, o è stato scritto troppo velocemente.

Un innocuo trucco di base per risolvere rapidamente un problema può creare un precedente nel codice base. Può essere copiato in più posizioni e trasformarsi in un anti-pattern che devi affrontare.

Allora cos'è un anti-pattern?

Nel software, anti-pattern è un termine che descrive come NON risolvere i problemi ricorrenti nel codice. Gli anti-pattern sono considerati un cattivo design del software e di solito sono correzioni inefficaci o oscure.  

Generalmente aggiungono anche "debito tecnico", che è il codice che devi tornare e correggere correttamente in seguito.

I sei anti-pattern di cui parlerò in questo articolo sono Spaghetti Code , Golden Hammer , Boat Anchor , Dead Code , Proliferation of Code e God Object .

Codice degli spaghetti

Spaghetti Code è l'anti-pattern più conosciuto. È un codice con una struttura da poco a zero.

Niente è modularizzato. Ci sono file casuali disseminati in directory casuali. L'intero flusso è difficile da seguire ed è completamente aggrovigliato (come gli spaghetti).

Normalmente, questo è un problema in cui qualcuno non ha pensato attentamente al flusso del proprio programma in anticipo e ha appena iniziato a programmare.

Che cosa fa?! Non posso seguirlo

image.png

Questo non è solo un incubo di manutenzione, ma rende quasi impossibile aggiungere nuove funzionalità.

Romperai costantemente le cose, non capirai la portata delle tue modifiche o fornirai stime accurate per il tuo lavoro poiché è impossibile prevedere gli innumerevoli problemi che sorgono quando si fa tale archeologia / congettura.

Puoi leggere di più qui sull'anti-pattern Spaghetti Code .

Martello d'oro

"Suppongo che sia allettante, se l'unico strumento che hai è un martello, trattare tutto come se fosse un chiodo." Abraham Maslow

Immagina uno scenario con me: il tuo team di sviluppo è molto, molto competente nella nuovissima architettura Hammer. Ha funzionato in modo fantastico per tutti i tuoi problemi passati. Sei il team di architettura Hammer leader nel mondo.

Ma ora, in qualche modo, tutto finisce sempre per utilizzare questa architettura. Una vite a testa piatta? Martello. Vite a testa Phillips? Martello. Hai bisogno di una chiave a brugola? No, non lo fai, martella.

Si inizia ad applicare un approccio architetturale che non abbastanza in forma quello che ti serve, ma ottiene il lavoro fatto. Sei troppo dipendente da un modello e hai bisogno di imparare lo strumento migliore per il miglior lavoro.

L'intero programma potrebbe finire per subire un grave calo di prestazioni perché stai cercando di speronare un quadrato in una forma circolare. Sai che ci vuole il doppio del tempo per programmare ed eseguire un programma usando l'architettura hammer per questo problema, ma è più facile ed è ciò con cui ti trovi bene.

Inoltre non è molto prevedibile. Lingue diverse hanno soluzioni comuni ai problemi che devono affrontare e ai propri standard. Non puoi applicare ogni singola regola che ha funzionato bene per te in una lingua all'altra, senza problemi.

Non trascurare l'apprendimento costante nella tua carriera. Scegli la lingua giusta per il tuo problema. Pensa all'architettura e spingi fuori la tua zona di comfort. Ricerca e analizza nuovi strumenti e nuovi modi di affrontare i problemi che devi affrontare.

Puoi leggere di più qui sull'anti-pattern Golden Hammer .

Ancora per barca

L' anti-pattern Boat Anchor è il punto in cui i programmatori lasciano il codice nel codebase perché potrebbero averne bisogno in seguito.

Hanno codificato qualcosa leggermente fuori specifica e non è ancora necessario, ma sono sicuri che lo faranno il mese prossimo. Quindi non vogliono eliminarlo. Invialo alla produzione e in seguito, quando ne hanno bisogno, possono farlo funzionare rapidamente.

Ma questo causa incubi di manutenzione nella codebase che contiene tutto quel codice obsoleto. Il grosso problema è che i loro colleghi avranno difficoltà a capire quale codice è obsoleto e non cambia il flusso, rispetto al codice che lo fa.

Immagina di essere in una soluzione rapida e di cercare disperatamente di capire qual è la responsabilità dell'invio dei dettagli della carta dei clienti all'API per prelevare fondi dalla loro banca. Potresti perdere tempo a leggere ed eseguire il debug di codice obsoleto, senza rendertene conto che non sei nemmeno nel posto giusto nella base del codice.

Il problema finale è che il codice obsoleto allunga i tempi di compilazione e potresti confondere il lavoro con il codice obsoleto. Potresti persino iniziare ad "accenderlo" inavvertitamente durante la produzione.

Ora puoi probabilmente capire perché si chiama anti-pattern dell'ancora della barca: è pesante da trasportare (aggiunge un debito tecnico) ma non fa nulla (letteralmente, il codice non serve a nulla, non funziona).

Puoi leggere di più qui sull'anti-pattern dell'ancora per barche .

Codice morto

Hai mai dovuto guardare un codice scritto da qualcuno che non lavora più nella tua azienda? C'è una funzione che non sembra stia facendo nulla. Ma si chiama da ogni dove! Chiedete in giro e nessun altro è abbastanza sicuro di quello che sta facendo, ma tutti sono troppo preoccupati per cancellarlo.

A volte puoi vedere cosa sta facendo, ma manca il contesto. Sei in grado di leggere e capire il flusso, ma perché? Non sembra più necessario raggiungere quell'endpoint. La risposta è sempre la stessa per ogni utente diverso.

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.

Puoi leggere di più qui sull'anti-modello dell'oggetto Dio .

Conclusione

In qualsiasi codebase di grandi dimensioni c'è un equilibrio costante tra la gestione del debito tecnico, l'avvio di un nuovo sviluppo e la gestione di una coda di bug per il tuo prodotto.

Spero che questo articolo ti abbia dato un occhio per individuare quando potresti finire nella tana del coniglio di un anti-pattern e alcuni strumenti per risolverlo in modo pulito.

Condivido i miei scritti su Twitter se questo articolo ti è piaciuto e vuoi saperne di più.