Σημειώσεις:Τεχνολογίες Υλοποίησης:Οργάνωση και Ανάπτυξη Κώδικα

Από DistrSys

Πίνακας περιεχομένων

Οργάνωση και Ανάπτυξη Κώδικα

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

Ποιότητα Κώδικα

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

  • Αποδοτικότητα (Efficiency) — Η αποδοτικότητα αφορά την όσο το δυνατόν πιο αποδοτική χρήση των πόρων του συστήματος. Με τον όρο πόροι ενός συστήματος συνήθως αναφερόμαστε στη μνήμη, τόσο την μόνιμη (σκληρός δίσκος) όσο και την προσωρινή (RAM - cache), τον επεξεργαστή, τις περιφερειακές συσκευές, το δίκτυο, κ.ά.
  • Αξιοπιστία (Reliability) — Ο παραγόμενος κώδικας πρέπει να είναι αξιόπιστος. ∆ηλαδή, θα πρέπει να υλοποιεί με ακρίβεια αυτά που έχουν οριστεί από τις προδιαγραφές προβλέποντας τα διάφορα προβλήματα που μπορεί να προκύψουν κατά τη διάρκεια της εκτέλεσης (όπως η υπερχείλιση ή η έλλειψη μνήμης).
  • Ευρωστία (Robustness) — Ο προγραμματιστής θα πρέπει να προβλέψει όσο το δυνατόν περισσότερες περιπτώσεις κατά τις οποίες, λόγω της ασυμβατότητας των διαφόρων δεδομένων ή στοιχείων προερχόμενων από το χρήστη, υπάρχει πιθανότητα να προκύψουν σφάλματα κατά την ώρα εκτέλεσης. Τέτοιου είδους σφάλματα θα πρέπει να συμβαίνουν όσο γίνεται πιο σπάνια και στην περίπτωση που συμβούν να περιγράφονται κατάλληλα με μηνύματα σφάλματος.
  • Μεταφερσιμότητα (Portability) — Η τεχνολογία πλέον εξελίσσεται ταχύτατα τόσο σε επίπεδο υλικού όσο και σε επίπεδο λογισμικού. ́Ετσι είναι πολύ χρήσιμο ο παραγόμενος κώδικας να μπορεί να μεταφέρεται σε οποιοδήποτε περιβάλλον και να μπορεί να εκτελεστεί χωρίς κάποια επιπλέον προσπάθεια επαναπρογραμματισμού.
  • Αναγνωσιμότητα (Readability) — Η ανάπτυξη και η συντήρηση του κώδικα δεν είναι πλέον θέμα ενός μόνο ατόμου. Η ανάπτυξη γίνεται στα πλαίσια ομάδων όπου κάθε άτομο αναλαμβάνει ένα μικρό κομμάτι της όλης εφαρμογής. ́Ετσι είναι πολύ χρήσιμο ο κώδικας που παράγουν τα διάφορα μέλη των ομάδων να είναι ευανάγνωστος και κατανοητός έτσι, ώστε να μπορεί οποιοδήποτε μέλος της ομάδας να διαβάσει οποιοδήποτε μέρος του κώδικα εφαρμογής.

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

́Ελεγχος Ποιότητας Κώδικα

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

Για την, κατά κάποιο τρόπο, πιστοποίηση της ποιότητας του παραγόμενου κώδικα έχουν αναπτυχθεί πολλά εργαλεία. Τα πιο διαδεδομένα κάνουν στατική ανάλυση κώδικα (static code analysis), δηλαδή διαβάζουν και αναλύουν τον κώδικα ελέγχοντας για τυχόν λάθη, παραλήψεις ή μη αποδοτικές τεχνικές προγραμματισμού. Ο PMD, είναι ένα παράδειγμα δυναμικού αναλυτή για κώδικα Java. Ο αναλυτής αυτός διαβάζει τον κώδικα και παράγει μία αναφορά στην κατάλληλη μορφή (πχ html, xml, κτλ) ανάλογα με το τι του έχει ορίσει ο χρήστης.Η αναφορά αυτή περιέχει παρατηρήσεις για διάφορα θέματα (ανάλογα με τους κανόνες που έχουν οριστεί) χωρισμένες σε πέντε επίπεδα σοβαρότητας. Ο προγραμματιστής μπορεί, διαβάζοντας την αναφορά, να τροποποιήσει τον κώδικά του κάνοντάς τον πιο ποιοτικό.

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

