Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Θορυβος ως προς την αναγνωση ή ως προς το τελικο προϊον; Στο τελικο προϊον αφαιρουνται αυτοματως με εργαλεια ως γνωστον. Ως προς την αναγνωση σε οτι framework εχω δουλεψει υπαρχουν παντου comments στον πηγαιο κωδικα και σχεδον ολες τις φορες υπαρχουν σχολια πολλων γραμμων πληρως επεξηγηματικα.

Σύμφωνα με τους υποστηρικτές του Clean Code τα πολλά comments θεωρούνται code smells...οπότε πρέπει να χρησιμοποιούνται μόνο όταν τα στοιχεία του κώδικα (μέθοδοι,μεταβλητές) αδυνατούν να περιγράψουν λόγω περιορισμένης εννοιας την χρήση του κώδικα...

 

public function materialize()
{
    $output = Json::encode($this->data);

    // INTERNET EXPLORER HORROR STORY #2436236
    // Server returns a 4xx or 5xx error code? Don't worry, IE comes to the rescue! If you return such a code IE
    // will helpfully REPLACE YOUR CONTENT with a friendly error message, which is bad enough by itself. If you are
    // in the pleasant position of doing this in a <iframe> and then try to access the content from the original
    // page this means that scripting errors will occur as a result of the same-origin policy and it all goes
    // downhill from there.
    //
    // Solution: make sure that you always return content larger than 512 bytes in order to turn off this "feature".
    // Documented at http://support.microsoft.com/kb/294807/en-us
    $userAgent = Application::resolve()->request->getUserAgentAndVersion();
    $isInternetExplorer = $userAgent && reset($userAgent) === HttpRequest::UA_INTERNET_EXPLORER;
    if ($isInternetExplorer && $this->httpCode >= 400 && strlen($output) < 513) {
        $output .= str_repeat(' ', 513 - strlen($output));
    }

    echo $output;
}

Νομίζω είναι προφανές πού θέλω να καταλήξω.

 

