Αντι-μοτίβα που πρέπει να αποφεύγετε στον κώδικα σας

Κάθε προγραμματιστής θέλει να γράψει δομημένο, απλώς προγραμματισμένο και ωραίο σχόλιο κώδικα. Υπάρχουν ακόμη και μυριάδες μοτίβα σχεδιασμού που μας δίνουν σαφείς κανόνες που πρέπει να ακολουθήσουμε και ένα πλαίσιο που πρέπει να έχουμε κατά νου.

Ωστόσο, μπορούμε ακόμα να βρούμε αντι-μοτίβα σε λογισμικό που γράφτηκε κάποια στιγμή ή γράφτηκε πολύ γρήγορα.

Ένα ακίνδυνο βασικό hack για γρήγορη επίλυση ενός προβλήματος μπορεί να δημιουργήσει προηγούμενο στη βάση κώδικα σας. Μπορεί να αντιγραφεί σε πολλά μέρη και να μετατραπεί σε ένα μοτίβο που πρέπει να αντιμετωπίσετε.

Τι είναι λοιπόν ένα αντι-μοτίβο;

Στο λογισμικό, το anti-pattern είναι ένας όρος που περιγράφει πώς ΔΕΝ επιλύει επαναλαμβανόμενα προβλήματα στον κώδικά σας. Τα αντι-μοτίβα θεωρούνται κακός σχεδιασμός λογισμικού και συνήθως είναι αναποτελεσματικές ή σκοτεινές διορθώσεις.  

Γενικά προσθέτουν επίσης "τεχνικό χρέος" - που είναι κωδικός που πρέπει να επιστρέψετε και να διορθώσετε σωστά αργότερα.

Τα έξι αντι-μοτίβα που θα συζητήσω σε αυτό το άρθρο είναι οι Spaghetti Code , Golden Hammer , Boat Anchor , Dead Code , Proliferation of Code και το God Object .

Κωδικός σπαγγέτι

Ο κώδικας Spaghetti είναι το πιο γνωστό anti-pattern. Είναι κωδικός με μικρή έως μηδενική δομή.

Τίποτα δεν είναι διαμορφωμένο. Υπάρχουν τυχαία αρχεία σκορπισμένα σε τυχαίους καταλόγους. Ολόκληρη η ροή είναι δύσκολο να ακολουθηθεί και είναι εντελώς μπερδεμένη μαζί (όπως τα μακαρόνια).

Κανονικά, αυτό είναι ένα ζήτημα όπου κάποιος δεν έχει μελετήσει προσεκτικά τη ροή του προγράμματός του και μόλις άρχισε να κωδικοποιεί.

Τι κάνει?! Δεν μπορώ να το ακολουθήσω

image.png

Αυτό δεν είναι μόνο εφιάλτης συντήρησης, αλλά καθιστά σχεδόν αδύνατο να προσθέσει νέα λειτουργικότητα.

Θα σπάτε συνεχώς τα πράγματα, δεν θα κατανοείτε το εύρος των αλλαγών σας, ή θα δίνετε ακριβείς εκτιμήσεις για την εργασία σας, καθώς είναι αδύνατο να προβλεφθούν τα αμέτρητα ζητήματα που εμφανίζονται όταν κάνετε τέτοια αρχαιολογία / εικασίες.

Μπορείτε να διαβάσετε περισσότερα εδώ σχετικά με το anti-pattern του Spaghetti Code .

Χρυσό Σφυρί

"Υποθέτω ότι είναι δελεαστικό, αν το μόνο εργαλείο που έχετε είναι ένα σφυρί, να αντιμετωπίζετε τα πάντα σαν να ήταν καρφί." Αβραάμ Μάσλοου

Φανταστείτε ένα σενάριο μαζί μου: η ομάδα προγραμματιστών σας είναι πολύ, πολύ ικανή στην ολοκαίνουργια αρχιτεκτονική Hammer. Λειτουργεί φανταστικά για όλα τα προηγούμενα θέματα που έχετε. Είστε η κορυφαία ομάδα αρχιτεκτονικής Hammer στον κόσμο.

Αλλά τώρα, κατά κάποιο τρόπο, όλα καταλήγουν πάντα χρησιμοποιώντας αυτήν την αρχιτεκτονική. Μια βίδα με επίπεδη κεφαλή; Σφυρί. Βίδα κεφαλής Phillips; Σφυρί. Χρειάζεστε ένα κλειδί Allen; Όχι, όχι, σφυρί.

Αρχίζετε να εφαρμόζετε μια αρχιτεκτονική προσέγγιση που δεν ταιριάζει αρκετά σε αυτό που χρειάζεστε αλλά ολοκληρώνεται η δουλειά. Είστε υπερβολικά βασισμένοι σε ένα μοτίβο και πρέπει να μάθετε το καλύτερο εργαλείο για την καλύτερη δουλειά.

Ολόκληρο το πρόγραμμά σας θα μπορούσε να καταλήξει σε μια σοβαρή επιτυχία απόδοσης επειδή προσπαθείτε να βάλετε ένα τετράγωνο σε σχήμα κύκλου. Γνωρίζετε ότι χρειάζονται δύο φορές περισσότερο για να κωδικοποιήσετε και για να εκτελέσετε ένα πρόγραμμα χρησιμοποιώντας την αρχιτεκτονική του σφυριού για αυτό το πρόβλημα, αλλά είναι ευκολότερο και αυτό είναι που σας αρέσει.