́Ελεγχος Ορθότητας Κώδικα

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

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

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

Συστήματα ∆ιαχείρισης Εκδόσεων (VCS)

́Οπως προαναφέρθηκε, πλέον το μέγεθος των εφαρμογών δεν επιτρέπει την ανάπτυξή τους από ένα μόνο άνθρωπο, αλλά κάνει αναγκαία τη συνεργασία πολλών. Αυτό δημιουργεί ένα πρόβλημα που δεν υπήρχε πριν : την έγκαιρη και χωρίς προβλήματα παρακολούθηση των αλλαγών που γίνονται από κάθε μέλος της ομάδας. ́Ετσι υπάρχει ανάγκη για την ύπαρξη κάποιου είδους μηχανισμού ο οποίος θα παρακολουθεί τις αλλαγές, θα εμποδίζει τις συγκρούσεις μεταξύ διαφορετικών εκδόσεων ίδιων αρχείων και θα δίνει τη δυνατότητα να έχουν όλοι πρόσβαση σε οτιδήποτε νέο προστεθεί. Τέτοιου είδους μηχανισμοί ονομάζονται Συστήματα ∆ιαχείρισης Εκδόσεων (Version Control Systems – VCS). Τα συστήματα διαχείρισης εκδόσεων είναι συνήθως αυτόνομα προγράμματα τα οποία διαχειρίζονται πολλαπλές εκδόσεις ίδιων μονάδων πληροφορίας. Οι διαφορετικές εκδόσεις διαχωρίζονται μέσω κάποιου είδους αύξοντα αριθμού και συνοδεύονται από σχόλια που προσθέτει ο χρήστης και συνδέονται με το χρήστη που πραγματοποίησε τις αλλαγές.

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

Ολοκληρωμένα Περιβάλλοντα Ανάπτυξης Λογισμικού (IDEs)

Για τη δημιουργία κάποιου προγράμματoς σήμερα αυτό που είναι απαραίτητο είναι η ύπαρξη κάποιου είδους κειμενογράφου και ενός μεταγλωττιστή (compiler) ή διερμηνέα(interpreter) μέσω του οποίου θα είναι δυνατή η μετατροπή του κώδικα από υψηλού επιπέδου γλώσσα σε γλώσσα μηχανής. ́Ετσι, για παράδειγμα, για την ανάπτυξη μίας Java εφαρμογής σε ένα windows σύστημα αρκεί η ύπαρξη ενός σημειωματάριου (notepad) και η εγκατάσταση της επιθυμητής έκδοσης της Java Virtual Machine. Σε αυτήν την περίπτωση ο προγραμματιστής κατά την διάρκεια της ανάπτυξης της εφαρμογής του θα πρέπει να μεταγλωττίζει και να τρέχει την εφαρμογή μέσω της γραμμής εντολών ξανά και ξανά, έχοντας ως μόνο του βοηθό στην περίπτωση ύπαρξης κάποιου σφάλματος τα μηνύματα σφάλματος του μεταγλωττιστή. Αυτό σημαίνει την κατανάλωση πολύ χρόνου και κόπου ακόμη και για τις πιο απλές εφαρμογές. ́Οσο το μέγεθος και η πολυπλοκότητα των εφαρμογών (άρα και του κώδικα) αυξάνεται, τα μεγέθη αυτά αυξάνονται σχεδόν εκθετικά, πράγμα που καθιστά αυτή τη μέθοδο ανάπτυξης μη πρακτική.

