Thursday, November 05, 2009

πολλά return σε μία μέθοδο, αλλά και ιnline evaluations - όχι δεν θα πάρω.

Μπορεις να διαβασεις και την αποψη του Bruce Eckel εδώ αλλα και αλλων σχετικα. Προσωπικά μισώ τις μεγάλες μεθόδους με exit points παντού! Μπορώ να το ανεχτώ σε μεθόδους μέχρι 10 γραμμές αλλά όταν εισαι σε μια αναγκαστηκά μεγάλη ρουτίνα και βλέπεις return πάνω κάτω δεξιά και αριστερά...τα προσωπικά μου WTF μεγαλώνουν!

Η αλήθεια ειναι ότι πολλοί προγραμματιστές τα γουστάρουν - άλλοι λένε και για κάποια minor performance gains. Εγώ το θεωρώ κακή προγραμματιστική λογική. Ίσως έχω καταντήσει οld school αλλά πάντα μου άρεσει το pattern.

Object result = null;

// mpla mpla code assignment

return result;

Θες να σπάσεις nested if's κάνε break.Γράψε πιο δομημένα if.

Απο εμπειρία επίσης θεωρώ ότι τα  πολλαπλά return statement  ειναι πιο δυσκολα και risky στο refactoring! Κάνε μια μαλακία σε κάποιο if (ένα bug) και έχεις προεξοφλήσει η μέθοδος σου εξαιτίας bug να επιστρέφει μια σταθερή τιμή.

Παράλληλα μισώ τα inline evaluation μέσα σε return! Ναι ειναι απόλυτα σωστός κώδικας - αλλά έχω δει και κώδικα που κανει.

 return aStr.equals(SomethingElse)

και τα null pointer να πηγαίνουν σύννεφο.


Όπως λεει και ο Gordon Ramsay keep it fucking sipmple. Διαχώρησε την λογική και μετά σούταρε την έξω με return!

Ακούω αποψεις!

12 comments:

  1. Συμφωνώ απόλυτα με αυτά που λες και όσο για τα performance gains έχω κάποιες αμφιβολίες. Σίγουρα είναι πολύ σπάνιες οι περιπτώσεις που θα έχουμε gain. Aπό μια άποψη είναι μόνο σωστό, άμα θες να μπερδέψεις τον άλλο που θα διαβάσει τον κωδικά σου.

    ReplyDelete
  2. Συμφωνώ dude, σε γενική περίπτωση πιστεύω πως inline / function calls σε return βάζει κανείς μόνο σε περιπτώσεις που είναι 100% σίγουρος του τί επιστρέφει το statement. Και ναι, τα multiple returns ειδικά σε μεγάλες συναρτήσεις είναι πονοκέφαλους για όλους, ειδικά για αυτόν που θα δεί τον κώδικα σου μετά ;)

    ReplyDelete
  3. Polla dikia exeis aderfe!!!
    Rota kai emena pou prosfata diavasa ton kodika tou dom4j epiksa stis methodous 100 kai 200 gramon kai sta 20 return statements.
    This sucks.

    ReplyDelete
  4. Επίσης ο Ramsay λέει συνέχεια "Always taste! taste! taste! before serve"

    ReplyDelete
  5. Πάρι είμαι υπέρμαχος των inline (σε λογικό βαθμό). Στο παράδειγμά σου θα μπορούσες να κάνεις απλώς

    return aStr != null ? aStr.equals(SomethingElse) : κάτι άλλο.

    ReplyDelete
  6. Αν κάνεις το

    if (param) return true;
    dostuff();
    return false;

    σε
    boolean result
    if (param) result=true;
    else {
    dostuff();
    result=false;
    }
    return result;

    δεν γεμίζεις blocks στο scope αλλων blocks? Και αν η μέθοδος μεγαλώσει αρκετά (περι τις 200 αγαπημένες γραμμές) χωρίς returns θα έχεις γεμισει εφολευμένα scopes.

    ReplyDelete
  7. Με κάλυψε ο Papo. Συμφωνώ 100%. Πες με old-skool άλλα έτσι μου αρέσει. Έχει τύχη να το χρησιμοποιήσω το return με αυτό τον τρόπο άλλα μόνο σε κώδικα που ΔΕΝ θα δουν άλλοι. Μπορεί να βολεύει κάπως (σπάνια) άλλα το πιθανότερο είναι να μην βολεύει τον άλλον που θα διαβάσει τον κώδικα και ο rule of thumb είναι "Γράψε κώδικα και φαντάσου ότι ο άλλος που θα τον διαβάσει δε ξέρει να γράφει κώδικα". Είμαι αυτής της άποψης τελεία και παύλα.

    ReplyDelete
  8. Θα συμφωνήσω με τον Πάνο περί inline.
    Για τα multiple returns αρκεί να υπάρχει μέτρο. π.χ. για early exit.

    ReplyDelete
  9. Ψηφίζω early exits για assertion ελέγχους. Από κει και πέρα αν γίνεται μακαρονάδα η μέθοδος, θέλει decomposition.

    ReplyDelete
  10. μου αρέσει ο κώδικας να διαβάζετα σαν μία παράγραφος. Στυλιστικά προτιμώ τα early exits στο τέλος - με τα κατάλληλα if και όχι πάνω πάνω. Δηλαδή όταν η μέθοδος λέει ΚΑΝΩ αυτό - άσε τον άλλον να διαβάσει καταρχήν τι κάνει και άσε τα early exit cases στο τέλος. Το ανάποδο το βρίσκω πολυ σπαστικό όταν διαβάζω κώδικα!


    Επίσης early exits γίνοντε και 1 return..δεν χρειάζεται 100000 return παντού!

    ReplyDelete
  11. Εμένα πάντως μου αρέσει ο κώδικας "μπουρμπουλήθρα".

    Δηλαδή, να σπας τον κώδικα σε όσα περισσότερα λογικά και επαναχρησιμοποιήσιμα κομμάτια μπορείς. Έτσι, άμα κάνεις debug μία μέθοδο θα σε πηγαίνει σε άλλη και σε άλλη μέχρι να σκάσει η "φούσκα".

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

    ReplyDelete
  12. Τα πολλά if /else/then που πάει το ένα πάνω στο άλλο είναι εξίσου ενοχλητικό. Τα returns είναι όντως επικίνδυνα και καλό είναι και να προσθέτουμε logs σε ορισμένα σημεία.

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

    Όντως, ας μην κάνουμε τον κώδικα μας sophisticated, αλλά πάνω απ' όλα ΑΠΛΟ.

    ReplyDelete