Εισαγωγή στη Unified Modeling Language - UML Βασίλης Γερογιάννης
Εισαγωγικές έννοιες & Διαγράμματα Περιπτώσεων Χρήσης Βασίλης Γερογιάννης
Τι είναι η UML Η UML αποτελεί μία γλώσσα απεικόνισης ή μοντελοποίησης ενός πληροφοριακού συστήματος βασισμένου σε αντικείμενα (αντικειμενοστραφούς συστήματος). H UML αποτελεί την πρότυπη (standard) γλώσσα μοντελοποίησης αντικειμενοστραφών συστημάτων. Η UML αποτελεί πρότυπο του OMG (Object Management Group – www.omg.org).
Γιατί μοντελοποιούμε συστήματα πληροφορικής; Η μοντελοποίηση ενός συστήματος παρέχει την δυνατότητα της αφαίρεσης των ασήμαντων με αυτό λεπτομερειών και της εστίασης στις σημαντικές λεπτομέρειες του συστήματος την δυνατότητα του πειραματισμού με διαφορετικές λύσεις ή προσεγγίσεις για το ίδιο πρόβλημα την δυνατότητα ανάλυσης, σχεδιασμού, καταγραφής και παρακολούθησης της προόδου ενός έργου πληροφορικής μία κοινή γλώσσα για την επικοινωνία όσων εμπλέκονται στην κατασκευή του συστήματος Χωρίς ένα μοντέλο δεν είναι δυνατόν να προσεγγίσει κανείς την πολυπλοκότητα των σύγχρονων πληροφοριακών συστημάτων
Γιατί Αντικειμονοστραφές Λογισμικό; Το αντικειμενοστραφές λογισμικό είναι ευκολότερο στην αρχική του σύλληψη μια και τα αντικείμενα είναι – εν μέρει – οντότητες του υπαρκτού κόσμου Το αντικειμενοστραφές λογισμικό είναι ευκολότερο στην εξέλιξή του. Η αντικειμενοστραφής προσέγγιση επιτρέπει την δημιουργία λογισμικού με βάση τα συστατικά (components) Σύγχρονες τεχνολογίες κατασκευής κατανεμημένων συστημάτων προσανατολισμένων στην σύνδεση επιχειρήσεων (Business-to-business – B2B) και στην σύνδεση επιχειρηματικών εφαρμογών (Enterprise Application Integra-tion – EAI), όπως οι Υπηρεσίες του παγκόσμιου ιστού (Web Services), έχουν σαν τεχνολογικό υπόβαθρο αντικειμενοστραφείς γλώσσες προγραμματισμού (π.χ. Java, C#).
Μεθοδολογίες Ανάπτυξης Λογισμικού Μία μεθοδολογία ανάπτυξης λογισμικού παρέχει μία συστηματική προσέγγιση στην διαδικασία ανάλυσης, σχεδίασης, κατασκευής και εξέλιξης ενός έργου πληροφορικής. Είναι μία σειρά σταδίων τα οποία περιγράφουν συγκεκριμένες εργασίες. Η UML είναι ουδέτερη σε σχέση με τις μεθοδολογίες χωρίς να επιβάλλει κάποια συγκεκριμένη μεθοδολογία Υπάρχουν πολλές μεθοδολογίες ανάπτυξης λογισμικού (όπως η Unified Process, eXtreme Programming, Catalysis, Syntropy κοκ.). Κάθε μία από αυτές θεωρείται πως είναι πιο κατάλληλη για κάποιον συγκεκριμένο τύπο λογισμικού, για παράδειγμα η Catalysis θεωρείται πως είναι πιο κατάλληλη για συστήματα βασισμένα σε συστατικά (component based systems)
Η Ενοποιημένη Προσέγγιση Ίσως η πιο διαδεδομένη μεθοδολογία είναι η Ενοποιημένη Προσέγγιση (Unified Process ή εν συντομία UP). Η UP αναπτύχθηκε αρχικά από την εταιρία Rational. Τα βασικά στάδια ή φάσεις της UP είναι τα εξής: Σύλληψη (Inception) Λεπτομερής Επεξεργασία (Elaboration) Κατασκευή (Construction) Μετάβαση (Transition)
Η Φάση της Σύλληψης Σε αυτό το σύντομο αρχικό στάδιο διερευνάται η σκοπιμότητα του έργου: είναι αναγκαίο, κερδοφόρο κλπ. Απλά διαπιστώνεται αν θα συνεχίσει η ομάδα με την εκτέλεση του έργου ή όχι και αν χρειάζεται εξασφαλίζεται η δέσμευση για την χρηματοδότηση του έργου.
Η Φάση της Λεπτομερούς Επεξεργασίας Αυτό το στάδιο διαρκεί από μερικές εβδομάδες μέχρι και λίγους μήνες, ανάλογα με το μέγεθος του έργου. Αποτελείται από επαναλήψεις (iterations) καθορισμένης χρονικής διάρκειας (time-boxed) στις οποίες βασικός στόχος είναι η καταγραφή των προδιαγραφών του συστήματος. Εντοπίζονται τα τυχόν «επικίνδυνα σημεία» του έργου Αναπτύσσεται και το χρονοδιάγραμμα του έργου στο οποίο καταγράφεται αναλυτικά πότε θα έχει παραδοθεί η κάθε προδιαγραφή του συστήματος. Αρχίζει να αναπτύσσεται το έργο, να δημιουργείται δηλ. κώδικας επιπέδου παραγωγής. Τυπικά το 15% περίπου του έργου θα έχει προγραμματιστεί πριν να περάσουμε στην επόμενη φάση.
Η Φάση της Κατασκευής Σε αυτή τη φάση γίνεται η κατασκευή του έργου σύμφωνα με το χρονοδιάγραμμα που δημιουργήθηκε στην φάση της επεξεργασίας. Είναι επαναληπτική με επαναλήψεις σταθερής χρονικής διάρκειας. Σε κάθε επανάληψη αναπτύσσεται ένα σύνολο προδιαγραφών του συστήματος Η πρόοδος του έργου είναι απολύτως ελέγξιμη Οποιαδήποτε καθυστέρηση θα γίνει πολύ γρήγορα αντιληπτή
Η Φάση της Μετάβασης Σε αυτή τη φάση γίνονται εργασίες όπως η τεκμηρίωση του συστήματος (documentation), έλεγχος ορθότητας (beta testing), ρύθμιση της απόδοσης του συστήματος (performance tuning), κλπ.
Τύποι Διαγραμμάτων της UML Διάγραμμα Περιπτώσεων Χρήσης (Use Case Diagram) Διάγραμμα Κλάσεων (Class Diagram) Διαγράμματα Συμπεριφοράς (Behavior Diagrams): Διάγραμμα Καταστάσεων (Statechart Diagram) Διάγραμμα Δραστηριοτήτων (Activity Diagram) Διαγράμματα Αλληλεπίδρασης Διάγραμμα Ακολουθίας (Sequence Diagram) Διάγραμμα Συνεργασίας (Collaboration Diagram) Διαγράμματα Υλοποίησης (Implementation Diagrams): Διάγραμμα Συστατικών (Component Diagram) Διάγραμμα Διάταξης (Deployment Diagram)
Γιατί τόσοι διαφορετικοί τύποι διαγραμμάτων; Το σύστημα έχει στατικά στοιχεία, δυναμικά στοιχεία, στοιχεία υλοποίησης κοκ. Δεν είναι δυνατόν ένας και μόνο τύπος διαγράμματος να περιγράψει όλες αυτές τις διαφορετικές οπτικές γωνίες ενός συστήματος. Έτσι τυπικά χρησιμοποιούμε διαγράμματα κλάσεων για την περιγραφή των στατικών σχέσεων μεταξύ των κλάσεων, διαγράμματα συμπεριφοράς (κατάστασης, ακολουθίας κοκ) για την περιγραφή της δυναμικής συμπεριφοράς του συστήματος και διαγράμματα υλοποίησης (συστατικών, διάταξης) για την καταγραφή των λεπτομερειών υλοποίησης του συστήματος. Τα διαγράμματα περιπτώσεων χρήσης είναι μία ειδική περίπτωση υπό την έννοια πως δεν έχουν κάποια σχέση με αντικείμενα ή αντικειμενοστραφή συστήματα.
Ανάλυση Προδιαγραφών Το βασικότερο θέμα στην κατασκευή ενός πληροφοριακού συστήματος είναι η κατασκευή του ορθού συστήματος: του συστήματος Το μοντέλο περιπτώσεων χρήσης δίνει έμφαση στην λειτουργικότητα ενός συστήματος, όπως αυτή είναι ορατή από τους εξωτερικούς χρήστες του. Μια περίπτωση χρήσης διαμερίζει την λειτουργικότητα ενός συστήματος σε συναλλαγές («περιπτώσεις χρήσης») που έχουν νόημα για τους χρήστες του συστήματος («χειριστές»).
Περίπτωση Χρήσης Αναπαριστά έναν στόχο (user goal) για έναν εξωτερικό χειριστή (actor) του συστήματος. Οι χειριστές ενός συστήματος μπορεί να είναι άνθρωποι (π.χ. γραμματέας, ταμίας) αλλά ενδέχεται να είναι και εξωτερικά συστήματα (π.χ. Διατραπεζικό Σύστημα Συναλλαγών) Το σύμβολο για μία περίπτωση χρήσης είναι η έλλειψη στην οποία αναγράφεται ένα όνομα για την περίπτωση χρήσης.
Σενάρια Περίπτωσης Χρήσης Μία περίπτωση χρήσης συνήθως περιλαμβάνει πολλά εναλλακτικά σενάρια τα οποία ονομάζονται επεκτάσεις (extensions) Ένα σενάριο όπου όλα πάνε καλά (happy path) Αρκετά σενάρια όπου κάτι δεν πάει καλά ή προκύπτει κάποια εξαίρεση σε σχέση με το φυσιολογικό Οι εξαιρέσεις διαφοροποιούν το βασικό σενάριο σε συγκεκριμένα σημεία
Χειριστές Ο χειριστής (actor) ενός συστήματος μπορεί να είναι άνθρωπος ή υποσύστημα Το σύμβολο των διαγραμμάτων περιπτώσεων χρήσης για τους χειριστές είναι μία φιγούρα (stickman) Αν πρόκειται για υποσύστημα μπορούμε να χρησιμοποιήσουμε το σύμβολο της κλάσης με το στερεότυπο <<Actor>>
Πλαίσιο Συστήματος Για να διακρίνουμε τις προδιαγραφές που βρίσκονται μέσα στα πλαίσια του υπό ανάπτυξη συστήματος από τα πιθανά εξωτερικά συστήματα και τους χρήστες, περιλαμβάνουμε τις περιπτώσεις χρήσης σε ένα πλαίσιο με τίτλο το όνομα του συστήματος Μέσα στο πλαίσιο του συστήματος τοποθετούμε τις περιπτώσεις χρήσης και έξω από αυτό τους χειριστές του συστήματος.
Σχέση Υποδηλώνει την σχέση ενός χειριστή με μία περίπτωση χρήσης. Ενδέχεται ένας χειριστής να είναι ο βασικός (primary) για μία περίπτωση χρήσης αλλά και άλλοι χειριστές ή εξωτερικά συστήματα να σχετίζονται επίσης με αυτήν.
Συμπερίληψη Η συμπερίληψη είναι μία ειδική περίπτωση σχέσης στην οποία σχετίζουμε δύο περιπτώσεις χρήσης. Η μία περίπτωση χρήσης συμπεριλαμβάνει την άλλη. Η έννοια της συμπερίληψης είναι υποχρεωτική, δηλαδή πάντα η μία περίπτωση χρήσης θα συμπεριλαμβάνει την άλλη. Η φορά του βέλους στην συμπερίληψη είναι από την περίπτωση χρήσης που συμπεριλαμβάνει προς αυτήν που συμπεριλαμβάνεται και επισημαίνεται με το στερεότυπο <<include>>
Επέκταση Η επέκταση όπως και η συμπερίληψη καθορίζει μία σχέση μεταξύ δύο περιπτώσεων χρήσης, στην οποία μία περίπτωση χρήσης επεκτείνεται προαιρετικά από μία άλλη ανάλογα με τις επιλογές ή την κατάσταση κάποιου χειριστή (βασικού ή δευτερεύοντος)
Καταγραφή προδιαγραφών με κείμενο Η εύρεση των προδιαγραφών του συστήματος δεν είναι μία εργασία που έχει άμεση σχέση με την καταγραφή αυτών των προδιαγραφών σε ένα διάγραμμα περιπτώσεων χρήσης. Το διάγραμμα περιπτώσεων χρήσης κατά τη διαδικασία εύρεσης των προδιαγραφών του συστήματος πρέπει να χρησιμοποιείται επικουρικά. Εναλλακτικά ή και συμπληρωματικά με τα διαγράμματα περιπτώσεων χρήσης θα μπορούσε η καταγραφή των προδιαγραφών να γίνει με κείμενο σε έναν πίνακα
Διαγράμματα Κλάσεων Τα βασικά στοιχεία Βασίλης Γερογιάννης
Οπτικές γωνίες αναπαράστασης συστημάτων Μοντέλο Πεδίου Προβλήματος (domain model) Στο μοντέλο αυτό καταγράφονται ως κλάσεις οι έννοιες του πεδίου του προβλήματος, χωρίς να υπάρχει δέσμευση πως αυτές οι ίδιες κλάσεις θα υπάρχουν και στο λογισμικό που θα κατασκευαστεί Eπίπεδο του πεδίου προβλήματος του λογισμικού Κατά τη φάση της επεξεργασίας, το μοντέλο του πεδίου του προβλήματος θα αποτελέσει πηγή έμπνευσης για το επίπεδο του πεδίου προβλήματος του λογισμικού Σύγκριση: Οντότητες του πεδίου Προβλήματος (1) – Κλάσεις του Λογισμικού (2) Υψηλού επιπέδου υποχρεώσεις (1) – Μέθοδοι (2)
Κλάση Οι κλάσεις αποτελούν τη βάση της κατασκευής οποιουδήποτε αντικειμενοστρεφούς συστήματος. Ενσωματώνουν τα δεδομένα καθώς και τις λειτουργίες που επενεργούν στα δεδομένα αυτά. Συμβολίζονται με ένα παραλληλόγραμμο που έχει τρία διαμερίσματα. Στο πάνω διαμέρισμα αναγράφεται το όνομα της κλάσης, στο μεσαίο διαμέρισμα απεικονίζονται οι ιδιότητες, και στο κάτω διαμέρισμα οι λειτουργίες.
Δημόσια και Ιδιωτικά Χαρακτηριστικά Το συνηθισμένο σε μία κλάση είναι ότι οι ιδιότητες είναι ιδιωτικές (private) και οι λειτουργίες δημόσιες (public). Ιδιωτικά είναι τα χαρακτηριστικά μιας κλάσης (ιδιότητες ή λειτουργίες) που δεν είναι προσπελάσιμα από άλλες κλάσεις δημόσια αυτά που είναι προσπελάσιμα από άλλες κλάσεις. Αρχή απόκρυψης δεδομένων (data hiding principle): Εύκολη αλλαγή της εσωτερικής αναπαράστασης δεδομένων Εφαρμογή πολιτικών ελέγχου από τις μεθόδους
Σύμβολα Πρόσβασης στη UML Το σύμβολο “–” χρησιμοποιείται για να δηλώσει ιδιωτική πρόσβαση Tο “+” σημαίνει δημόσια πρόσβαση. Η πρόσβαση “#”, που είναι προστατευμένη πρόσβαση, έχει τη σημασία πως η ιδιότητα ή λειτουργία είναι προσπελάσιμη από την κλάση και τις τυχόν υποκλάσεις της. Η πρόσβαση σε επίπεδο πακέτου έχει την επισήμανση “~” και τη σημασία πως η ιδιότητα ή λειτουργία είναι προσπελάσιμη από την κλάση στην οποία δηλώνεται και τις άλλες κλάσεις που βρίσκονται στο ίδιο πακέτο με αυτήν. Τέλος, μη χρήση συμβόλου πρόσβασης σημαίνει πως η πρόσβαση δεν φαίνεται, αλλά αυτό δε σημαίνει πως δεν υπάρχει πρόσβαση ή πως η πρόσβαση είναι δημόσια.
Συντακτικό Ιδιοτήτων στη UML Προσδιοριστής-πρόσβασης όνομα-ιδιότητας: Τύπος [πολλαπλότητα διάταξη] = Αρχική-τιμή {συμβολοσειρά ιδιοτήτων} Μερικά Παραδείγματα: - students : string[* ordered] - interestRate : double = 0.035 {frozen}
Συντακτικό Λειτουργιών στη UML Προσδιοριστής-πρόσβασης όνομα (λίστα-παραμέτρων) : τύπος-επιστροφής {συμβολοσειρά ιδιοτήτων} Συντακτικό λίστας παραμέτρων: [in | out | inout] όνομα-παραμέτρου : τύπος = εξ ορισμού τιμή Μερικά παραδείγματα: + withdraw(in amount : Money) : boolean + getBalance():Money {query}
Λειτουργίες με Εμβέλεια Κλάσης Κάποιες ιδιότητες ή λειτουργίες έχουν εμβέλεια κλάσης και όχι αντικειμένου. Έστω, για παράδειγμα, ότι θέλουμε να μπορούμε να δημιουργήσουμε αντικείμενα Account διαβάζοντας τα στοιχεία για τη δημιουργία κάθε τέτοιου αντικειμένου από μια βάση δεδομένων. Θα μπορούσαμε να δηλώσουμε μια λειτουργία με το εξής συντακτικό: +createAccount(AccountID : String) : Account
Συσχετίσεις Κλάσεων Μια συσχέτιση (association) μεταξύ δύο κλάσεων απεικονίζει μία στατική σχέση μεταξύ των δύο κλάσεων. Απεικονίζουν σχέσεις μεταξύ κλάσεων που είναι αναγκαίες σε μόνιμη βάση Για την αναπαράσταση μιας συσχέτισης χρησιμοποιούμε μία γραμμή μεταξύ των δύο κλάσεων. όπως δείχνει η Εικόνα
Ονόματα Άκρων Συσχέτισης Σε κάθε άκρο μίας συσχέτισης μπορούμε να βάλουμε ένα όνομα που υποδηλώνει το ρόλο αυτής της κλάσης στη συσχέτιση. Επειδή το όνομα του άκρου συσχέτισης προσδιορίζει το ρόλο μίας κλάσης στη συσχέτιση, μερικές φορές αναφέρεται και ως όνομα ρόλου (rolename) Απαραίτητο όταν δύο κλάσεις συνδέονται με περισσότερες από μία συσχετίσεις όπως στην Εικόνα
Πολλαπλότητα Η πολλαπλότητα (multiplicity) αφορά ένα πέρας μίας συσχέτισης και είναι το πλήθος των αντικειμένων που μπορεί πιθανώς να συσχετίζονται με ένα αντικείμενο της άλλης κλάσης κατά τη διάρκεια της εκτέλεσης του προγράμματος Στο παράδειγμα ένας λογαριασμός έχει έναν ή περισσότερους δικαιούχους και ένας πελάτης έχει έναν ή περισσότερους λογαριασμούς Άλλες πιθανές τιμές για την πολλαπλότητα είναι οι * (που σημαίνει 0 ή περισσότερες), 0..1 (που σημαίνει 0 ή 1, δηλαδή προαιρετική συσχέτιση), κάποιος συγκεκριμένος αριθμός (π.χ. 11), ή και κάποια συγκεκριμένη περιοχή τιμών όπως 2..4
Πλοϊμότητα Η πλοϊμότητα (navigability) σε μία συσχέτιση συμβολίζεται με ένα βέλος στο πέρας της συσχέτισης και υποδηλώνει πλοϊμότητα μόνο προς τη φορά του βέλους Αφορά τη δυνατότητα που έχουμε από μία κλάση να ανακτήσουμε αντικείμενα της άλλης σε μία συσχέτιση Στην Εικόνα υπάρχει πλοϊμότητα μόνο από την κλάση «Department» προς την κλάση «Teacher»: έχοντας ένα αντικείμενο Department μπορούμε να βρούμε ποιοι διδάσκουν σε αυτό το τμήμα ή ποιος είναι ο πρόεδρός του, αλλά έχοντας ένα αντικείμενο Teacher δεν μπορούμε να βρούμε σε ποιο τμήμα διδάσκει
Παράδειγμα Συσχετίσεων στη Java Στο παράδειγμά μας έχουμε μία κλάση «Teacher», η οποία αφορά έναν εκπαιδευτικό. Κάθε εκπαιδευτικός έχει ένα όνομα που είναι αλφαριθμητικό (String). Επειδή ο εκπαιδευτικός δεν έχει την υποχρέωση να γνωρίζει το τμήμα στο οποίο ανήκει μια και δεν υπάρχει πλοϊμότητα από την κλάση «Teacher» προς την κλάση «Department», η κλάση «Teacher» δεν αναφέρεται καθόλου στην κλάση «Department».
Κώδικας της Κλάσης Teacher public class Teacher { private String name; public Teacher(String name) { this.name = name; } public String getName() { return name; public boolean equals(Object o) { Teacher t = (Teacher) o; return t.name == this.name; public int hashCode() { return name.hashCode();
Κώδικας της κλάσης Department (1) …διάφορα import public class Department { private Teacher president; private Set<Teacher> teachers; private String name; public Department(String name) { this.name = name; this.teachers = new HashSet<Teacher>(); } public boolean addTeacher(Teacher t) { return teachers.add(t); public boolean removeTeacher(Teacher t) { return teachers.remove(t);
Κώδικας της κλάσης Department (2) public boolean findTeacher(Teacher t) { return teachers.contains(t); } public void setPresident(Teacher t) { this.president = t; public Teacher getPresident() { return president; public void printTeachers() { Iterator<Teacher> iterator = teachers.iterator(); while (iterator.hasNext()) { Teacher t = iterator.next(); System.out.println(t.getName());
Μέθοδος Ελέγχου (main) public static void main(String args[]) { Teacher george = new Teacher("Γιώργος Κακαρόντζας"); Teacher george1 = new Teacher("Γιώργος Κακαρόντζας"); Department dept = new Department("Τμήμα ΧΥΖ"); dept.addTeacher(george); //αυτήν η εισαγωγή θα αποτύχει! boolean ok = dept.addTeacher(george1); if (!ok) { System.out.println("Η εισαγωγή απέτυχε"); } System.out.println("Εκπαιδευτικοί:"); dept.printTeachers(); dept.setPresident(george); System.out.println("Πρόεδρος: "+dept.getPresident().getName());
Συσχέτισης Γενίκευσης Η γενίκευση είναι μία ειδική μορφή συσχέτισης, κατά την οποία μία γενική κλάση αποτελεί τη βάση για τη δήλωση μίας ή περισσοτέρων ειδικότερων, υπό κάποια έννοια, κλάσεων. Η γενική κλάση ονομάζεται υπερκλάση και οι ειδικές κλάσεις ονομάζονται υποκλάσεις. Το σύμβολο της γενίκευσης είναι ένα βέλος που δείχνει από την ειδική στη γενική κλάση.
Παράδειγμα Γενίκευσης στη Java Οι κλάσεις «Person» και «Student» στην Java δίνονται στη Λίστα Κώδικα που ακολουθεί. Παρατηρήστε ότι η κλάση «Student» δηλώνεται ως υποκλάση της κλάσης «Person» με τη χρήση της φράσης extends στη δήλωσή της, επίσης, η κλάση «Student» υπερβαίνει τη μέθοδο toString της υπερκλάσης της δηλώνοντας τη μέθοδο toString εκ νέου.
Η Κλάση Person public class Person { protected String name; private int age; public Person() {} public void setName(String name) {this.name = name; } public void setAge(int age) {this.age = age;} public String getName() {return name;} public int getAge() {return age;} public String toString() { return "Είμαι ο " + name + " και είμαι " + age + " ετών."; }
Η Κλάση Student public class Student extends Person { private String fieldOfStudy; public void setFieldOfStudy(String fieldOfStudy) { this.fieldOfStudy = fieldOfStudy; } public String getField() { return fieldOfStudy; // Νέα δήλωση (υπέρβαση) της μεθόδου toString ειδικά για τους φοιτητές public String toString() { return "Είμαι o " + name + " και είμαι " + getAge() + " ετών. "+ “ Σπουδάζω " + fieldOfStudy;
Προχωρημένα Στοιχεία των Διαγραμμάτων Κλάσεων Βασίλης Γερογιάννης
Αφαιρετικές Κλάσεις – Συγκεκριμένες Υποκλάσεις Κάποιες κλάσεις σε ένα σύστημα δηλώνονται ως αφαιρετικές (abstract). Αυτές οι κλάσεις παρέχουν κώδικα για κάποιες λειτουργίες αλλά αφήνουν άλλες λειτουργίες τους χωρίς κώδικα (αφαιρετικές). Κάποιες υποκλάσεις αυτών των κλάσεων θα προσδιορίσουν τις χωρίς υλοποίηση λειτουργίες, παρέχοντας την κατάλληλη γι’ αυτές υλοποίηση. Αυτές οι υποκλάσεις ονομάζονται συγκεκριμένες (concrete).
Συμβολισμός της UML για τις Αφαιρετικές Κλάσεις Για να επισημάνετε μία τάξη ως αφαιρετική στην UML χρησιμοποιείτε το όνομα της τάξης με πλάγια γραφή (Italics). Επίσης με πλάγια γραφή επισημαίνονται και τα αφαιρετικά στοιχεία (οι αφαιρετικές λειτουργίες). Στην εικόνα η κλάση Shape είναι αφαιρετική και έχει την αφαιρετική λειτουργία draw. Η κλάση Square είναι συγκεκριμένη και υλοποιεί την λειτουργία draw.
Διασυνδέσεις Μία διασύνδεση (interface) είναι ένας τύπος που παρέχει ένα σύνολο λειτουργιών οι οποίες είναι στο σύνολό τους αφαιρετικές. Μία διασύνδεση δεν έχει δεδομένα (state), ούτε συσχετίσεις με πλοϊμότητα από την διασύνδεση προς το άλλο άκρο της συσχέτισης Η αδυναμία πλοϊμότητας αποτελεί συνέπεια της έλλειψης δεδομένων μια και η πλοϊμότητα συνεπάγεται την υποχρέωση της γνώσης των αντικειμένων της συσχετιζόμενης κλάσης και άρα την διατήρηση δεδομένων.
Πραγμάτωση Διασύνδεσης Κάποια κλάση που πραγματώνει (realizes) την διασύνδεση έχει την υποχρέωση να υλοποιήσει όλες τις λειτουργίες της διασύνδεσης. Το «κέρδος» για την κλάση είναι ότι τα αντικείμενά της θα έχουν τον τύπο της διασύνδεσης και επομένως θα μπορούν να χρησιμοποιηθούν όπου αναμένονται αντικείμενα του τύπου της διασύνδεσης.
Συμβολισμός της UML για τις Διασυνδέσεις Μία διασύνδεση στην UML σχεδιάζεται με το σύμβολο της κλάσης με την λέξη-κλειδί «Interface» πάνω από το όνομα της κλάσης Το διαμέρισμα των ιδιοτήτων μπορεί να μην υπάρχει ή να είναι κενό εφόσον υπάρχει Ένας εναλλακτικός συμβολισμός είναι ένας μικρός άδειος κύκλος με το όνομα της διασύνδεσης κάτω από τον κύκλο
Συμβολισμός UML για την Πραγμάτων Διασυνδέσεων Μία κλάση που υλοποιεί την διασύνδεση συσχετίζεται με αυτήν με το σύμβολο της πραγμάτωσης (realization) που είναι ίδιο με το σύμβολο της γενίκευσης μόνο που η γραμμή είναι διακεκομμένη. Εναλλακτικά μπορεί να χρησιμοποιηθεί ο συμβολισμός lollipop
Εξάρτηση Κλάσεων από Διασυνδέσεις Μία κλάση μπορεί να πραγματώνει περισσότερες από μία διασυνδέσεις. Επίσης άλλες κλάσεις μπορεί να είναι εξαρτημένες από υποσύνολα αυτών των διασυνδέσεων Στην εικόνα η κλάση Baby παρέχει τις διασυνδέσεις CryingObject και CuteObject. Η κλάση Speaker εξαρτάται μόνο από την διασύνδεση CryingObject ενώ η Camera εξαρτάται μόνο από την διασύνδεση CuteObject Η εξάρτηση συμβολίζεται με ένα διακεκομμένο βέλος από τον πελάτη της εξάρτησης προς την πηγή της εξάρτησης
Πλεονεκτήματα της Χρήσης Διασυνδέσεων Ο διαμερισμός των λειτουργιών μιας κλάσης σε διασυνδέσεις και ο ελεγχόμενος τρόπος με τον οποίο άλλες κλάσεις εξαρτώνται από συγκεκριμένα υποσύνολα των διασυνδέσεων και μόνο αυτά αποτελεί μία από τις σημαντικότερες τεχνικές για την αντιμετώπιση των δυσκολιών που συναντάμε στην κατασκευή πολύπλοκων συστημάτων λογισμικού. Ο κυριότερος λόγος γι’ αυτό είναι πως εφόσον μία κλάση δεν χρησιμοποιεί όλες τις λειτουργίες μίας άλλης κλάσης αλλά μόνο ένα καλά καθορισμένο υποσύνολο των λειτουργιών αυτών (μόνο αυτές τις λειτουργίες που παρέχει η διασύνδεση που χρησιμοποιεί) μπορούμε να ελέγξουμε καλύτερα τη διαδικασία των αλλαγών στο λογισμικό (change management).
Παράδειγμα με Διασυνδέσεις Στην εικόνα έχουμε μία κλάση Person που υλοποιεί την διασύνδεση Comparable της Java. Επίσης φαίνεται η κλάση PriorityQueue της Java η οποία έχει την μέθοδο offer για την εισαγωγή αντικειμένων στην ουρά. Όπως φαίνεται η κλάση PriorityQueue εξαρτάται από την διασύνδεση Comparable και όχι από την κλάση Person. Τα αντικείμενα της κλάσης Person μπορούν να εισαχθούν στην PriorityQueue γιατί η κλάση Person υλοποιεί την διασύνδεση Comparable.
Η κλάση Person σε Java … import java.util.PriorityQueue; import java.util.Iterator; public class Person implements Comparable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } //Μία πιθανή υλοποίηση της compareTo που ταξινομεί τα άτομα με βάση την ηλικία και τα //άτομα με την ίδια ηλικία η ταξινόμηση γίνεται με βάση το όνομα public int compareTo(Object obj) { Person other = (Person) obj; if (other.age == this.age) { return name.compareTo(other.name); return this.age - other.age; …
Παράδειγμα Εισαγωγής Person σε PriorityQueue public static void main(String[] args) { //Ουρά προτεραιότητας από Person PriorityQueue<Person> pq = new PriorityQueue<Person>(); //Εισαγωγή τριών Person στην ουρά Person p3 = new Person("Ναταλία", 39); Person p1 = new Person("Γιώργος", 39); Person p2 = new Person("Αναστασία", 2); pq.offer(p1); pq.offer(p2); pq.offer(p3); //Εμφάνιση της ουράς από την αρχή //προς το τέλος Iterator<Person> i = pq.iterator(); while (i.hasNext()) { Person p = i.next(); System.out.println(p); } Το αποτέλεσμα της εκτέλεσης του πιο προγράμματος θα είναι: Ηλικία: 2, Όνομα: Αναστασία Ηλικία: 39, Όνομα: Γιώργος Ηλικία: 39, Όνομα: Ναταλία
Παραμετρικές Κλάσεις Πολύ συχνά θέλουμε να ορίσουμε μία κλάση στην οποία κάποιος τύπος των ιδιοτήτων της κλάσης είναι παράμετρος. Ένα κλασικό παράδειγμα είναι η περίπτωση των διαφόρων κλάσεων που ορίζουν συλλογές στοιχείων. Όταν ορίζουμε μία ουρά προτεραιότητας για παράδειγμα, θα θέλαμε να μπορούμε να καθορίσουμε την ουρά χωρίς αναφορά στον συγκεκριμένο τύπο των στοιχείων που θα εισαχθούν σε αυτήν. Το ίδιο ισχύει και για τις άλλες συλλογές στοιχείων (σύνολα ή λίστες). Πλεονεκτήματα: Επαναχρησιμοποίηση της ίδιας κλάσης με στοιχεία διαφόρων τύπων Ισχυρός έλεγχος τύπων κατά την διάρκεια της μεταγλώττισης
Συμβολισμός της UML για τις Παραμετρικές Κλάσεις Αν ο τύπος της παραμέτρου παραλειφθεί τότε θεωρείται πως θα είναι κάποιος τύπος δεδομένων του συστήματος ή της γλώσσας προγραμματισμού που θα χρησιμοποιηθεί για την ανάπτυξη του συστήματος. Αν δεν ισχύει αυτό τότε ο τύπος θα πρέπει να καθοριστεί.
Δεσμευμένα Στοιχεία Οι παραμετρικές κλάσεις δεν μπορούν να χρησιμοποιηθούν για την δημιουργία αντικειμένων. Θα πρέπει να δεσμευθούν οι παράμετροι σε συγκεκριμένους τύπους, τιμές κλπ. προκειμένου να προκύψουν συγκεκριμένες κλάσεις από τις οποίες μπορούν να δημιουργηθούν αντικείμενα. Για παράδειγμα δεν μπορείτε να δημιουργήσετε ένα πίνακα με στοιχεία τύπου Τ. Θα πρέπει να δημιουργήσετε έναν πίνακα με στοιχεία κάποιου συγκεκριμένου τύπου (π.χ. Person). Αυτές οι συγκεκριμένες κλάσεις ονομάζονται δεσμευμένα στοιχεία (Bound Elements).
Συμβολισμός Δεσμευμένων Στοιχείων στη UML Επώνυμο Δεσμευμένο Στοιχείο Ανώνυμο Δεσμευμένο Στοιχείο
Συναρμολόγηση Η συναρμολόγηση (aggregation) δηλώνει τη συσχέτιση μίας κλάσης με κάποια άλλη κλάση που αποτελεί μέρος της. Η συναρμολόγηση έχει μόνο έναν επιπλέον περιορισμό σε σχέση με μία συνηθισμένη συσχέτιση: δεν επιτρέπεται η κυκλική συσχέτιση του μέρους με το όλο, αλλά μόνο μία συσχέτιση από το όλο προς το μέρος Η συναρμολόγηση συμβολίζεται με ένα άσπρο διαμάντι στην πλευρά του όλου όπως φαίνεται στην εικόνα «Η συναρμολόγηση είναι αυστηρά χωρίς σημασία. Σαν αποτέλεσμα σας συνιστώ να την αγνοήσετε όταν σχεδιάζετε τα δικά σας διαγράμματα» Martin Fowler
Σύνθεση Η σύνθεση (composition) είναι μία ισχυρή μορφή συσχέτισης όλου και μερών με δύο επιπλέον σημασιολογικά στοιχεία Το όλο περιέχει αποκλειστικά τα μέρη του Υπάρχει μία σχέση ζωής και θανάτου μεταξύ του όλου και των μερών του Συμβολίζεται με ένα μαύρο διαμάντι στην πλευρά του όλου όπως δείχνει η εικόνα
Προσδιορισμένες Συσχετίσεις Προσδιορισμένες (qualified) συσχετίσεις είναι αυτές στις οποίες χρησιμοποιείται ένα προσδιοριστικό (qualifier) για την ταυτοποίηση των αντικειμένων που συμμετέχουν στην συσχέτιση στο άλλο άκρο της συσχέτισης Στην εικόνα το αντικείμενο Φοιτητής είναι το προσδιοριστικό και για κάθε φοιτητή υπάρχουν 0 ή 1 γραμμές στο Βαθμολόγιο. Λέμε πως η συσχέτιση μεταξύ Βαθμολογίου και Γραμμής Βαθμολογίου είναι προσδιορισμένη (qualified) με προσδιοριστικό (qualifier) ένα αντικείμενο τύπου Φοιτητής
Πακέτα Τα μοντέλα ενός μεγάλου συστήματος είναι χρήσιμο να οργανώνονται σε πακέτα. Τα πακέτα παρέχουν: Οργάνωση συναφών μοντέλων σε ομάδες Έλεγχο των εξαρτήσεων Ένα χώρο ονομάτων Συμβολίζονται με ένα φάκελο όπως φαίνεται στην εικόνα όπου έχουμε τρία πακέτα με τις εξαρτήσεις τους Το πακέτο GUI εξαρτάται από το Accounting και το Accounting από το Database
Διάγραμμα Αντικειμένων Ένα διάγραμμα αντικειμένων είναι ένα στιγμιότυπο του συστήματος σε κάποια χρονική στιγμή στο οποίο απεικονίζονται αντικείμενα καθώς και οι σύνδεσμοι μεταξύ των αντικειμένων Ουσιαστικά ένα παράδειγμα της εκτέλεσης του συστήματος Ο όρος «Διάγραμμα Αντικειμένων» δεν αποτελεί επίσημη ορολογία αλλά χρησιμοποιείται ευρύτατα
Παράδειγμα Διαγράμματος Αντικειμένων Συνεπές διάγραμμα αντικειμένων Ασυνεπές διάγραμμα αντικειμένων
Εξαρτήσεις Οι εξαρτήσεις (dependencies) συμβολίζονται με διακεκομμένα βέλη που συνδέουν ένα διαγραμματικό στοιχείο από το οποίο ξεκινούν και ονομάζεται πελάτης με ένα άλλο διαγραμματικό στοιχείο στο οποίο καταλήγουν και ονομάζεται πηγή. Η ιδέα είναι πως αν μεταβληθεί η πηγή θα πρέπει πιθανώς να αλλάξει και ο πελάτης ο οποίος εξαρτάται από την πηγή. Υπάρχουν αρκετοί προκαθορισμένοι τύποι εξαρτήσεων στην UML πέρα από αυτούς που ήδη είδαμε ήδη. Αν θέλουμε, για παράδειγμα, να επισημάνουμε πως η εξάρτηση μεταξύ δύο πακέτων είναι η εισαγωγή του ενός πακέτου στο άλλο μπορούμε να χρησιμοποιήσουμε την λέξη κλειδί «import» αντί του γενικότερου «use». Οι εξαρτήσεις ΔΕΝ είναι μεταβατικές
Ένα Παράδειγμα Εξαρτήσεων H κλάση Course εξαρτάται από την κλάση Student γιατί καλεί κάποια μέθοδο (π.χ. την getName) Για να δείξουμε ότι η εξάρτηση αφορά την κλήση λειτουργίας βάζουμε την λέξη κλειδί <<call>>
Διαγράμματα Αλληλεπίδρασης και Καταστάσεων Βασίλης Γερογιάννης
Τι απεικονίζουν τα διαγράμματα αλληλεπίδρασης Τα διαγράμματα αλληλεπίδρασης (interaction diagrams) χρησιμοποιούνται για την οπτική αναπαράσταση των διαφόρων σεναρίων των περιπτώσεων χρήσης του συστήματος. Απεικονίζουν ένα σενάριο σαν στιγμιότυπα αντικειμένων που αλληλεπιδρούν μεταξύ τους ανταλλάσσοντας μηνύματα.
Τύποι διαγραμμάτων αλληλεπίδρασης Υπάρχουν δύο τύποι διαγραμμάτων αλληλεπίδρασης, οι οποίοι είναι ισοδύναμοι: το διάγραμμα ακολουθίας (sequence diagram) και το διάγραμμα συνεργασίας (collaboration diagram). Το διάγραμμα ακολουθίας δίνει έμφαση στη χρονική ακολουθία των μηνυμάτων. Το διάγραμμα συνεργασίας απεικονίζει τους συνδέσμους μεταξύ των αντικειμένων σε αυτό, ενώ για να γίνει προφανής η χρονική σειρά των μηνυμάτων απαιτείται η αρίθμησή τους.
Τι απεικονίζεται στα διαγράμματα ακολουθίας Στα διαγράμματα ακολουθίας (sequence diagrams) έχουμε την απεικόνιση μιας συνεργασίας αντικειμένων. Τα αντικείμενα συμβολίζονται με παραλληλόγραμμα στα οποία αναγράφεται το όνομα του αντικειμένου ακολουθούμενο από μία άνω-κάτω τελεία και στη συνέχεια το όνομα της κλάσης. Αν δε χρειάζεται το όνομα του αντικειμένου, μπορεί να παραλειφθεί. Κάτω από κάθε αντικείμενο εκτείνεται μία διακεκομμένη γραμμή που ονομάζεται γραμμή ζωής (lifeline) του αντικειμένου. Αν πρέπει να δείξουμε τον τερματισμό της ζωής ενός αντικειμένου, μπορούμε να βάλουμε ένα στο τέλος της γραμμής ζωής του. Τα αντικείμενα γράφονται από αριστερά προς τα δεξιά και στον οριζόντιο άξονα. Τα αντικείμενα ανταλλάσσουν μηνύματα, τα οποία στην επίσημη ορολογία της UML ονομάζονται ερεθίσματα (stimuli)
Τύποι ερεθισμάτων Κλήση μιας λειτουργίας: όταν ένα αντικείμενο καλεί μία λειτουργία ενός άλλου αντικειμένου. Σήμα: όταν ένα αντικείμενο αποστέλλει ένα ασύγχρονο μήνυμα σε ένα άλλο αντικείμενο. Δημιουργία αντικειμένου: είναι ένα ερέθισμα που καταλήγει στη δημιουργία ενός νέου αντικειμένου και όχι στη γραμμή ζωής κάποιου υπάρχοντος αντικειμένου. Επιστροφή κλήσης: είναι ένα διακεκομμένο βέλος το οποίο συμβολίζει την επιστροφή από μία κλήση. Καταστροφή αντικειμένου: είναι ένα ερέθισμα που καταλήγει στο σύμβολο τερματισμού της ζωής ενός άλλου αντικειμένου.
Παράδειγμα διαγρ. ακολουθίας
Παρατηρήσεις για τα διαγράμματα ακολουθίας (1) Στο διάγραμμα ακολουθίας δεν απεικονίζεται η λογική μιας λειτουργίας (ο αλγόριθμος). Τα πλαίσια ενεργοποίησης είναι σημαντικά επειδή μας δείχνουν τη ροή του προγράμματος από αντικείμενο σε αντικείμενο με κλήσεις διαδικασιών, των οποίων η εκτέλεση περιέχεται μέσα σε άλλες διαδικασίες. Το κάθε αντικείμενο που καλεί μία λειτουργία σε ένα άλλο αντικείμενο θα πρέπει να συνδέεται με αυτό μόνιμα (με συσχέτιση των αντίστοιχων κλάσεων στο διάγραμμα κλάσεων) ή εφήμερα (π.χ. το αντικείμενο μπορεί να είναι τοπική μεταβλητή ή παράμετρος).
Παρατηρήσεις για τα διαγράμματα ακολουθίας (2) Οι λειτουργίες που καλούνται στα διάφορα αντικείμενα θα πρέπει να είναι λειτουργίες των αντίστοιχων κλάσεων στο διάγραμμα κλάσεων. Σε σχέση με την προηγούμενη παρατήρηση, θα πρέπει να παρατηρήσουμε ότι η κατανομή των αρμοδιοτήτων στα διάφορα αντικείμενα είναι ένα βασικό θέμα στη σχεδίαση ενός αντικειμενοστραφούς συστήματος. Μερικούς κανόνες για την ανάθεση αρμοδιοτήτων σε κλάσεις μπορείτε να βρείτε στο βιβλίο του Craig Larman “Applying UML and Patterns”], όπου αναλύονται τα πρότυπα GRASP (General Responsibility Assignment Software Patterns) που μπορούν να χρησιμοποιηθούν γι’ αυτό το σκοπό.
Συμβολισμός δημιουργίας αντικειμένου Η δημιουργία ενός νέου αντικειμένου απεικονίζεται με ένα μήνυμα που αποστέλλεται σε ένα αντικείμενο και το οποίο καταλήγει πάνω στο πλαίσιο (το “κουτί”) του νέου αντικειμένου που δημιουργείται.
Καταστροφή αντικειμένου Η καταστροφή ενός αντικειμένου συμβολίζεται με ένα στο τέλος της γραμμής ζωής του. Αν η καταστροφή του αντικειμένου προκαλείται από ένα άλλο αντικείμενο, αυτό μπορούμε να το δείξουμε με ένα σήμα που αποστέλλεται από το ένα αντικείμενο στο άλλο και καταλήγει πάνω στο
Αυτοκλήση Όταν ένα αντικείμενο καλεί μια λειτουργία στον εαυτό του, αυτό απεικονίζεται σαν μία κλήση που ξεκινάει από το αντικείμενο και καταλήγει πάλι σε αυτό. Το πλαίσιο ενεργοποίησης εμφανίζεται ένθετο (“εμφωλευμένο”) στο πλαίσιο ενεργοποίησης της λειτουργίας στην οποία γίνεται η αυτοκλήση
Μηνύματα υπό συνθήκη Στα μηνύματα υπό συνθήκη τοποθετούνται αγκύλες μέσα στις οποίες αναγράφεται μία συνθήκη που μπορεί να είναι αληθής ή ψευδής. Η σημασία του συμβολισμού είναι ότι το μήνυμα θα αποσταλεί μόνο αν η συνθήκη είναι αληθής. Αν θέλουμε ταυτόχρονα να δείξουμε μία αποστολή εναλλακτικού μηνύματος, δείχνουμε τα δύο αμοιβαία αποκλειόμενα μηνύματα σαν μηνύματα με το ίδιο σημείο εκκίνησης και γράφουμε στο πρώτο τη συνθήκη και στο δεύτερο τη φράση [else]
Τι είναι τα διαγράμματα συνεργασίας Ένα διάγραμμα συνεργασίας είναι ισοδύναμο με ένα διάγραμμα ακολουθίας. Η διαφορά του έγκειται στο γεγονός ότι τα αντικείμενα μπορούν να είναι διάσπαρτα στο χώρο. Οι ανταλλαγές των μηνυμάτων θα πρέπει να αριθμηθούν έτσι ώστε να φαίνεται η σειρά τους. Για να επισημάνουμε ποιες κλήσεις περιέχονται μέσα σε άλλες κλήσεις μπορούμε να χρησιμοποιήσουμε αρίθμηση με δεκαδική ταξινόμηση· για παράδειγμα, αν ένα μήνυμα έχει αριθμό 1.2.3, αυτό σημαίνει πως είναι η 3η κλήση μέσα στη 2η κλήση, που περιέχεται με τη σειρά της μέσα στην 1η κλήση.
Απεικόνιση συνδέσμων και μηνυμάτων Στο διάγραμμα συνεργασίας απεικονίζονται, πέρα από τα αντικείμενα, και οι σύνδεσμοι μεταξύ των αντικειμένων, συμπεριλαμβανομένων των εφήμερων συνδέσμων. Τα μηνύματα παριστάνονται με ερεθίσματα πάνω ή κοντά στις γραμμές των συνδέσμων μέσω των οποίων αποστέλλονται.
Παράδειγμα διαγρ. συνεργασίας
Διάγραμμα Καταστάσεων Ένα διάγραμμα καταστάσεων (state diagram) απεικονίζει τη δυναμική συμπεριφορά των αντικειμένων μιας κλάσης και τον τρόπο που μεταβάλλεται η κατάστασή τους ως ανάδραση σε συμβάντα. Μπορείτε να χρησιμοποιήσετε τα διαγράμματα κατάστασης για να μοντελοποιήσετε τη συμπεριφορά και άλλων στοιχείων της UML, αλλά τυπικά χρησιμοποιούνται για τα στιγμιότυπα μιας κλάσης. Συνήθως ΔΕΝ σχεδιάζουμε διαγράμματα κατάστασης για όλες τις κλάσεις σε ένα σύστημα, παρά μόνο για εκείνες που παρουσιάζουν μία έντονα δυναμική συμπεριφορά. Το διάγραμμα κατάστασης μας βοηθάει να αντιληφθούμε αυτήν τη συμπεριφορά.
Παράδειγμα διαγρ. καταστάσεων
Σύμβολο τέλους διαγράμματος καταστάσεων Μπορείτε να χρησιμοποιήσετε ένα σύμβολο με ένα κύκλο και στο κέντρο του ένα γεμισμένο μαύρο κύκλο για να υποδηλώσετε το τέλος ενός διαγράμματος κατάστασης. Στο παράδειγμα απεικονίζεται η όχι και τόσο ενδιαφέρουσα ζωή ενός αντικειμένου-άνθρωπος (εντάξει παραλείψαμε αρκετές υποκαταστάσεις της σύνθετης κατάστασης «living»!).
Ταυτόχρονες σύνθετες καταστάσεις Πολλές φορές θέλουμε να απεικονίσουμε ταυτόχρονα διαγράμματα κατάστασης στα οποία ένα αντικείμενο βρίσκεται ταυτόχρονα σε δύο ή και περισσότερες καταστάσεις. Για το σκοπό αυτόν μπορούμε να χωρίσουμε μία κατάσταση σε δύο ή και περισσότερα μέρη με μια διακεκομμένη γραμμή και να δείξουμε τα ταυτόχρονα διαγράμματα κατάστασης στα διαφορετικά αυτά μέρη.
Επιπλέον διαγράμματα της UML και εισαγωγή στην μεθοδολογία ανάπτυξης Λογισμικού ICONIX Βασίλης Γερογιάννης
Διάγραμμα Δραστηριοτήτων Το διάγραμμα δραστηριοτήτων (activity diagram) είναι μια παραλλαγή του διαγράμματος καταστάσεων στο οποίο οι κόμβοι αναπαριστούν καταστάσεις ενεργειών και οι μεταβάσεις λαμβάνουν χώρα με την ολοκλήρωση αυτών των ενεργειών και όχι ως συνέπεια ενός συμβάντος όπως συμβαίνει με το διάγραμμα καταστάσεων. Τυπικά χρησιμοποιούμε τα διαγράμματα δραστηριοτήτων για την περιγραφή υπολογισμών ή ροών εργασιών (workflows). Η επισήμανση για το ποιο τμήμα ή αντικείμενο είναι υπεύθυνο για την εκτέλεση κάποιων ενεργειών σε μια δραστηριότητα γίνεται με τη χρήση διαδρόμων (swimlanes). Επίσης, είναι δυνατή η απεικόνιση της δημιουργίας και των ροών αντικειμένων μεταξύ των διαφόρων ενεργειών.
Παράδειγμα διαγρ. δραστηριοτήτων
Τι είναι ένα συστατικό Συστατικό (component) είναι μια ενότητα λογισμικού που εκθέτει τις λειτουργίες της μέσω ενός συνόλου δημόσιων διασυνδέσεων και μπορεί να συνδεθεί δυναμικά με άλλα συστατικά για τη δημιουργία μεγαλύτερων συστατικών και εφαρμογών. Επομένως, ένα συστατικό έχει τρία σημαντικά χαρακτηριστικά: Διαθέτει τις λειτουργίες του μέσω διασυνδέσεων και άρα η εσωτερική του υλοποίηση είναι κρυφή Μπορεί να συνδεθεί δυναμικά με άλλα συστατικά, και Είναι επαναχρησιμοποιήσιμο (δεν έχει γίνει για μία μόνο εφαρμογή).
Διάγραμμα Συστατικών Για να αναπαραστήσουμε τα συστατικά με τη UML χρησιμοποιούμε το διάγραμμα συστατικών (component diagram). Τα συστατικά παριστάνονται σαν παραλληλόγραμμα, από την αριστερή πλευρά των οποίων εξέρχονται δύο μικρότερα παραλληλόγραμμα. Οι διασυνδέσεις που εκθέτει ένα συστατικό συμβολίζονται με μικρούς λευκούς κύκλους, οι οποίοι συνδέονται μέσω ευθύγραμμων τμημάτων με το συστατικό (συμβολισμός lollipop). Τα συστατικά μπορούν να εξαρτώνται από άλλα συστατικά με χρήση των διασυνδέσεων. Η εξάρτηση αυτή απεικονίζεται με ένα κατευθυνόμενο διακεκομμένο βέλος, με αρχή από το συστατικό που χρησιμοποιεί τη διασύνδεση και κατάληξη στη διασύνδεση του συστατικού που την παρέχει.
Παράδειγμα διαγράμματος συστατικών
Διάγραμμα διάταξης Το διάγραμμα διάταξης (deployment diagram) μπορεί να χρησιμοποιηθεί κυρίως σε κατανεμημένα συστήματα για να δείξει τη φυσική διάταξη των διαφόρων τμημάτων του λογισμικού. Εδώ μπορούν να παρουσιαστούν και συστατικά τα οποία είναι στιγμιότυπα των συστατικών που απεικονίζονται στο διάγραμμα συστατικών. Το διάγραμμα περιέχει κόμβους (nodes) οι οποίοι περιέχουν τις εφαρμογές, τα συστατικά κ.λπ. που εκτελούνται σε αυτούς. Οι κόμβοι του συστήματος συμβολίζονται με κύβους, στους οποίους αναγράφεται το όνομα του κόμβου
Παράδειγμα διαγράμματος διάταξης
Τι είναι η ICONIX H μεθοδολογία αντικειμενοστραφούς ανάπτυξης ICONIX μπορεί με την αμεσότητα και την πληρότητά της να ελαττώσει τον ανταγωνισμό ανάμεσα στις ομάδες ανάπτυξης και διαχείρισης ενός έργου λογισμικού και να αυξήσει ταυτόχρονα την ποιότητα του παραγόμενου λογισμικού. Η ICONIX είναι απλούστερη και συντομότερη από την πολύ εκτενή ενοποιημένη προσέγγιση (Unified Process – UP). Όπως και η UP, η ICONIX υιοθετεί τη UML ως γλώσσα έκφρασης των απαιτήσεων και των προδιαγραφών του υπό σχεδίαση λογισμικού και είναι “καθοδηγούμενη από τις περιπτώσεις χρήσης”. Ταυτόχρονα, αποφεύγει την πληθώρα μοντέλων χωρίς να παραλείπει τις διαδικασίες ανάλυσης και σχεδιασμού.
Πλεονεκτήματα της ICONIX Χρησιμοποιεί UML αλλά περιέχει μόνο τον ελάχιστο αριθμό απαραίτητων βημάτων, αποφεύγοντας την παράλυση της ομάδας έργου λόγω υπερβολικής ανάλυσης (analysis paralysis). Παρέχει σε κάθε βήμα τη δυνατότητα ανίχνευσης του βαθμού υλοποίησης των απαιτήσεων – δεν επιτρέπει σε κανένα σημείο την απομάκρυνση από τις ανάγκες του χρήστη. Είναι επαναληπτική και αυξητική – το στατικό μοντέλο εκλεπτύνεται καθώς αναλύεται το δυναμικό μοντέλο – χωρίς να επιφέρει μεγάλη διαχειριστική επιβάρυνση.
Διαγράμματα της UML που χρησιμοποιεί η ICONIX Για να εφαρμόσουμε την ICONIX θα χρησιμοποιήσουμε μόνο τέσσερα είδη διαγραμμάτων UML: Διαγράμματα περιπτώσεων χρήσης για να αναπαραστήσουμε τα σενάρια χρήσης και τους χειριστές του συστήματος. Διαγράμματα κλάσεων για να αναπαραστήσουμε το πεδίο εφαρμογής του συστήματος, αλλά και τη λεπτομερή στατική δομή του συστήματος. Διαγράμματα συνεργασίας για να αναπαραστήσουμε τον τρόπο με τον οποίο η στατική δομή υλοποιεί τα σενάρια χρήσης του συστήματος. Διαγράμματα ακολουθίας για να συσχετίσουμε λεπτομερώς τη δυναμική συμπεριφορά με τη στατική δομή του συστήματος.
Δομή της μεθοδολογίας Η μεθοδολογία ICONIX περιλαμβάνει τρεις φάσεις: Ανάλυση απαιτήσεων Αρχικός σχεδιασμός Σχεδιασμός Στα πλαίσια κάθε φάσης, αναπτύσσουμε ένα σύνολο μοντέλων, τα οποία συνολικά μας επιτρέπουν να φτάσουμε στην παραγωγή κώδικα ξεκινώντας από τις περιπτώσεις χρήσης.
Σημεία ελέγχου (milestones) Ελάχιστα απαραίτητα σημεία ελέγχου: Εντοπισμός και περιγραφή όλων των σεναρίων χρήσης του υπό ανάπτυξη συστήματος. Εντοπισμός των οντοτήτων που ανήκουν στο πεδίο εφαρμογής και οι οποίες αποτελούν δομικά τμήματα (κλάσεις) του στατικού μοντέλου του συστήματος. Επαλήθευση ότι όλες οι λειτουργικές απαιτήσεις ικανοποιούνται στο σχεδιασμό του συστήματος. Εφαρμογή βασικών αρχών σχεδιασμού (ελαχιστοποίηση εξαρτήσεων, μεγιστοποίηση συνοχής, γενικότητα, πληρότητα κ.λπ.) κατά την ανάθεση λειτουργικής συμπεριφοράς σε τμήματα του λογισμικού.
Θεμελιώδη ερωτήματα για ένα σύστημα Η ICONIX αναγκάζει την ομάδα έργου να παραμένει προσηλωμένη στην απάντηση των θεμελιωδών ερωτήσεων και εμποδίζει την εμπλοκή της σε δευτερεύοντα θέματα αναπαράστασης. Τα θεμελιώδη αυτά ερωτήματα είναι τα εξής: Ποιοι είναι οι χρήστες του συστήματος και τι θέλουν να κάνουν με αυτό; Ποια είναι τα αντικείμενα του πραγματικού κόσμου όπου λειτουργεί το σύστημα και ποιες οι συσχετίσεις μεταξύ τους; Ποια από αυτά τα αντικείμενα χρησιμοποιούνται σε κάθε περίπτωση χρήσης; Πώς αλληλεπιδρούν τα αντικείμενα που συνεργάζονται σε κάθε περίπτωση χρήσης; Πώς χειριζόμαστε τα θέματα ελέγχου; Πώς θα φτάσουμε στην πραγματική κατασκευή του συστήματος;
Προσχέδιο διασύνδεσης χρήστη Ξεκινώντας, θα πρέπει να κάνουμε ένα πρόχειρο προσχέδιο της διασύνδεσης χρήστη και να σκεφτούμε ορισμένα σενάρια λειτουργίας του συστήματος. Έπειτα μπορούμε να αρχίσουμε την ανάλυση κάθε σεναρίου και το σχεδιασμό του συστήματος. Ο τελικός στόχος είναι να περιγράψουμε τόσο τη στατική δομή του συστήματος (συνήθως πρόκειται για ένα σύνολο κλάσεων), αλλά και τη δυναμική συμπεριφορά του συστήματος (δηλαδή τον τρόπο που συνεργάζονται συγκεκριμένα αντικείμενα των κλάσεων για να υλοποιήσουν τα σενάρια που περιγράφουν οι περιπτώσεις χρήσης).
Ανάλυση συστήματος Στην συνέχεια ξεκινάμε την διαδικασία της ανάλυσης του συστήματος Ο στόχος της ανάλυσης είναι να περιγράψουμε τις περιπτώσεις χρήσης του συστήματος ανά σενάριο λειτουργίας. Πρέπει να αποφύγουμε ασαφείς περιπτώσεις χρήσης: Για να το πετύχουμε αυτό θα πρέπει να δώσουμε μια περιγραφή των περιπτώσεων χρήσης έχοντας στο νου μας το μοντέλο του πεδίου εφαρμογής (application domain model) το οποίο περιέχει τα αντικείμενα του πεδίου εφαρμογής. Αυτό το μοντέλο θα εξελιχθεί στην συνέχεια στο στατικό μοντέλο του συστήματος.
Μοντέλο πεδίου εφαρμογής Το διάγραμμα αυτό δεν περιέχει λεπτομέρειες, όπως ιδιότητες (κατηγορήματα) ή μεθόδους των κλάσεων, αλλά συνοψίζει μόνο τις κλάσεις που περιγράφουν το πεδίο εφαρμογής. Αρχικά κάνουμε μια πρώτη εκτίμηση του μοντέλου αυτού με βάση την περιγραφή της διασύνδεσης και των σεναρίων λειτουργίας. Στην συνέχεια καθώς θα σχεδιάζουμε λεπτομερώς τις περιπτώσεις χρήσης χρησιμοποιώντας διαγράμματα και κείμενο, το αρχικό διάγραμμα κλάσεων θα εξελίσσεται στο λεπτομερές στατικό μοντέλο του συστήματος.
Περιγραφή δυναμικής συμπεριφοράς του συστήματος Έχοντας μια αρχική περιγραφή της στατικής δομής του συστήματος, πρέπει να προχωρήσουμε στη λεπτομερή περιγραφή της δυναμικής συμπεριφοράς του. Αυτό γίνεται σε δύο στάδια: Ποια είναι η δυναμική συμπεριφορά; Πώς υλοποιείται αυτή στο συγκεκριμένο σύστημα;
Ποια είναι η δυναμική συμπεριφορά του συστήματος; Για να απαντήσουμε στο πρώτο ερώτημα σχεδιάζουμε το μοντέλο συνεργασίας, το οποίο περιλαμβάνει ένα σύνολο διαγραμμάτων συνεργασίας. Σε κάθε διάγραμμα συνεργασίας φαίνεται ποιες κλάσεις του μοντέλου του πεδίου εφαρμογής και ποιες κλάσεις του συστήματος συνεργάζονται για να υλοποιήσουν κάθε περίπτωση χρήσης. Με βάση τα διαγράμματα συνεργασίας θα εμπλουτίσουμε το κείμενο που περιγράφει τις περιπτώσεις χρήσης και θα ενσωματώσουμε στο μοντέλο του πεδίου εφαρμογής τα συνοριακά αντικείμενα (boundary objects), τα οποία αναπαριστούν τον τρόπο με τον οποίο το σύστημά μας επικοινωνεί με το περιβάλλον στο οποίο λειτουργεί – πρόκειται δηλαδή για κλάσεις που αναπαριστούν οθόνες χρήστη και επικοινωνία με εξωτερικά υποσυστήματα όπως βάσεις δεδομένων κ.α.
Πώς υλοποιείται η δυναμική συμπεριφορά στο σύστημα; Στη συνέχεια σχεδιάζουμε το διάγραμμα ακολουθίας, στο οποίο ουσιαστικά μετατρέπουμε τις λειτουργίες που υλοποιούν τη δυναμική συμπεριφορά σε μεθόδους τις οποίες κατανέμουμε στις κλάσεις. Για κάθε ένα σενάριο χρήσης του συστήματος θα σχεδιάσουμε ένα διάγραμμα ακολουθίας, το οποίο θα μας δείχνει ποιο αντικείμενο μέσα στον κώδικα είναι υπεύθυνο για ποια λειτουργία του συστήματος. Κατά τη σχεδίαση των διαγραμμάτων ακολουθίας θα αποφασίσουμε και την κατανομή των λειτουργιών σε κλάσεις.
Τελικό εξαγόμενο αποτέλεσμα της μεθοδολογίας Το τελικό εξαγόμενο της μεθοδολογίας είναι ένα λεπτομερές διάγραμμα κλάσεων, από το οποίο είναι εύκολο να παραχθεί ο κώδικας του συστήματος. Το διάγραμμα αυτό περιλαμβάνει όλες τις κλάσεις του συστήματος (στατικό μοντέλο) Για κάθε κλάση, περιλαμβάνει τις μεθόδους που υλοποιούν τις λειτουργίες του συστήματος (μοντέλο δυναμικής συμπεριφοράς) και τα δεδομένα (μοντέλο δεδομένων) που αυτές χρησιμοποιούν.
Οπτική παράσταση των βημάτων της ICONIX
Σύντομο Παράδειγμα μιας συνοπτικής μεθοδολογίας ανάπτυξης Βασίλης Γερογιάννης
Περιγραφή Παραδείγματος Κράτηση δωματίου σε ξενοδοχείο Ο υπάλληλος δίνει τα στοιχεία του πελάτη το δωμάτιο (μονό, διπλό κλπ) και την περίοδο. Το σύστημα βρίσκει το δωμάτιο και κάνει κράτηση ή αποφαίνεται πως δεν υπάρχει κατάλληλο δωμάτιο για την περίοδο που προσδιορίστηκε
Σκοπός του Παραδείγματος Το παράδειγμα δεν αποσκοπεί στο να κάνουμε ένα πλήρες σύστημα κράτησης δωματίων σε ξενοδοχείο (π.χ. δεν θα ασχοληθούμε με την αποθήκευση των κρατήσεων σε Βάση Δεδομένων). Αποσκοπεί στο να καταλάβουμε: Πως μπορούμε να χρησιμοποιήσουμε τα διαγράμματα ακολουθίας για να διαπιστώσουμε ποιες είναι οι κατάλληλες τάξεις και λειτουργίες για τον προγραμματισμό ενός σεναρίου μιας περίπτωσης χρήσης. Την ταυτόχρονη εξέλιξη ενός διαγράμματος κλάσεων προκειμένου να καλυφθούν οι απαιτήσεις μιας εφαρμογής Την ροή των μηνυμάτων μεταξύ αντικειμένων
Περίπτωση Χρήσης και Σενάρια Κρατήσεις Δωματίων Επιτυχής Κράτηση Δωματίου Ανεπιτυχής Κράτηση Δωματίου Υπάλληλος Ακύρωση Κράτησης Δωματίου …
Αρχικό Διάγραμμα Κλάσεων Hotel Reservation 0..N 1 1..N Client Room 1 Το ξενοδοχείο έχει πολλά δωμάτια Κάθε δωμάτιο έχει 0 ή περισσότερες κρατήσεις Κάθε κράτηση αφορά έναν πελάτη και ένα δωμάτιο
Διάγραμμα Ακολουθίας (1) ReservationWindow: Άλλη μία νέα κλάση. Χωρίς γραφική διασύνδεση ο χρήστης δεν μπορεί να χρησιμοποιήσει το σύστημα. Αυτές οι κλάσεις ονομάζονται «συνοριακές τάξεις» Reservation Window makeReservation (period , client, roomType,) Period: Αυτό είναι μία υποψήφια νέα κλάση; Έχει δύο ημερομηνίες (αρχής και τέλους). Έχει την δυνατότητα να μας πει αν μία περίοδος επικαλύπτεται χρονικά από κάποια άλλη περίοδο.
Διάγραμμα Ακολουθίας (2) Reservation Window Hotel makeReservation(period,client,roomType) r:=roomsOfType(roomType) Το ξενοδοχείο έχει δωμάτια διαφόρων τύπων (μονά, διπλά κλπ.). Η αναζήτηση θα γίνει μόνο στα δωμάτια με τύπο ίδιο με αυτόν για τον οποίο ενδιαφέρεται ο πελάτης
Διάγραμμα Ακολουθίας (3) Hotel room:Room r:=roomsOfType(roomType) * [forall room in r] free:=available(period) Για κάθε Room στο r έλεγξε αν είναι διαθέσιμο για την περίοδο για την οποία ενδιαφέρεται ο πελάτης.
Διάγραμμα Ακολουθίας (4) room:Room Reservation * free:=available(period) * ovr:=overlaps(period) Για κάθε μία από τις ήδη υπάρχουσες κρατήσεις για το δωμάτιο έλεγξε αν επικαλύπτει χρονικά την περίοδο για την οποία ενδιαφέρεται ο πελάτης
Διάγραμμα Ακολουθίας (5) Reservation Period * ovr:=overlaps(period) ovr:=overlaps(period) Αυτό το period είναι η περίοδος κράτησης αυτού του Reservation Η κράτηση ελέγχει αν επικαλύπτει χρονικά την περίοδο που ενδιαφέρει τον πελάτη, με την σύγκριση με την δική της περίοδο κράτησης.
Επιτυχής Αναζήτηση Για κάποιο από τα δωμάτια η available θα επιστρέψει true για την περίοδο που ενδιαφέρει τον πελάτη. Σ’ αυτή τη περίπτωση δημιουργείται μία νέα κράτηση για την περίοδο που ενδιαφέρει τον πελάτη και προστίθεται στις ήδη υπάρχουσες κρατήσεις γι’ αυτό το δωμάτιο.
Διάγραμμα Ακολουθίας (6) Hotel room: Room r:=roomsOfType(roomType) * free:=available(period) newR: Reservation [free] Reservation(period, client, room) addReservation(newR) newR
Διάγραμμα Ακολουθίας (7) Reservation Window Hotel makeReservation (period , client, roomType,) makeReservation(period,client,roomType) r:=roomsOfType(roomType) * free:=available(period) … newR … newR
Τέλος Κράτησης Τελικά το ReservationWindow παίρνει την νέα κράτηση (newR) και εμφανίζει τις πληροφορίες της κράτησης στον υπάλληλο. Για παράδειγμα εμφανίζει ένα μήνυμα επιβεβαίωσης της κράτησης όπως το ακόλουθο:
Διάγραμμα Ακολουθίας
Εμπλουτισμός του Διαγράμματος Κλάσεων Ξεκινήσαμε με ένα αρχικό διάγραμμα κλάσεων. Τώρα θα πρέπει να προσθέσουμε σε αυτό όλες τις νέες κλάσεις που ανακαλύψαμε (π.χ. Period, ReservationWindow) καθώς και τις μεθόδους που είναι απαραίτητες για την διεκπεραίωση της κράτησης (π.χ. την available στην τάξη Room, την overlaps στην τάξη Period κλπ.)
Διάγραμμα Κλάσεων [ ]
Πρόγραμμα Java Σημείωση: Η βηματική εκτέλεση σε debugger μας επιτρέπει να δούμε την ανταλλαγή των μηνυμάτων μεταξύ των αντικειμένων ακριβώς όπως αυτά απεικονίζονται στο διάγραμμα ακολουθίας.
Η κλάση Period import java.util.Date; public class Period { private Date startDate; private Date endDate; public Period(Date startDate, Date endDate) { this.startDate = startDate; this.endDate = endDate; } public Date getStartDate() { return startDate; } public Date getEndDate() { return endDate; } public boolean overlaps(Period p) { Date pStartD = p.getStartDate(); Date pEndD = p.getEndDate(); if ((pStartD.compareTo(startDate)>=0 && pStartD.compareTo(endDate)<=0) || (pEndD.compareTo(startDate)>=0 && pEndD.compareTo(endDate)<=0)) { return true; return false;
Η κλάση Room (1) import java.util.Vector; import java.util.Enumeration; public abstract class Room { public final static int SINGLE_ROOM = 1; public final static int DOUBLE_ROOM = 2; private Vector reservations; private String name; public Room(String name) { reservations = new Vector(); this.name = name; } public Reservation[] getReservations() { Object[] o = reservations.toArray(); Reservation[] r = new Reservation[o.length]; System.arraycopy(o, 0, r, 0, o.length); return r; . . .
Η κλάση Room (2) public void addReservation(Reservation r) { reservations.add(r); } public boolean available(Period p) { Enumeration e = reservations.elements(); while (e.hasMoreElements()) { Reservation r = (Reservation) e.nextElement(); if (r.overlaps(p)) { return false; return true; public String getName() { return name; abstract public int getRoomType();
Οι κλάσεις DoubleRoom και SingleRoom public class DoubleRoom extends Room { /** Creates a new instance of DoubleRoom */ public DoubleRoom(String name) { super(name); } public int getRoomType() { return Room.DOUBLE_ROOM; } public class SingleRoom extends Room{ /** Creates a new instance of SingleRoom */ public SingleRoom(String name) { return Room.SINGLE_ROOM;
Η κλάση Client public class Client { private String name; private String telephone; /** Creates a new instance of Client */ public Client(String name, String telephone) { this.name = name; this.telephone = telephone; } public String getName() { return name; } public String getTelephone() { return telephone; }
Η κλάση Reservation public class Reservation { private Period period; private Client client; private Room room; public Reservation(Period period, Client client, Room room) { this.period = period; this.client = client; this.room = room; } public Client getClient() { return client; } public Period getPeriod() { return period; } public Room getRoom() { return room; } public boolean overlaps(Period p) { return period.overlaps(p);
Άλλες κλάσεις Υπάρχουν επίσης άλλες δύο κλάσεις: Η συνοριακή κλάση ReservationWindow που είναι το παράθυρο μέσω του οποίου γίνεται μία κράτηση Η βασική κλάση Hotel που αποτελεί και το σημείο εισόδου στο πρόγραμμα
Ασκήσεις Κάντε το διάγραμμα ακολουθίας για την «Ακύρωση Κράτησης» και εμπλουτίστε αντίστοιχα το διάγραμμα τάξεων Εξηγείστε σε ποια σημεία θα πρέπει να προστεθεί η πρόσβαση σε Βάση Δεδομένων για την αποθήκευση και ανάκτηση των κρατήσεων Πότε θα πρέπει να διαγραφεί μία κράτηση φυσιολογικά (όχι από ακύρωση);