Χωρίς να είμαι ειδικός στο refactoring και με περιορισμένη γνώση σε PHP θεωρώ ότι θα ήταν καλύτερο να αντιμετωπίσεις το πρόβλημα σαν γενικότητα του τύπου εαν ο Browser ανήκει σε αυτούς που συμπεριφέρονται σωστά τότε....ειδάλλως Ειδικοί browser με ειδική αντιμετώπιση ...ετσι δεν θα εχεις φυτευτές τιμές μόνο για IE (π.χ αυριο μεθαυριο ο Opera αλλάζει και δεν αντιδρα οπως θα έπρεπε....απλώς τον καταχωρείς στην Λίστα με τους Browsers Που τυγχάνουν ειδικής αντιμετώπισης .......

Τωρα για τα απαραίτητα comments θα μπορούσες να βάλεις μόνο 1 σχόλιο του τύπου ΙΕ_HORROR STORY #2436236 στην αντιμετώπιση του ΙΕ και να το έχεις κάπου σε 1 εξωτερικό αρχείο

Δημοσ.

Χωρίς να είμαι ειδικός στο refactoring και με περιορισμένη γνώση σε PHP θεωρώ ότι θα ήταν καλύτερο να αντιμετωπίσεις το πρόβλημα σαν γενικότητα του τύπου εαν ο Browser ανήκει σε αυτούς που συμπεριφέρονται σωστά τότε....ειδάλλως Ειδικοί browser με ειδική αντιμετώπιση ...ετσι δεν θα εχεις φυτευτές τιμές μόνο για IE (π.χ αυριο μεθαυριο ο Opera αλλάζει και δεν αντιδρα οπως θα έπρεπε....απλώς τον καταχωρείς στην Λίστα με τους Browsers Που τυγχάνουν ειδικής αντιμετώπισης .......

 

Μη ξεχνάμε πάντως ότι αυτόν τον κώδικα τον έδωσα για να μιλήσουμε για τα comments.  :)

 

Πέρα από αυτό τώρα. Ναι, είναι πιο ευέλικτο όταν έχεις πολλές περιπτώσεις "παραξενιών" του κάθε browser να γενικοποιείται η κατάσταση και να μη καταλήγουμε σε ατελείωτα if έτσι elseif γιουβέτσι ξανά και ξανά. Και πολύ βολικό που το αναφέρεις κιόλας γιατι ταιριάζει στο θέμα. Επί του θέματος λοιπόν...

 

Λοιπόν, αρχικά δεν υπήρχε πρόβλεψη για να γίνει τίποτα από όλα αυτά. Κάποια στιγμή προέκυψε στα πλαίσια του testing ότι υπό πολύ συγκεκριμένες συνθήκες ("AJAX" file upload σε παλιό IE που δεν υποστηρίζει τέτοια και το χακεύεις με POST σε <iframe>, και το upload να αποτύχει) τα πράγματα χαλάνε. Μετά από το σχετικό debugging (από το οποίο προέκυψε και το comment/bug description παραπάνω) βρέθηκε η λύση. Ωραία, πώς την υλοποιούμε;

 

Στην προκειμένη περίπτωση ξέρω (λέμε τώρα) από πριν πως δε θα χρειαστεί ποτέ καμία άλλη παρόμοια διόρθωση γιατί η συγκεκριμένη δυσλειτουργία δεν προκύπτει όταν ο browser υποστηρίζει XHR, και ο μόνος browser που δεν υποστηρίζει XHR και ταυτόχρονα υποστηρίζεται από τη συγκεκριμένη εφαρμογή είναι ο IE 8 και 9. Ταυτόχρονα η "targeted hack" εκδοχή παραπάνω δεν είναι και τίποτα εφόσον έχεις το context -- 3-4 γραμμές σε ένα σημείο που δε χρειάζεται καν να τις διαβάσεις εκτός αν έχεις το bug να σπαρταράει στα χέρια σου, οπότε ούτε και για βελτίωση του σχεδιασμού μπορούμε να μιλάμε γιατί οτιδήποτε άλλο θα είναι ακόμα πιο περίπλοκο.

 

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

 

Αν τώρα υποθέσουμε πως έμπαινα στη διαδικασία να κάνω "σωστό σχεδιασμό" because reasons, τότε...

  • Γιατί να κάνω "λίστα" με περίεργους browsers? Τι μορφή θα είχε δηλαδή αυτή η λίστα;
  • Άντε αν η πιθανή παραξενιά του οποιουδήποτε browser είναι μόνο αυτή για την οποία συζητάμε, τους βάζω σε μια λίστα. Αν όμως ο browser Α έχει την παραξενιά Χ και o B την Y, θα κάνω δύο λίστες; Τι γίνεται αν υπάρχουν 10-15 διαφορετικές παραξενιές που έχω να αντιμετωπίσω;
  • Αν έχουν την ίδια παραξενιά αλλά με μια διαφορά του στυλ ο ένας την εμφανίζει για content length < 500 και ο άλλος για < 1000 τότε τι κάνω; Διαφορετικές λίστες πάλι; Έτσι μπορεί να καταλήξω να έχω 3 "διαφορετικές" λίστες με έναν browser η καθεμία για την ίδια ακριβώς περίπτωση! Αν οι μεταβλητές/συνθήκες υπό τις οποίες εμφανίζεται η παραξενιά είναι πολύ περίεργες, πώς το κωδικοποιώ αυτό;

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

 

Συμπερασματικά, είναι πάρα πολύ δύσκολο να γράψεις σωστά δομημένο κώδικα όταν δε μπορείς να προβλέψεις το μέλλον.  ;)

Τωρα για τα απαραίτητα comments θα μπορούσες να βάλεις μόνο 1 σχόλιο του τύπου ΙΕ_HORROR STORY #2436236 στην αντιμετώπιση του ΙΕ και να το έχεις κάπου σε 1 εξωτερικό αρχείο

 

Και τι ακριβώς θα κέρδιζα έτσι; Με ποιό τρόπο θα ήταν καλύτερο το να διαβάσω στον κώδικα κάτι που είναι ακόμα πιο ακαταλαβίστικο από τον κώδικα που συνοδεύει, και που πρέπει να πάω να ανοίξω άλλο αρχείο (ποιό? πού είναι? πώς θα το βρεις εσύ που πρώτη φορά βλέπεις αυτό τον κώδικα στη ζωή σου?) για να μάθω τι σημαίνει;

 