Επίσης, δεν είναι πολύ προβλέψιμο. Διαφορετικές γλώσσες έχουν κοινές λύσεις στα προβλήματα που αντιμετωπίζουν και στα δικά τους πρότυπα. Δεν μπορείτε να εφαρμόσετε κάθε κανόνα που λειτούργησε καλά για εσάς σε μια γλώσσα στην άλλη, χωρίς προβλήματα.

Μην παραμελείτε τη συνεχή μάθηση στην καριέρα σας. Επιλέξτε τη σωστή γλώσσα για το πρόβλημά σας. Σκεφτείτε την αρχιτεκτονική και βγάλτε έξω τη ζώνη άνεσής σας. Ερευνήστε και ερευνήστε νέα εργαλεία και νέους τρόπους προσέγγισης των προβλημάτων που αντιμετωπίζετε.

Μπορείτε να διαβάσετε περισσότερα εδώ σχετικά με τη Χρυσή Hammer αντι-πρότυπο.

Αγκυρα λέμβου

Το αντι-μοτίβο Boat Anchor είναι όπου οι προγραμματιστές αφήνουν τον κώδικα στη βάση κώδικα επειδή μπορεί να τον χρειαστούν αργότερα.

Κωδικοποίησαν κάτι λίγο εκτός προδιαγραφών και δεν χρειάζεται ακόμη, αλλά είναι σίγουροι ότι θα τον επόμενο μήνα. Επομένως, δεν θέλουν να το διαγράψουν. Στείλτε το στην παραγωγή και αργότερα όταν το χρειάζονται, μπορούν να το κάνουν γρήγορα να λειτουργήσει.

Αλλά αυτό προκαλεί εφιάλτες συντήρησης στη βάση κώδικα που περιέχει όλο τον παρωχημένο κώδικα. Το τεράστιο ζήτημα είναι ότι οι συνάδελφοί τους θα δυσκολευτούν να επεξεργαστούν ποιος κώδικας είναι ξεπερασμένος και δεν αλλάζει τη ροή, έναντι του κώδικα που ισχύει.

Φανταστείτε ότι βρίσκεστε σε καυτό πρόβλημα και προσπαθείτε απεγνωσμένα να βρείτε τι είναι υπεύθυνο για την αποστολή των στοιχείων της κάρτας πελατών στο API για την ανάληψη χρημάτων από την τράπεζά τους. Θα μπορούσατε να χάσετε χρόνο ανάγνωσης και εντοπισμού σφαλμάτων ξεπερασμένου κώδικα, χωρίς να συνειδητοποιήσετε ότι δεν είστε καν στη σωστή θέση στη βάση κώδικα.

Το τελευταίο ζήτημα είναι ότι ο παρωχημένος κώδικας καθιστά τον χρόνο κατασκευής σας μεγαλύτερο και μπορεί να συνδυάσετε τον κώδικα εργασίας και του παρωχημένου. Θα μπορούσατε ακόμη και να αρχίσετε να ακούτε κατά λάθος την παραγωγή.

Τώρα πιθανότατα μπορείτε να δείτε γιατί ονομάζεται αντιολισθητικό σκάφος - είναι βαρύ να μεταφερθεί (προσθέτει τεχνικό χρέος) αλλά δεν κάνει τίποτα (κυριολεκτικά, ο κώδικας δεν εξυπηρετεί κανένα σκοπό, δεν λειτουργεί).

Μπορείτε να διαβάσετε περισσότερα εδώ σχετικά με το μοτίβο άγκυρας Boat .

Νεκρός κωδικός

Είχατε ποτέ να κοιτάξετε κώδικα που γράφτηκε από κάποιον που δεν εργάζεται πλέον στην εταιρεία σας; Υπάρχει μια λειτουργία που δεν φαίνεται να κάνει τίποτα. Αλλά καλείται από παντού! Ρωτάτε γύρω και κανείς άλλος δεν είναι αρκετά σίγουρος τι κάνει, αλλά όλοι ανησυχούν πολύ για να το διαγράψουν.

Μερικές φορές μπορείτε να δείτε τι κάνει, αλλά το περιβάλλον λείπει. Μπορείτε να διαβάσετε και να κατανοήσετε τη ροή, αλλά γιατί; Δεν φαίνεται να χρειάζεται να χτυπήσουμε πια αυτό το τελικό σημείο. Η απόκριση είναι πάντα η ίδια απάντηση για κάθε διαφορετικό χρήστη.

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.

Μπορείτε να διαβάσετε περισσότερα εδώ για το αντικειμενικό αντικείμενο του Θεού .

συμπέρασμα

Σε οποιαδήποτε μεγάλη βάση κώδικα υπάρχει μια σταθερή ισορροπία μεταξύ διαχείρισης τεχνικού χρέους, έναρξης νέας ανάπτυξης και διαχείρισης ουράς σφαλμάτων για το προϊόν σας.

Ελπίζω ότι αυτό το άρθρο σάς έδωσε τη δυνατότητα να εντοπίσετε πότε θα μπορούσατε να κατεβείτε την τρύπα του κουνελιού ενός αντι-μοτίβου και ορισμένα εργαλεία για να το επιλύσετε καθαρά.

Μοιράζομαι τη γραφή μου στο Twitter αν σας άρεσε αυτό το άρθρο και θέλετε να δείτε περισσότερα.