Τη λύση σε αυτό το πρόβλημα δίνουν τα ολοκληρωμένα περιβάλλοντα ανάπτυξης λογισμικού (Integrated Development Environment) — ευρέως γνωστά ως IDEs. Τα IDEs είναι ολοκληρωμένες εφαρμογές μέσα στις οποίες μπορεί να πραγματοποιηθεί κάθε απαραίτητη διαδικασία για την ανάπτυξης μίας εφαρμογής.Οι συνηθέστερες λειτουργίες που παρέχονται είναι η συγγραφή του κώδικα, η τροποποίησή του, η μεταγλώττισή του, η εκτέλεσή του καθώς και κάποια διαδικασία εντοπισμού σφαλμάτων. Ο βασικός σκοπός τους είναι να περιορίσουν και κατά κάποιο τρόπο να κρύψουν όλες τις ρυθμίσεις που χρειάζονται για το συντονισμό των διαφορετικών κομματιών, ο συνδυασμός των οποίων είναι απαραίτητος για την επιτυχημένη εκτέλεση μίας εφαρμογής. Αυτό έχει σαν συνέπεια την ευκολότερη εκμάθηση μιας γλώσσας προγραμματισμού καθώς και την αύξηση της παραγωγικότητας.

Γνωστά IDEs

Τα τελευταία χρόνια έχουν αναπτυχθεί πολλά ολοκληρωμένα περιβάλλοντα ανάπτυξης λογισμικού. Μερικά από τα διασημότερα και ευρύτερα χρησιμοποιούμενα είναι το Visual Studio της Microsoft, το Eclipse, το NetBeans της Sun, και το IntelliJ IDEA της JetBrains. Η υλοποίηση της εφαρμογής που αναπτύχθηκε στα πλαίσια της παρούσας διπλωματικής εργασίας έγινε στο περιβάλλον ανάπτυξης IntelliJ. Τα βασικά σημεία και δυνατότητες αυτού περιγράφονται στην ακόλουθη ενότητα.

IntelliJ IDEA

Το IntelliJ είναι ένα αρκετά δημοφιλές εμπορικό ολοκληρωμένο περιβάλλον ανάπτυξης λογισμικού, κυρίως για Java εφαρμογές. Εκτός της Java παρέχει υποστήριξη και για άλλες γλώσσες προγραμματισμού όπως JavaScript, HTM- L/XHTML/CSS, XML/XSL, Ruby. Επιπλέον της ασικής έκδοση της Java υποστηρίζεται η χρήση πολλών τεχνολογιών και περιβάλλοντων εργασίας όπως Spring, Hibernate, Web Services, Struts, JSP, JSF, EJB, AJAX. Στο πακέτο παρέχεται ένας αναπτυγμένος κειμενογράφος ο οποίος προσφέρει κάποιες πολύ χρήσιμες υπηρεσίες. Τέτοιες είναι η αυτόματη παραγωγή κώδικα,η ανάλυση κώδικα κατά την ώρα πληκτρολόγησης, ο αυτόματος σχολιασμός σύμφωνα με το πρότυπο της Java και ο έλεγχος λαθών και πιθανών παραλήψεων κατά την ώρα πληκτρολόγησης.

Επιπλέον δίνεται η δυνατότητα χρήσης εργαλείων που βοηθούν την παρακολούθηση της πορείας ανάπτυξης του κώδικα καθ́ όλη τη διαδικασία παραγωγής. Υποστηρίζεται η χρήση αρκετών γνωστών συστημάτων διαχείρισης εκδόσεων (Version Control Systems), ενώ παράλληλα παρέχεται ένα ισχυρό εργαλείο παρακολούθησης της τοπικής ιστορίας. ∆ιευκολύνεται η χρήση δημοφιλών Java εργαλείων όπως το JUnit και το Ant, ενώ τέλος προσφέρεται ένα πολύ εύχρηστο περιβάλλον μεταγλώττισης, εκτέλεσης και αποσφαλμάτωσης (debugging).

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