Don't get me wrong έτσι; Η γραμμή μου εδώ είναι η εξής και δεν το λέω αυτό για να σου την πω αλλά για να εκφράσω την παρούσα κατάσταση όπως την αντιλαμβάνομαι: διάβασες κάπου "κάνε Χ γιατί το Υ είναι κακό" αλλά δεν κατάλαβες πραγματικά (πιθανότατα δεν εξηγήθηκε και σωστά) για ποιό λόγο είναι κακό το Υ και τι προσπαθούμε να πετύχουμε κάνοντας Χ. Ο κάθε κανόνας έχει εξαιρέσεις, ειδικά οι μπούσουλες που απευθύνονται σε λιγότερο έμπειρους.

 

Αυτά που έχεις διαβάσει περι σχολίων να έχεις υπόψη, λένε (και έχουν δίκιο) πως είναι κακό να κάνεις αυτό:

// frobs the widget
frob(widget);
// blips the gadget
blip(gadget);

Δεν είναι όμως καθόλου κακό -- ίσα ίσα το αντίθετο -- να κάνεις αυτό:

// IMPORTANT: The widget has to be frobbed before the gadget is blipped because reasons
// even more reasons
// SO MANY REASONS
frob(widget);
blip(gadget);
  • Like 1
Δημοσ.

Τα πολλα κομεντς ειναι καλα. Απλα να μπαινιυν με μετρο. Πχ στο παραδειγμα με το date δεν υπαρχει λογος για κομεντς, ουτε να την πας σε αμπστρακτιον μεχρι αηδιας, σε αντιθεση με την αλλη συναρτηαη που οντως θελει κομεντς.

Δημοσ.

Συνήθως σε php functions κάνω το ακόλουθο:

/**
* @param string $a blah blah blah
* @throws Exception 
*/
function foo($a)
{
...
 throw new Exception();
...
}

H πχ. εαν περνάω κάποιο array που θέλει ιδιάιτερο format:


/**
* @param array $a an associative array that must have this following format:
* [
*   'foo1'=>"blah blah blah",
*   'foo2'=>[
*     'harem'=>'master',
*     'anime'=> true,
*     'watcher'=>false
*   ]
* ]
*/
function foo(array $a)
{
 ...
}

Και σαφώς θεωω πλεόν must όταν γράφεις σε Object Oriented γλώσσα Πάντα να έχεις δίπλα το manual για τα ΟΟ Desighn Patterns και σαφώς DI, βασικά όταν γράφεις κώδικα (σε αντικειμενοστρεφής γλώσσα) αυτόματα χωρίς σκέψη να κάνεις DI και να εφαρμόζεις ΟΟ Desighn Patterns.

Δημοσ.

ουτε να την πας σε αμπστρακτιον μεχρι αηδιας

 

Γιατί όχι; Έτσι και ακολουθείς το YAGNI μιας και όντως το χρειάστηκες, αλλά έχεις και κάτι πολύ πιο self documented και reusable σε περίπτωση που το χρειαστείς ξανά.

 

Από την άλλη το "δομημένο κώδικα" μου κάνει το ίδιο με το Desighn Patters. Και ατσά μάγκες, τζαμάουα και δέρνουα. Πως ορίζεται το "σωστός δομημένος κώδικας"; Με βάση τι; Το structured programming paradigm που ταιριάζουν και στις λέξεις; :blink:  :wacko:

 

Από την άλλη τα design patterns/conventions/best practices είναι μονόδρομος σε μεγάλα projects. Ένας έμπειρος προγραμμαστιστής εν γνώση του μπορεί να αποφύγει κάπου να τα χρησιμοποιήσει, ωστόσο ξέρει ότι στο 99% των περιπτώσεων μακροπρόθεσμα αυτό το κομμάτι κώδικα θα χρειαστεί οπωσδήποτε refactoring για να είναι maintainable. Και ειδικά αν στο ενδιάμεσο κάποιος άλλος έχει πατήσει πάνω στο λάθος σχεδιασμό και έχει κάνει ένα κάρο άλλα πράγματα implement, τότε είναι που αρχίζει ο χρόνος να περνάει άσκοπα.

 

