Ο Πέτρος το έθεσε πολύ σωστά. Ακόμη και στο παράδειγμα των κομμάτων και των εδρών μπορεί οι κλάσεις να είναι απαραίτητες. Για παράδειγμα, γιατί να μην υπάρχει μία κλάση Κόμμα με properties τον αριθμό ψήφων και εδρών? Σε αυτή την περίπτωση η συνάρτηση υπολογισμού των εδρών θα μπορούσε να πάει σε κάθε κόμμα, να υπολογίσει τις έδρες και να τις αποθηκεύσει στο κατάλληλο πεδίο. Και, γιατί array και όχι Dictionary με κλειδί το κόμμα?
Τα πάντα εξαρτώνται από το πως θέλεις να χρησιμοποιήσεις τη συνάρτηση και σε ποιό πλαίσιο. Για παράδειγμα, έτσι όπως αλλάζουν οι εκλογικοί νόμοι, θα ήθελα να μπορώ να αλλάξω τον τρόπο υπολογισμού των εδρών χωρίς να πειράξω το υπόλοιπο πρόγραμμα, άσε που αν ήμουν τηλεοπτικό κανάλι θα ήθελα να δείξω τα αποτελέσματα με τον παλιό και το νέο εκλογικό νόμο. Σε μία τέτοια περίπτωση θα κοίταζα να μετατρέψω το function σε delegate έτσι ώστε να μπορώ να κάνω τους υπολογισμούς με διαφορετικό τρόπο, επιλέγοντας ποιό function να χρησιμοποιήσω.
Από εκεί και πέρα, πάλι σωστά το θέτει ο Πέτρος, κάνεις ολίγον TDD (για να το ονομάσουμε και επίσημα) και φτιάχνεις καταρχήν ένα stub της συνάρτησης το οποίο καλείς με τον τρόπο που βολεύει για τη συγκεκριμένη χρήση της συνάρτησης και την καλείς με διάφορους συνδυασμούς τιμών ελέγχοντας τα αποτελέσματα. Έτσι εξασφαλίζεις ότι κάθε αλλαγή στον κώδικα δεν προσθέτει σφάλματα.
Πέρα όμως από το σχεδιασμό της σωστής λειτουργίας του function, θα πρέπει κανείς να σκεφτεί και τί θα γίνει σε περίπτωση σφαλμάτων, και φυσικά να προσθέσει τα κατάλληλα tests. Για παράδειγμα, τί θα γίνει αν υπάρχουν περισσότερα ή λιγότερα κόμματα από αυτά που περιέχονται στο array των ψήφων? Τί θα γίνει αν κάπου υπάρχουν μηδενικές ή αρνητικές ψήφοι? Αν ο αριθμός των εδρών είναι μηδέν? Όλα αυτά μπορεί να φαίνονται "περίεργα" αλλά ένα bug κάπου αλλού μπορεί άνετα να αφήσει κάποιο πεδίο με μηδενική ή παράλογη τιμή.
Και αφού βρούμε το λάθος, τί κάνουμε? Αν έχουμε ήδη θέσει τιμές σε κάποιο εξωτερικό array ή αντικείμενο θα πρέπει να τις αντιστρέψουμε. Ακόμα καλύτερα, θα πρέπει να σχεδιάσουμε το function έτσι ώστε να μην προκαλεί παρενέργειες όταν κάτι πάει στραβά. Και τέλος, θα πρέπει να αποφασίσουμε τί θα κάνουμε με το σφάλμα? Μία περίπτωση είναι να ρίξω exception και σε περίπτωση λάθος παραμέτρων αυτό είναι καλή λύση. Ποιός όμως θα χειριστεί αυτό το exception?
Και τί θα γίνει αν εμφανιστεί exception μέσα στο function? Ο τρόπος χειρισμού δεν είναι δεδομένος. Αν δεν σκοπεύω να κάνω κάτι γι αυτό, μπορώ απλά να αφήσω το exception να ανέβει προς τα πάνω και κάποιος άλλος θα το πιάσει και θα το χειριστεί, είτε ειδοποιώντας το χρήστη, είτε ξαναδιαβάζοντας τα δεδομένα από την πηγή. Ή μπορεί να το πιάσω σε ένα catch, να προσθέσω επιπλέον στοιχεία στο exception και να το ξαναρίξω. Τέλος μπορώ να γράψω απλά πληροφορίες σε ένα log στο finally και να αφήσω το exception να προχωρήσει.
Όλα αυτά όμως έχουν να κάνουν με το πως και γιατί δημιουγώ το function και όχι μόνο με το τί θέλω να κάνει αυτό.
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos