ΠΕΡΙΕΧΟΜΕΝΑ 1 Η σηµασία της τεχνολογίας λογισµικού... 1 1.1 Τι σηµαίνει τεχνολογία λογισµικού;... 3 1.2 Πόσο επιτυχηµένοι ήµασταν µέχρι τώρα;... 7 1.3 Τι σηµαίνει "καλό λογισµικό";... 13 1.4 Ποιος αναλαµβάνει την τεχνολογία λογισµικού;... 22 1.5 Προσέγγιση από την πλευρά του συστήµατος... 25 1.6 Προσέγγιση από την πλευρά της σχεδίασης... 33 1.7 Τα µέλη της οµάδας ανάπτυξης... 40 1.8 Πώς µετεξελίχθηκε η τεχνολογία λογισµικού... 43 1.9 Παράδειγµα πληροφοριακού συστήµατος... 57 1.10 Παράδειγµα συστήµατος πραγµατικού χρόνου... 60 1.11 Η σηµασία αυτού του κεφαλαίου για σας... 63 1.12 Η σηµασία αυτού του κεφαλαίου για την οµάδα ανάπτυξης... 64 1.13 Η σηµασία αυτού του κεφαλαίου για τους ερευνητές... 64 1.14 Εργασία εξαµήνου... 65 1.15 Σηµαντικές πήγες αναφοράς... 68 1.16 Ασκήσεις... 69 2 Μοντελοποίηση διεργασιών και κύκλου ζωής λογισµικού... 73 2.1 Η σηµασία της έννοιας "διεργασία"... 74 2.2 Μοντέλα διεργασιών ανάπτυξης λογισµικού... 78 2.3 Εργαλεία και τεχνικές µοντελοποίησης διεργασιών... 96 2.4 Πρακτικές εφαρµογές της µοντελοποίησης διεργασιών... 105 2.5 Παράδειγµα πληροφοριακού συστήµατος... 110 2.6 Παράδειγµα συστήµατος πραγµατικού χρόνου... 113 2.7 Η σηµασία αυτού του κεφαλαίου για σας... 115 2.8 Η σηµασία αυτού του κεφαλαίου για την οµάδα ανάπτυξης... 116 2.9 Η σηµασία αυτού του κεφαλαίου για τους ερευνητές... 116 2.10 Εργασία εξαµήνου... 117 2.11 Σηµαντικές πηγές αναφοράς... 120 2.12 Ασκήσεις... 122
xviii Περιεχόµενα 3 Σχεδιασµός και διοίκηση του έργου... 124 3.1 Παρακολούθηση της προόδου... 124 3.2 Το προσωπικό του έργου... 142 3.3 Εκτίµηση προσπάθειας... 155 3.4 ιαχείριση κίνδυνων... 177 3.5 Το πλάνο του έργου... 184 3.6 Μοντέλα διεργασιών και διοίκηση έργων... 187 3.7 Παράδειγµα πληροφοριακού συστήµατος... 198 3.8 Παράδειγµα συστήµατος πραγµατικού χρόνου... 201 3.9 Η σηµασία αυτού του κεφαλαίου για σας... 203 3.10 Η σηµασία αυτού του κεφαλαίου για την οµάδα ανάπτυξης... 204 3.11 Η σηµασία αυτού του κεφαλαίου για τους ερευνητές... 204 3.12 Εργασία εξαµήνου... 205 3.13 Σηµαντικές πήγες αναφοράς... 205 3.14 Ασκήσεις... 206 4 Η εξαγωγή των απαιτήσεων... 210 4.1 Η διεργασία των απαιτήσεων... 211 4.2 Τύποι απαιτήσεων... 221 4.3 Τα χαρακτηριστικά των απαιτήσεων... 224 4.4 Τρόποι έκφρασης των απαιτήσεων... 227 4.5 Άλλες σηµειογραφίες απαιτήσεων... 248 4.6 Πρωτοτυποποίηση των απαιτήσεων... 259 4.7 Τεκµηρίωση των απαιτήσεων... 262 4.8 Οι συµµετέχοντες στη διεργασία απαιτήσεων... 266 4.9 Επικύρωση απαιτήσεων... 268 4.10 Μετρήσεις των απαιτήσεων... 270 4.11 Επιλογή τεχνικής για την προδιαγραφή απαιτήσεων... 274 4.12 Παράδειγµα πληροφοριακού συστήµατος... 280 4.13 Παράδειγµα συστήµατος πραγµατικού χρόνου... 282 4.14 Η σηµασία αυτού του κεφαλαίου για σας... 284 4.15 Η σηµασία αυτού του κεφαλαίου για την οµάδα ανάπτυξης... 285 4.16 Η σηµασία αυτού του κεφαλαίου για τους ερευνητές... 286 4.17 Εργασία εξαµήνου... 287 4.18 Σηµαντικές πήγες αναφοράς... 292 4.19 Ασκήσεις... 293
Περιεχόµενα xix 5 Η σχεδίαση του συστήµατος... 297 5.1 Ο ορισµός του σχεδίου... 297 5.2 Αποσύνθεση και τµηµατικότητα... 302 5.3 Στυλ και στρατηγικές στην αρχιτεκτονική... 305 5.4 Ζητήµατα στη δηµιουργία του σχεδίου... 318 5.5 Τα χαρακτηριστικά του καλού σχεδίου... 333 5.6 Τεχνικές για τη βελτίωση του σχεδίου... 350 5.7 Επαλήθευση και επικύρωση σχεδίασης... 362 5.8 Η τεκµηρίωση του σχεδίου... 375 5.9 Παράδειγµα πληροφοριακού συστήµατος... 377 5.10 Παράδειγµα συστήµατος πραγµατικού χρόνου... 380 5.11 Η σηµασία αυτού του κεφαλαίου για σας... 381 5.12 Η σηµασία αυτού του κεφαλαίου για την οµάδα ανάπτυξης... 381 5.13 Η σηµασία αυτού του κεφαλαίου για τους ερευνητές... 382 5.14 Εργασία εξαµήνου... 383 5.15 Σηµαντικές πήγες αναφοράς... 383 5.16 Ασκήσεις... 384 6 Αντικείµενα... 387 6.1 Προσανατολισµός σε αντικείµενα... 390 6.2 Η αντικειµενοστρεφής διεργασία ανάπτυξης... 395 6.3 Περιπτώσεις χρήσης... 399 6.4 Αντικειµενοστρεφής αναπαράσταση: Ένα παράδειγµα µε χρήση της UML... 406 6.5 Αντικειµενοστρεφής σχεδίαση συστήµατος... 408 6.6 Αντικειµενοστρεφής σχεδίαση προγραµµάτων... 427 6.7 Μετρήσεις στα αντικειµενοστρεφή συστήµατα... 439 6.8 Παράδειγµα πληροφοριακού συστήµατος... 452 6.9 Παράδειγµα συστήµατος πραγµατικού χρόνου... 454 6.10 Η σηµασία αυτού του κεφαλαίου για σας... 454 6.11 Η σηµασία αυτού του κεφαλαίου για την οµάδα ανάπτυξης... 455 6.12 Η σηµασία αυτού του κεφαλαίου για τους ερευνητές... 455 6.13 Εργασία εξαµήνου... 456 6.14 Σηµαντικές πήγες αναφοράς... 456 6.15 Ασκήσεις... 457
xx Περιεχόµενα 7 Η συγγραφή των προγραµµάτων... 458 7.1 Πρότυπα και διαδικασίες προγραµµατισµού... 459 7.2 Κατευθυντήριες γραµµές προγραµµατισµού... 463 7.3 Τεκµηρίωση... 477 7.4 Παράδειγµα πληροφοριακού συστήµατος... 484 7.5 Παράδειγµα συστήµατος πραγµατικού χρόνου... 486 7.6 Η σηµασία αυτού του κεφαλαίου για σας... 487 7.7 Η σηµασία αυτού του κεφαλαίου για την οµάδα ανάπτυξης... 488 7.8 Η σηµασία αυτού του κεφαλαίου για τους ερευνητές... 488 7.9 Εργασία εξαµήνου... 489 7.10 Σηµαντικές πήγες αναφοράς... 489 7.11 Ασκήσεις... 490 Ευρετήριο... 493
Κεφάλαιο 5: Η σχεδίαση του συστήµατος 333 σχεδίου θα αποφασίσουµε για τον τρόπο που θα χειριστούµε τον µη ντετερµινισµό. Πρότυπα σχεδίων και επαναχρησιµοποίηση Πολύ συχνά, σχεδιάζουµε και κατασκευάζουµε συστήµατα που είναι παρόµοια σε ορισµένα σηµεία µε άλλα συστήµατα που έχουµε κατασκευάσει στο παρελθόν. Για παράδειγµα, κατασκευάζουµε µερικές φορές µια σειρά από συστήµατα ελέγχου για εγκαταστάσεις επεξεργασίας υγρών λυµάτων κάθε σύστηµα είναι µια βελτίωση ή αντικατάσταση, του προηγουµένου. Άλλες φορές, σχεδιάζουµε και κατασκευάζουµε µια σειρά εφαρµογών που έχουν παρόµοια λειτουργικότητα αλλά πρέπει να εκτελεστούν σε διαφορετικά περιβάλλοντα τα έτοιµα εµπορικά προϊόντα όπως τα συστήµατα διαχείρισης βάσεων δεδοµένων ή τα συστήµατα ηλεκτρονικού ηµερολογίου σχεδιάζονται συνήθως µε αυτό τον τρόπο. Άρα, θέλουµε να εκµεταλλευτούµε την οµοιότητα ανάµεσα σε ορισµένα συστήµατα, ώ- στε να µη χρειάζεται να αναπτύξουµε τα καινούργια συστήµατα από την αρχή. Ένας δηµοφιλής τρόπος αναγνώρισης των οµοιοτήτων είναι να εξετάσουµε την ύπαρξη προτύπων σχεδίων. Μπορούµε τότε να χρησιµοποιήσουµε ξανά τα πρότυπα, όπως και τον κώδικα, του ελέγχους και τα έγγραφα που σχετίζονται µε αυτά, όταν κατασκευάσουµε το επόµενο παρόµοιο σύστηµα. Ένα πρότυπο ή υπόδειγµα σχεδίου (design pattern) ονοµάζει, εξετάζει αφαιρετικά, και αναγνωρίζει τις κρίσιµες πλευρές µιας κοινής δοµής σχεδίου που είναι χρήσιµη για τη δηµιουργία ενός επαναχρησιµοποιήσιµου... σχεδίου. Το πρότυπο σχεδίου α- ναγνωρίζει τις συµµετέχουσες κλάσεις και στιγµιότυπα, τους ρόλους και τις συνεργασίες τους, και την κατανοµή των ευθυνών (Gamma κ.α., 1995). Όπως θα δούµε σε επόµενα κεφάλαια, στην ιδανική περίπτωση θέλουµε να χρησιµοποιήσουµε ξανά τα σχέδια όπως ακριβώς έχουν, χωρίς καµιά τροποποίηση, συχνά όµως πρέπει να αλλάξουµε το σχέδιο για να ταιριάζει µε τις απαιτήσεις και τους περιορισµούς του τρέχοντος συστήµατος, οι οποίοι διαφέρουν από τους αντίστοιχους των προηγουµένων συστηµάτων. Άρα, είναι σηµαντικό να κατασκευάζουµε πρότυπα σχεδίων µε τρόπους που δεν τα συνδέουν τόσο στενά µε τις ιδιαιτερότητες ενός συγκεκριµένου συστήµατος. Αυτό σηµαίνει ότι, ενώ υλοποιούµε τις απαιτήσεις του τρέχοντος συστήµατος, επιθυµούµε παράλληλα να µεγιστοποιήσουµε τις δυνατότητες επαναχρησιµοποίησης του σχεδίου µας. 5.5 ΤΑ ΧΑΡΑΚΤΗΡΙΣΤΙΚΑ ΤΟΥ ΚΑΛΟΥ ΣΧΕ ΙΟΥ Στο Κεφάλαιο 1 εξετάσαµε διάφορα µοντέλα ποιότητας λογισµικού και βρήκαµε τα χαρακτηριστικά που είναι επιθυµητά για τα προϊόντα που κατασκευάζουµε. Καθώς σχεδιάζουµε ένα σύστηµα, επιθυµούµε να εξασφαλίσουµε ότι περιλαµβά-
334 Τεχνολογία λογισµικού νονται κάποια από αυτά τα χαρακτηριστικά ποιότητας. Τα σχέδια υψηλής ποιότητας πρέπει να διαθέτουν χαρακτηριστικά που οδηγούν σε ποιοτικά προϊόντα: ευκολία κατανόησης, ευκολία υλοποίησης, ευκολία ελέγχου, ευκολία τροποποιήσεων, και σωστή µετάφραση από την προδιαγραφή των απαιτήσεων. Η ευκολία τροποποίησης είναι εξαιρετικά σηµαντική, καθώς οι αλλαγές στις απαιτήσεις ή οι αλλαγές που χρειάζονται για τη διόρθωση των σφαλµάτων µερικές φορές οδηγούν στην αλλαγή του σχεδίου. Στην παρούσα ενότητα, εξετάζουµε µε περισσότερες λεπτοµέρειες τα χαρακτηριστικά που αντανακλούν την ποιότητα της σχεδίασης. Ανεξαρτησία των συστατικών του σχεδίου Η αφαίρεση και η απόκρυψη πληροφοριών µας επιτρέπουν να εξετάσουµε τους τρόπους µε τους οποίους τα συστατικά σχετίζονται µεταξύ τους στα πλαίσια του συνολικού σχεδίου. Το Θέµα 5.4 περιγράφει τον τρόπο που θέµατα που αφορούν τον έλεγχο των συστατικών µπορούν να ληφθούν υπόψη στα σχέδιά µας. Προσπαθούµε στα περισσότερα σχέδια να καταστήσουµε ανεξάρτητα τα συστατικά µεταξύ τους. Με αυτό τον τρόπο είναι ευκολότερο να κατανοήσουµε τον τρόπο λειτουργίας ενός συστατικού (εάν δεν συνδέεται περίπλοκα µε τα υπόλοιπα), αλλά ταυτόχρονα είναι πολύ ευκολότερο να τροποποιηθεί ένα ανεξάρτητο συστατικό. Παροµοίως, όταν προσπαθούµε να βρούµε τις αιτίες δυσλειτουργίας του συστήµατος προχωρώντας προς τα πίσω από τον κώδικα στο σχέδιο, τα ανεξάρτητα συστατικά µπορούν να µας βοηθήσουν να αποµονώσουµε και να διορθώσουµε την αιτία. Εικόνα 5.12 Σύζευξη συστατικών
Κεφάλαιο 5: Η σχεδίαση του συστήµατος 335 Για να αναγνωρίσουµε και να µετρήσουµε το βαθµό της ανεξαρτησίας των συστατικών σε ένα σχέδιο, χρησιµοποιούµε δύο έννοιες: τη σύζευξη και τη συνεκτικότητα (Yourdon και Constantine 1978). Σύζευξη (coupling). Λέµε ότι δύο συστατικά υπόκεινται σε υψηλή σύζευξη (highly coupled) όταν υπάρχει µεγάλος βαθµός εξάρτησης µεταξύ τους. Τα συστατικά µε χαλαρή σύζευξη (loosely coupled) εξαρτώνται σε κάποιο βαθµό, αλλά οι διασυνδέσεις ανάµεσά τους είναι λίγες. Τα µη συζευγµένα (uncoupled) συστατικά δε διαθέτουν καθόλου διασυνδέσεις είναι εντελώς ανεξάρτητα, όπως φαίνεται στην Εικόνα 5.12. Υπάρχουν πολλοί τρόποι εξάρτησης των συστατικών µεταξύ τους, εποµένως η σύζευξη εξαρτάται από διάφορα πράγµατα: Τις αναφορές που γίνονται από το ένα συστατικό στα υπόλοιπα. Για παράδειγµα, το συστατικό Α µπορεί να καλεί το συστατικό Β, εποµένως το συστατικό Α εξαρτάται από το συστατικό Β όσον αφορά την ολοκλήρωση της λειτουργίας ή της διεργασίας του. Την ποσότητα δεδοµένων που περνούν από το ένα συστατικό στα υπόλοιπα. Για παράδειγµα, το συστατικό Α µπορεί να περνά µια παράµετρο, τα περιεχόµενα ενός πίνακα, ή ένα µπλοκ δεδοµένων, στο συστατικό Β. Την ποσότητα ελέγχου που ένα συστατικό εξασκεί επί των άλλων. Για παράδειγµα, το συστατικό Α µπορεί να περνά µια σηµαία ελέγχου στο στοιχείο Β. Η τιµή αυτής της σηµαίας προσδιορίζει στο συστατικό Β την κατάσταση κάποιου πόρου ή υποσυστήµατος, τη διεργασία που πρέπει να καλέσει ή το αν πρέπει να καλέσει τελικά κάποια διεργασία. Το βαθµό πολυπλοκότητας στη διασύνδεση ανάµεσα στα συστατικά. Για παράδειγµα, το συστατικό Α περνά µια παράµετρο στο συστατικό Β, για να το καθοδηγήσει στην εκτέλεσή του. Όµως, τα συστατικό Γ και ανταλλάσσουν τιµές πριν το να ολοκληρώσει την εκτέλεσή του, εποµένως η διασύνδεση ανάµεσα στα Α και Β είναι λιγότερο περίπλοκη σε σχέση µε αυτή των Γ και. Η χρήση ενός αποµονωτή ή ενός φρουρού είναι ακόµη πιο περίπλοκη. Εποµένως, µπορούµε να µετρήσουµε τη σύζευξη µε βάση ένα εύρος εξαρτήσεων, από την πλήρη εξάρτηση έως την πλήρη ανεξαρτησία, όπως φαίνεται στην Εικόνα 5.13. Στην πραγµατικότητα, είναι απίθανο ένα σύστηµα να κατασκευαστεί µε βάση αποκλειστικά µη συζευγµένα συστατικά. Μπορούµε να σκεφτούµε την περίπτωση ενός τραπεζιού και των καρεκλών που το περιβάλλουν: παρά το γεγονός
336 Τεχνολογία λογισµικού Εικόνα 5.13 Το εύρος των µετρικών σύζευξης ότι τα συστατικό αυτά είναι ανεξάρτητα µεταξύ τους, µπορούν να συνδυαστούν για να δηµιουργηθεί ένα σύνολο τραπεζαρίας, από φαινοµενικά µη συζευγµένα συστατικά τα οποία όµως συνδέονται έµµεσα. Άρα, ο στόχος µας δεν είναι απαραίτητα η πλήρης ανεξαρτησία, αλλά αντιθέτως είναι µάλλον η διατήρηση του βαθµού σύζευξης όσο το δυνατόν σε χαµηλότερα επίπεδα. Αυτό σηµαίνει ότι, θέλουµε να ε- λαχιστοποιήσουµε την εξάρτηση ανάµεσα στα συστατικά, καθώς υπάρχουν σοβαροί λόγοι για να υιοθετήσουµε αυτή την τακτική. Αν ένα στοιχείο επηρεάζεται από µια ενέργεια του συστήµατος, θέλουµε πάντα να γνωρίζουµε πιο συστατικό προκάλεσε το αντίστοιχο γεγονός σε µια δεδοµένη χρονική στιγµή. Αυτή η γνώση µας ε- πιτρέπει να αλλάξουµε ένα τµήµα του σχεδίου του συστήµατος χωρίς να επιφέρου- µε µεγάλη αναστάτωση (όσο αυτό είναι δυνατόν). Για παράδειγµα, ας υποθέσουµε ότι στη διόρθωση ενός σφάλµατος ή στην αντιµετώπιση µιας αλλαγής των απαιτήσεων του πελάτη, αποφασίζουµε ότι µια λειτουργία ή ένας τύπος δεδοµένων πρέπει να αντικατασταθεί από κάτι άλλο. Στην ιδανική περίπτωση, θα θέλαµε απλούστατα να αλλάξουµε το παλιό συστατικό µε το καινούργιο. Αν έχουµε ένα αρθρωτό σχέδιο µε χαλαρή σύνδεση ανάµεσα στα συστατικά, τότε το σενάριο απλής εισαγωγής και εξαγωγής συστατικών µπορεί να εφαρµοστεί θαυµάσια. Αν η σύζευξη είναι χαλαρή τότε µόνο ελάχιστα άλλα συστατικά θα επηρεαστούν από την αλλαγή και θα είναι υποψήφια για τροποποίηση ή αντικατάσταση. Αν όµως η σύζευξη είναι υψηλή, τότε µεγάλα τµήµατα του συστήµατος θα διαταραχτούν από την αλλαγή. Επο- µένως, η χαλαρή σύζευξη µας βοηθά να ελαχιστοποιήσουµε τον αριθµό των συστατικών που χρειάζονται αναθεώρηση. Μερικοί τύποι σύζευξης είναι λιγότερο επιθυµητοί από τους υπόλοιπους. Ο λιγότερο επιθυµητός τύπος προκύπτει όταν ένα συστατικό τροποποιεί στην πραγ- µατικότητα ένα άλλο. Τότε το τροποποιηµένο συστατικό εξαρτάται πλήρως από
Κεφάλαιο 5: Η σχεδίαση του συστήµατος 337 Εικόνα 5.14 Παράδειγµα σύζευξης περιεχοµένου αυτό που το τροποποιεί. Αυτή η σχέση ονοµάζεται σύζευξη περιεχοµένου (content coupling). Η σύζευξη περιεχοµένου µπορεί να προκύψει όταν ένα συστατικό τροποποιεί ένα εσωτερικό δεδοµένο σε κάποιο άλλο στοιχείο ή όταν ένα συστατικό διακλαδώνεται στο µέσο ενός άλλου συστατικού. Στην Εικόνα 5.14, το συστατικό B διακλαδώνεται µέσα στο D, παρά το γεγονός το D υποτίθεται ότι βρίσκεται υπό τον έλεγχο του C. Μπορούµε να µειώσουµε κάπως τη σύζευξη οργανώνοντας το σχέδιό µας έτσι ώστε τα δεδοµένα να είναι προσπελάσιµα µέσω ενός κοινού αποθηκευτικού χώρου δεδοµένων. Ωστόσο, υπάρχει ακόµη και σε αυτή την περίπτωση εξάρτηση, καθώς µια αλλαγή στα κοινά δεδοµένα σηµαίνει ότι οδηγούµαστε πίσω σε όλα τα στοιχεία τα οποία προσπελαύνουν αυτά τα δεδοµένα για να εκτιµήσουµε τα αποτελέσµατα αυτής της αλλαγής. Αυτό το είδος εξάρτησης ονοµάζεται σύζευξη κοινών δεδοµένων (common coupling). Στη σύζευξη κοινών δεδοµένων, µπορεί να είναι δύσκολο να εξακριβώσουµε ποιο συστατικό είναι υπεύθυνο για τον ορισµό της τιµής µιας συγκεκριµένης τιµής σε µια µεταβλητή. Η Εικόνα 5.15 επεξηγεί τον τρόπο εργασίας της σύζευξης κοινών δεδοµένων. Όταν ένα συστατικό περνά παραµέτρους για να ελέγξει τη δραστηριότητα ενός άλλου συστατικού, λέµε ότι πρόκειται για σύζευξη ελέγχου (control coupling) ανάµεσα σε αυτά τα δύο. Το ελεγχόµενο συστατικό είναι αδύνατον να λειτουργήσει χωρίς καθοδήγηση του ελέγχοντος συστατικού. Σε ένα σχέδιο µε σύζευξη ελέγχου, υπάρχει πλεονέκτηµα εάν κάθε συστατικό εκτελεί µόνο µια λειτουργία ή µια διεργασία. Αυτός ο περιορισµός ελαχιστοποιεί την ποσότητα
338 Τεχνολογία λογισµικού Εικόνα 5.15 Παράδειγµα σύζευξης κοινών δεδοµένων των πληροφοριών ελέγχου που πρέπει να περάσουν από το ένα συστατικό στο άλλο και εντοπίζει τον έλεγχο σε ένα σταθερό και αναγνωρίσιµο σύνολο παραµέτρων που δηµιουργούν µια καλά ορισµένη διασύνδεση. Όταν µια δοµή δεδοµένων χρησιµοποιείται για να περάσουν πληροφορίες από ένα συστατικό σε ένα άλλο, και περνά η ίδια η δοµή δεδοµένων, έχουµε σύζευξη αντιγράφου (stamp coupling) ανάµεσα στα στοιχεία αν περνούν µόνο δεδοµένα, τα στοιχεία συνδέονται µε σύζευξη δεδοµένων (data coupling). Στη σύζευξη αντιγράφου, οι τιµές, η µορφή, και η οργάνωση των δεδοµένων πρέπει να ταιριάζουν στα συστατικά που αλληλεπιδρούν. Εποµένως, η σύζευξη δεδοµένων είναι απλούστερη και αφήνει λιγότερα περιθώρια για λάθη. Αν πρέπει να υπάρχει σύζευξη ανάµεσα στα συστατικά ο πιο επιθυµητός τύπος είναι η σύζευξη αντιγράφου είναι ο ευκολότερος τρόπος για να γίνεται ιχνηλάτιση των δεδοµένων και να πραγµατοποιούνται αλλαγές. Τα συστατικά σε µια αντικειµενοστρεφή σχεδίαση έχουν συνήθως µικρή σύζευξη, καθώς ο ορισµός κάθε συστατικού (αντικειµένου) περιέχει τους ορισµούς των πράξεων που γίνονται από αυτό (και επί αυτού). Εποµένως, η µικρή σύζευξη είναι ένα αυτόµατο όφελος της αντικειµενοστρεφούς προσέγγισης. Συνεκτικότητα (cohesion). Αντί να µετράται η αµοιβαία εξάρτηση των στοιχείων, η συνεκτικότητα αναφέρεται στην εσωτερική "συνοχή" µε βάση την οποία κατασκευάζεται ένα συστατικό. Όσο πιο συνεκτικό είναι ένα συστατικό, τόσο πιο πολύ σχετίζονται τα εσωτερικά µέρη του συστατικού µεταξύ τους και
Κεφάλαιο 5: Η σχεδίαση του συστήµατος 339 εξυπηρετούν το συνολικό σκοπό του. Με άλλα λόγια, ένα συστατικό είναι συνεκτικό αν όλα τα τµήµατά του προορίζονται και είναι απαραίτητα για την εκτέλεση της ίδιας εργασίας. Οι αρχικοί ορισµοί αυτών των επιπέδων βασίζονται στις έννοιες της λειτουργικής αποσύνθεσης. Ένας κοινός στόχος της σχεδίασης ήταν να γίνει κάθε συστατικό όσο συνεκτικότερο γίνεται, έτσι ώστε κάθε τµήµα της επεξεργασίας ενός συστατικού να σχετίζεται µε τη µία και µοναδική λειτουργία του συστατικού. Μπορούµε να γενικεύσουµε αυτή την ιδέα ώστε να εφαρµοστεί σε κάθε τύπο αποσύνθεσης. Αυτό σηµαίνει ότι, µπορούµε να δηµιουργήσουµε επίπεδα συνεκτικότητας για τα συστατικά, ανεξάρτητα µε τον τρόπο που έχει δηµιουργηθεί η αποσύνθεση. Η Εικόνα 5.16 παρουσιάζει τους διάφορους τύπους συνεκτικότητας. Ο χειρότερος τύπος συνεκτικότητας, η συµπτωµατική (coincidental), εµφανίζεται σε ένα συστατικό του οποίου τα τµήµατα δε σχετίζονται µεταξύ τους. Σε αυτή την περίπτωση, άσχετες λειτουργίες, διεργασίες, ή δεδοµένα βρίσκονται στο ίδιο συστατικό για λόγους άνεσης και εύκολης εύρεσης. Για παράδειγµα, ένα συστατικό που ελέγχει την κατηγορία ασφαλείας ενός χρήστη και τυπώνει επίσης τη µισθοδοσία της τρέχουσας εβδοµάδας είναι συµπτωµατικά συνεκτικό. Το επόµενο επίπεδο αποτελείται από την λογική (logical) συνεκτικότητα (η οποία επίσης δεν είναι επιθυµητή), όπου διάφορες λογικά σχετιζόµενες συναρτήσεις ή δεδοµένα τοποθετούνται στο ίδιο συστατικό. Για παράδειγµα, ένα συστατικό µπορεί να διαβάζει όλα τα είδη εισόδου (από ταινία, δίσκο, και θύρα τηλεπικοινωνιών), ανεξάρτητα από την πηγή της εισόδου ή τον τρόπο χρήσης της "η είσοδος" είναι η κόλλα που συνδέει τα µέρη αυτού του συστατικού. Παρά το γεγονός ότι είναι περισσότερο σωστή από τη συµπτωµατική συνεκτικότητα, τα Εικόνα 5.16 Τύποι συνεκτικότητας
340 Τεχνολογία λογισµικού τµήµατα ενός λογικά συνεκτικού συστατικού δε σχετίζονται λειτουργικά. Στο παράδειγµά µας, καθώς η είσοδος µπορεί να εξυπηρετεί διαφορετικούς σκοπούς για διαφορετικά συστατικά, εκτελούµε πολλές ασυσχέτιστες λειτουργίες σε ένα σηµείο. Μερικές φορές χρησιµοποιείται ένα συστατικό για να αρχικοποιηθεί ένα σύστηµα ή ένα σύνολο µεταβλητών. Ένα τέτοιο στοιχείο εκτελεί διάφορες λειτουργίες στη σειρά, αλλά οι λειτουργίες σχετίζονται µόνο µε βάση τη χρονική περίοδο στην οποία εκτελούνται, εποµένως αυτή η συνεκτικότητα είναι χρονική (temporal). Τόσο τα συστατικά µε χρονική συνεκτικότητα όσο και τα συστατικά µε λογική συνεκτικότητα αλλάζουν πολύ δύσκολα. Ας υποθέσουµε ότι πρέπει να τροποποιήσετε το σχέδιο της λειτουργίας Χ ενός συστήµατος. Επειδή τα συστατικά που έχουν λογική ή χρονική συνεκτικότητα εκτελούν πολλές διαφορετικές λειτουργίες, για να αλλάξει η λειτουργία Χ, πρέπει να εξεταστούν όλα τα συστατικά για να βρεθούν τα µέρη τους που σχετίζονται µε την Χ. Πολύ συχνά, πρέπει να εκτελούνται κάποιες λειτουργίες µε συγκεκριµένη σειρά. Για παράδειγµα, τα δεδοµένα πρέπει να εισαχθούν πριν ελεγχθούν και γίνουν κάποιοι υπολογισµοί που τα αφορούν: πρόκειται για τρεις λειτουργίες µε βάση µια συγκεκριµένη ακολουθία. Όταν οι λειτουργίες οµαδοποιούνται σε ένα συστατικό µόνο για να εξασφαλιστεί αυτή η σειρά, αυτό το συστατικό είναι διαδικασιακά συνεκτικό (procedurally cohesive). Εναλλακτικά, µπορούµε να συσχετίσουµε συγκεκριµένες λειτουργίες επειδή παράγουν το ίδιο σύνολο δεδοµένων ή ενεργούν επί αυτού. Για παράδειγµα, µερικές φορές ασυσχέτιστα δεδοµένα προσκοµίζονται µαζί επειδή η µεταφορά αυτή µπορεί να γίνει µε µία µόνο προσπέλαση δίσκου ή ταινίας. Τα στοιχεία που κατασκευάζονται µε αυτό τον τρόπο είναι επικοινωνιακώς συνεκτικά (communicationally cohesive). Ωστόσο, η επικοινωνιακή συνεκτικότητα καταστρέφει συχνά την τµηµατικότητα και τη λειτουργική ανεξαρτησία του σχεδίου. Αν η έξοδος από ένα τµήµα ενός συστατικού παράγει την είσοδο για το ε- πόµενο τµήµα, το συστατικό διαθέτει ακολουθιακή συνεκτικότητα (sequential cohesion). Επειδή και πάλι το στοιχείο δεν έχει κατασκευαστεί µε βάση λειτουργικές σχέσεις, υπάρχει η πιθανότητα να µην περιέχει όλη την επεξεργασία που σχετίζεται µε µία λειτουργία. Την ιδανική περίπτωση αποτελεί η λειτουργική συνεκτικότητα (functional cohesion), όπου κάθε τµήµα επεξεργασίας είναι απαραίτητο για την απόδοση µιας µόνο λειτουργίας, και όλα αυτά τα θεµελιώδη τµή- µατα περιέχονται σε ένα στοιχείο. Ένα λειτουργικώς συνεκτικό στοιχείο εκτελεί µόνο τη λειτουργία για την οποία έχει σχεδιαστεί, και ταυτόχρονα δεν κάνει απολύτως τίποτα άλλο. Η Εικόνα 5.17 παρουσιάζει παραδείγµατα των διάφορων τύπων συνεκτικότητας.
Κεφάλαιο 5: Η σχεδίαση του συστήµατος 341 Εικόνα 5.17 Παραδείγµατα συνεκτικότητας. Η έννοια της συνεκτικότητας µπορεί να επεκταθεί σε αντικειµενοστρεφή και άλλα σχέδια όπου τα συστατικά βασίζονται σε δεδοµένα ή γεγονότα τα οποία αφορούν το συνολικό σκοπό: να τοποθετηθούν τα αντικείµενα και οι ενέργειες µαζί µόνο όταν υπάρχει ένας κοινός και λογικός σκοπός. Για παράδειγµα, λέµε ότι ένα συστατικό αντικειµενοστρεφούς σχεδίου είναι συνεκτικό αν κάθε χαρακτηριστικό, µέθοδος, ή ενέργεια είναι θεµελιώδης για το αντικείµενο. Τα αντικει- µενοστρεφή συστήµατα έχουν συχνά σχέδια µε υψηλή συνεκτικότητα, επειδή η διεργασία σύνθεσης του σχεδίου εξαναγκάζει τις ενέργειες να τοποθετούνται µαζί µε τα αντικείµενα που επηρεάζουν. Αναγνώριση και χειρισµός εξαιρέσεων Όταν µαθαίνουµε να οδηγούµε ένα αυτοκίνητο, ο δάσκαλος µας τονίζει ότι πρέπει να οδηγούµε "αµυντικά". Αυτό σηµαίνει ότι, έχουµε ένα ενεργό ρόλο, όχι µόνο για να αποκρινόµαστε στα συµβάντα καθώς αυτά προκύπτουν, αλλά ταυτόχρονα για να λαµβάνουµε προφυλάξεις καθώς η τρέχουσα κατάσταση µπορεί να γίνει επικίνδυνη, ενώ παίρνουµε τα κατάλληλα µέτρα για να αποφύγουµε τα προβλήµατα. Με
342 Τεχνολογία λογισµικού ΘΕΜΑ 5.4 ΖΗΤΗΜΑΤΑ ΕΛΕΓΧΟΥ Στις περισσότερες σχεδιάσεις, πρέπει να αποφασίσουµε για τον αριθµό των συστατικών που βρίσκονται υπό τον έλεγχο κάποιου άλλου συστατικού. Στο σχεδιάγραµµα δοµής για το σύστηµα 1 στην Εικόνα 5.18 ένα βέλος συνδέει ένα συστατικό µε ένα άλλο µόνο αν το πρώτο συστατικό µπορεί να καλέσει το δεύτερο. Για κάποιο συγκεκριµένο συστατικό, το σύνολο των συστατικών προς τα οποία σχεδιάζονται βέλη ο- νοµάζεται εύρος ελέγχου (scope of control) για το συγκεκριµένο συστατικό. Τα συστατικά που καλούνται από το συγκεκριµένο συστατικό αυτό καλούνται όλα µαζί εύρος επίδρασης (scope of effect). Κανένα συστατικό δε µπορεί να βρίσκεται στο εύρος επίδρασης αν δε βρίσκεται στο εύρος ελέγχου. Αν το εύρος επίδρασης ενός συστατικού είναι µεγαλύτερο από το εύρος ελέγχου του, είναι σχεδόν αδύνατο να εξασφαλιστεί ότι µια αλλαγή στο συστατικό δεν θα καταστρέψει ολόκληρο το σχέδιο. Ας θεωρήσουµε τα συστήµατα 1 και 2 ως δύο πιθανά σχέδια για το ίδιο σύστη- µα. Το πλήθος εισόδων (fan-in) είναι ο αριθµός των συστατικών που ελέγχουν ένα συγκεκριµένο συστατικό, και το πλήθος εξόδων (fan-out) είναι ο αριθµός των συστατικών που ελέγχονται από κάποιο συστατικό. Εποµένως, το συστατικό Α έχει πλήθος εξόδων 3 στο σύστηµα 1, αλλά πλήθος εξόδων 5 στο σύστηµα 2. Παροµοίως, το εύρος εισόδων για το στοιχείο C και στα δυο συστήµατα είναι 1. Ποιο είναι το καλύτερο σχέδιο; Στη γενική περίπτωση θέλουµε να ελαχιστοποιήσουµε τον αριθµό των συστατικών που έχουν υψηλό πλήθος εξόδων. Αν ένα συστατικό ελέγχει πολλά άλλα συστατικά, συνήθως κάνει περισσότερα από όσα πρέπει το συστατικό που ελέγχει τα άλλα εκτελεί πιθανότατα περισσότερες από µία λειτουργίες. Εποµένως, το σύστηµα 1 µπορεί να διαθέτει καλύτερο σχέδιο από το σύστηµα 2 επειδή τα συστατικά του έχουν χαµηλότερο πλήθος εξόδων. Από την άλλη µεριά, καθώς αυξάνουµε τον αριθµό των επιπέδων στο σχέδιο, µερικές φορές επιθυµούµε να χρησιµοποιήσουµε ένα συγκεκριµένο συστατικό περισσότερες από µία φορές. Για παράδειγµα, σε πολλές περιπτώσεις, µπορεί να χρειαστεί να ψάξουµε σε ένα αλφαριθµητικό για έναν συγκεκρι- µένο χαρακτήρα. Αν σχεδιάσουµε ένα συστατικό γενικού σκοπού για να επιτελεί αυτή την εργασία, και στη συνέχεια καλούµε αυτό το συστατικό από πολλά άλλα, το σχέδιο που προκύπτει είναι πολύ αποτελεσµατικό και πιο εύκολα ελέγξιµο και τροποποιήσιµο σε σχέση µε ένα άλλο που διαθέτει πάρα πολλές παρόµοιες συναρτήσεις που ψάχνουν αλφαριθµητικά. Εποµένως, για ένα σχέδιο που έχει µεγάλο αριθµό επιπέδων µπορούµε να δηµιουργήσουµε ένα σύνολο από συστατικά-βοηθήµατα (utility components): πρόκειται για εργαλεία ή δοµικά στοιχεία τα οποία χρησιµοποιούνται από άλλα συστατικά για να εκτελούνται εργασίες που γίνονται συχνά. Ένα τυπικό βοηθητικό συστατικό διαθέτει υψηλό πλήθος εισόδων επειδή καλείται από πολλά άλλα συστατικά. Ένας από τους στόχους στη σχεδίαση συστηµάτων είναι να δηµιουργούνται συστατικά µε υψηλό πλήθος εισόδων και χαµηλό πλήθος εξόδων.