Φυσικά, το παραπάνω απέχει πολύ από το να φας ατέλειωτες εργατοώρες προκειμένου να παίζεις και να προσπαθείς να κάνεις "τέλειο" ένα one time migration script των 100 γραμμων το οποίο για κάποιο λόγο θα το έχεις φτάσει στις 1000 δίχως να έχεις κερδίσει κάτι σε features ή robustness... 

Δημοσ.

Να προσθεσω επίσης, οτι τα πολλά comments σε μεγαλη κλιμακα codebase ίσως και να δειχνουν οτι η γλωσσα δεν ειναι και τόσο declarative και δεν εξυπηρετεί.

  • 5 μήνες μετά...
Δημοσ. (επεξεργασμένο)

Για να πεις κάτι αν είναι "εύκολο" ή "δύσκολο" πρέπει να έχεις κάτι άλλο ως μέσο σύγκρισης.

 

Αυτό που μου γίνεται αρκετά αντιληπτό τώρα, όπου φτιάχνω το μεγαλύτερο project που έχω ασχοληθεί ως τώρα (5.500 γραμμές και ούτε το 1/10 της λειτουργικότητας ακόμα) είναι το εξής:

 

# Είναι εύκολο κατά τη συγγραφή για διάφορους λόγους να αμελήσεις κάτι και να κάνεις κάποια 'λάθη' τα οποία κάποια στιγμή θα συσσωρευτούν. Και όσο συσσωρεύονται, τόσο πιο δύσκολο θα είναι να τα λύσεις αργότερα, και τόσο πιο πολλές παρενέργειες θα είναι πιθανές. Γιατί θα έχεις φτιάξει 2-3 συστήματα να λειτουργούν με έναν Α τρόπο, αλλά στη πορεία να διαπιστώσεις πως για το επόμενο feature που πρέπει να προσθέσεις, πρέπει να τα αλλάξεις και να τα κάνεις να λειτουργούν με ένα Β τρόπο. Και αντί να προσθέτεις νέα features κάθεσαι και ξαναγράφεις τα παλιά που είχες ήδη γράψει...

 

# Το καλύτερο πράγμα που μπορείς να κάνεις αρχικά, είναι να ξοδέψεις περισσότερο χρόνο στο σχεδιασμό. Όπως είδα να γράφεται σε ένα διαδικτυακό meme "An hour of planning saves days of coding".

 

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

 

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

 

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

πχ

 

1. Η αρχή του κάθε τι να κάνει ένα μόνο πράγμα, και να το κάνει καλά. Είτε κλάση είτε συνάρτηση, να κάνει ένα πράγμα.

2. Η κάθε κλάση να ξέρει όσο το δυνατόν λιγότερα πράγματα για άλλες κλάσεις.

3. Πολυμορφισμός!

4. Κάθε κομμάτι γνώσης να υπάρχει μια μόνο φορά, και να μην επαναλαμβάνεται σε πολλά σημεία.

5. Και διάφοροι άλλοι...

 

Αυτά είναι πράγματα τα οποία ίσως να μη ξέρεις απ' την αρχή γιατί πρέπει να τα κάνεις, ή να σκέφτεσαι ότι το δικό σου project δε τα χρειάζεται. Θα έρθουν στιγμές όμως που ενώ έχεις ήδη κάνει πολύ δουλειά, επειδή δεν ακολούθησες κάτι ή όλα απ' αυτά όπως και εκεί που πρέπει, θα αντιληφθείς πως για να μπορέσεις να συνεχίσεις την ανάπτυξη του έργου θα πρέπει να πας πίσω και να κάνεις "γενναίο" refactor, και για 1 αλλαγή που θες να κάνεις σε 1 πράγμα, θα πρέπει να κάνεις Χ αλλαγές σε Ψ πράγματα..

Επεξ/σία από Alithinos

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...