Κατέβασμα παρουσίασης
Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε
ΔημοσίευσεBemus Antoni Τροποποιήθηκε πριν 9 χρόνια
1
2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης1 ΟΙΚΟΝΟΜΙΚΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΑΘΗΝΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ ΤΕΧΝΟΛΟΓΙΑ ΛΟΓΙΣΜΙΚΟΥ Λεπτομερής Σχεδίαση (2/2) Μανόλης Γιακουμάκης αναπληρωτής καθηγητής ΟΠΑ
2
2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης2 Σημερινή παρουσίαση Από το σχέδιο στον κώδικα –Κλάσεις –Απλοί τύποι –Συσχετίσεις –Κληρονομικότητα και διεπαφές –Διαγράμματα ακολουθίας Συστάσεις αντικειμενοστρεφούς σχεδίασης –Σχεδίαση κλάσεων –Μεταβίβαση, κληρονομικότητα και πολυμορφισμός –Συνεργασία αντικειμένων –Σχεδίαση πακέτων
3
Από το σχέδιο στον κώδικα Όταν ο σχεδιαστής του λογισμικού προσεγγίζει τη σχεδίαση των βασικών δομικών μονάδων του λογισμικού, επικοινωνεί τις σχεδιαστικές του επιλογές στον προγραμματιστή. Επειδή ακριβώς η σχεδίαση με τα διαγράμματα κλάσεων της UML είναι πολύ κοντά και στον προγραμματισμό, ο σχεδιαστής του λογισμικού θα πρέπει να γνωρίζει πώς μεταφέρεται το σχέδιο στον κώδικα. Επίσης, θα πρέπει σε περιπτώσεις όπου η UML αφήνει περιθώρια ερμηνειών των στοιχείων μοντελοποίησης, να υπάρξει μία εκ των προτέρων συμφωνία μεταξύ σχεδιαστή και του προγραμματιστή για την ερμηνεία τους. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης3
4
Κλάσεις public class Employee { private static int lastEmpId ; protected int Id; private String firstName; private String lastName; public final int maxNumberOfPhones = 2; private String[] phoneNumbers = new String[maxNumberOfPhones]; public String getFirstName() {} public void setFistName(String firstName) {} public String getLastName() {} public void setLastName(String lastName){} public void paySalary(Month month){} protected void calculateSalary(Month month) {} public static int nextEmployeeId(){} } 20094ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
5
Κλάσεις Η υλοποίηση των κλάσεων, των ιδιοτήτων και των λειτουργιών της UML είναι σχεδόν αυτόματη διαδικασία. Οι κλάσεις της UML μετατρέπονται σε κλάσεις της Java, οι ιδιότητες γίνονται πεδία και οι λειτουργίες μέθοδοι. Ένα σημείο που χρήζει κάποιας προσοχής είναι οι ορατότητες της UML. Οι ορατότητες, όπως ορίζονται στη UML, έχουν όμοια αντιστοιχία με τις ορατότητες της Java με κάποιες λεπτές διαφορές. Για παράδειγμα η προστατευμένη (protected) ορατότητα της Java είναι ταυτόχρονα και ορατότητα πακέτου (package). 20095ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
6
Η έννοια της ισότητας των αντικειμένων τιμών στη Java 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης6 University a = new University(); a.setName("AUEB"); University b = a;
7
Η έννοια της ισότητας των αντικειμένων τιμών στη Java 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης7 University a = new University(); a.setName("AUEB"); University b = new University(); b.setName("AUEB”);
8
Η έννοια της ισότητας των αντικειμένων τιμών στη Java 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης8 Όταν συγκρίνουμε δύο αναφορές σε αντικείμενα απλών τύπων, πχ ημερομηνιών, μας ενδιαφέρει εάν οι δύο αναφορές αναφέρονται στις ίδιες ημερομηνίες. Θέλουμε επομένως σύγκριση βάσει των τιμών και όχι βάσει των ταυτοτήτων των αντικειμένων.
9
Συσχετίσεις Τα δύο σημαντικότερα στοιχεία που θα πρέπει να έχει υπόψη του ο σχεδιαστής για μία συσχέτιση είναι η πολλαπλότητα και η πλοηγησιμότητα στα άκρα των συσχετίσεων. 20099ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
10
Μονόδρομες συσχετίσεις με πολλαπλότητα ένα 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης10 Ο κώδικας που αντιστοιχεί στο διάγραμμα είναι: public class Book { private Publisher publisher; public void setPublisher(Publisher publisher) { this.publisher = publisher; } public Publisher getPublisher() { return publisher; }
11
Μονόδρομες συσχετίσεις με πολλαπλότητα ένα Για να υλοποιήσουμε την απλή συσχέτιση όπου κάθε αντικείμενο της κλάσης Book γνωρίζει ένα αντικείμενο της κλάσης Publisher, δημιουργούμε ένα πεδίο publisher με τύπο Publisher εντός της κλάσης Book. Την ονομασία του πεδίου την πήραμε από το όνομα του άκρου της συσχέτισης του σχήματος 8-33. Η μέθοδος setPublisher ενημερώνει το πεδίο και η μέθοδος getPublisher το επιστρέφει 200911ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
12
Μονόδρομες συσχετίσεις με πολλαπλότητα πολλά 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης12 public class Book { private Set items = new HashSet (); public Set getItems(){ return items; }
13
Μονόδρομες συσχετίσεις με πολλαπλότητα πολλά Θα πρέπει επομένως να χρησιμοποιήσουμε μία συλλογή στην κλάση Book που θα περιέχει αναφορές προς τα συσχετιζόμενα αντικείμενα της κλάσης Item. Μία συλλογή που μπορεί να χρησιμοποιηθεί είναι τα σύνολα της Java. Για τα σύνολα η Java παρέχει τη διεπαφή Set και ορισμένες κλάσεις που την υλοποιούν, όπως οι κλάσεις HashSet και TreeSet. 200913ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
14
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης14 Το σχήμα παρουσιάζει διαγραμματικά τη χρήση των συλλογών. Ένα αντικείμενο της κλάσης Book έχει την αναφορά items προς μία συλλογή. Αν και πολλές φορές λέμε ότι μία συλλογή περιέχει αντικείμενα, στην πραγματικότητα περιέχει αναφορές προς αντικείμενα.
15
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας Εφόσον η συλλογή items αρχικοποιείται σε συλλογή HashSet, θα ήταν λογικό να επιστρέφουμε HashSet και από την getItems(). Προτιμούμε όμως να επιστρέφουμε τη συλλογή ως τη διεπαφή Set και όχι την υλοποίηση που είναι η κλάση HashSet. 200915ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
16
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας Οι πελάτες της κλάσης Book δε γνωρίζουν την υλοποίηση της συλλογής των αντικειμένων, γνωρίζουν μόνο ότι η συλλογή είναι σύνολο. Η καλή πρακτική για το χειρισμό των συλλογών είναι να δημοσιεύονται στους πελάτες οι διεπαφές (π.χ. Set) και όχι οι κλάσεις που τις υλοποιούν (π.χ. HashSet). Αυτό γιατί οι υλοποιήσεις των συλλογών μπορεί να αλλάζουν, αλλά δε θέλουμε οι αλλαγές αυτές να επηρεάζουν τους πελάτες. Η υλοποίηση αυτή διευκολύνει ακόμα περισσότερο την αλλαγή της υλοποίησης της συλλογής items. Η αλλαγή στην αρχικοποίηση της συλλογής σε items = new TreeSet() δεν επηρεάζει τους πελάτες της κλάσης Book. 200916ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
17
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας Έτσι, όταν θέλουμε να χρησιμοποιήσουμε τη συλλογή items, θα έχουμε κάποιο κώδικα όπως: Book oneBook = new Book(); Item oneItem = new Item(); oneBook.getItems().add(oneItem); oneBook.getItems().remove(oneItem); Με το τμήμα του κώδικα παραπάνω, δημιουργούνται δύο αντικείμενα oneBook και oneItem. Εισάγουμε το αντικείμενο oneItem στη συλλογή items και αμέσως μετά το απομακρύνουμε από τη συλλογή. 200917ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
18
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας Σε αυτό το σημείο πρέπει να σημειώσουμε ότι δεν υπάρχει κάποια μέθοδος setItems στην κλάση Book, γιατί δε θέλουμε οι πελάτες να τροποποιούν απευθείας τη συλλογή, αλλά μόνο μέσω των μεθόδων εισαγωγής και διαγραφής αντικειμένων. Εάν υπήρχε, θα μπορούσε να υπάρξει ο κώδικας: oneBook.setItems(null); κώδικας που διαγράφει όλη τη συλλογή, κάτι που προφανώς δεν είναι επιθυμητό. 200918ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
19
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας Όταν χρησιμοποιούμε συλλογές σε ένα αντικείμενο, εισάγουμε νέες βοηθητικές μεθόδους για την πρόσθεση και απομάκρυνση αντικειμένων, έτσι ώστε ο πελάτης να μη χρησιμοποιεί απευθείας τη συλλογή. Έτσι, στην κλάση Book προσθέτουμε τις δύο βοηθητικές μεθόδους παρακάτω: public class Book { //… public void addItem(Item item) { if (item != null ) { items.add(item); } } public void removeItem(Item item) { if (item != null) { items.remove(item); } } } 200919ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
20
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας Οι βοηθητικές μέθοδοι μας βοηθούν, αλλά ο πελάτης εξακολουθεί να έχει πρόσβαση στη συλλογή μέσω του παρακάτω κώδικα: Set myItems = oneBook.getItems() myItems.add(aSecondItem) Μπορεί επομένως ο πελάτης να προσθέσει απευθείας αντικείμενα στη συλλογή, χωρίς να χρησιμοποιήσει τις βοηθητικές μεθόδους. Θα επιθυμούσαμε επομένως να ενθυλακώσουμε πλήρως τη συλλογή και να εξαναγκάσουμε τους πελάτες της κλάσης Book να χρησιμοποιήσουν τις βοηθητικές μεθόδους addItem και removeItem. Η ενθυλάκωση αυτή γίνεται με την επιστροφή αντιγράφου της συλλογής και όχι την ίδια τη συλλογή. Αυτό επιτυγχάνεται με την τροποποίηση της μεθόδου getItems παρακάτω: public Set getItems(){ return new HashSet (items); } 200920ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
21
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας Η getItems επιστρέφει πλέον αντίγραφα της συλλογής items και όχι την ίδια τη συλλογή. Τα αντίγραφα των συλλογών δίνουν πρόσβαση στα αντικείμενα που περιέχουν και αφήνουν φυσικά την πλήρη χρήση τους, όπως για παράδειγμα την τροποποίηση των πεδίων τους. Αυτό που απαγορεύουν είναι η απευθείας πρόσβαση στη συλλογή. 200921ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης
22
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης22
23
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας Το σχήμα 8-36 παρουσιάζει την εικόνα ενός αντιγράφου της συλλογής. Εάν υποθέσουμε ότι έχουμε τον κώδικα: Set myItems = oneBook.getItems(); τότε η συλλογή myItems είναι το αντίγραφο της συλλογής του αντικειμένου oneBook. Μέσω της συλλογής myItems έχουμε πρόσβαση σε όλα τα αντικείμενα και μπορούμε να αλλάξουμε την κατάστασή τους. Η πρόσθεση και η απομάκρυνση αντικειμένων γίνεται πλέον στο αντίγραφο της συλλογής και όχι στην αρχική. Για να γίνει πρόσθεση ή απομάκρυνση αντικειμένων στην αρχική συλλογή θα πρέπει να χρησιμοποιηθούν οι βοηθητικές μέθοδοι addItem και removeItem. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης23
24
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας Έστω για παράδειγμα ο κώδικας: oneBook.addItem(oneItem); oneBook.getItems().add(secondItem); Η πρώτη γραμμή του κώδικα θα εισαγάγει το αντικείμενο oneItem στην (ενθυλακωμένη) συλλογή items. Η δεύτερη γραμμή όμως θα εισαγάγει το αντικείμενο secondItem σε αντίγραφο της συλλογής items. Η συλλογή items δε θα αλλάξει. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης24
25
Η χρήση συλλογών για την υλοποίηση της πολλαπλότητας Η τελική εικόνα της υλοποίησης γίνεται: public class Book { private Set items = new HashSet (); public Set getItems() { return new HashSet (items); } public void addItem(Item item) { if (item != null ) { items.add(item); } } public void removeItem(Item item) { if (item != null) { items.remove(item); } } } 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης25
26
Αμφίδρομες Συσχετίσεις Μία αμφίδρομη συσχέτιση υλοποιείται με δύο μονόδρομες. Υπάρχει όμως μία πολύ σημαντική διαφορά. Όλες οι αλλαγές στη μία μονόδρομη συσχέτιση θα πρέπει να απεικονίζονται στην άλλη. Μία αμφίδρομη συσχέτιση μεταξύ δύο κλάσεων σημαίνει αυτόματα ότι οι δύο κλάσεις είναι αμοιβαία εξαρτώμενες. Η σύζευξη των κλάσεων με αμφίδρομη συσχέτιση είναι υψηλότερη της σύζευξης με μονόδρομη. Οι αμφίδρομες συσχετίσεις δυσχεραίνουν και τη συντήρηση του λογισμικού. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης26
27
Αμφίδρομες Συσχετίσεις 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης27 public class Item { private Book book; public Book getBook() { return book; } } public class Book { private Set items = new HashSet (); public void addItem(Item item) {//…} public void removeItem(Item item) {//…} }
28
Αμφίδρομες Συσχετίσεις 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης28
29
Συσσωμάτωση Η διαφορά μεταξύ της απλής συσχέτισης και της συσσωμάτωσης είναι περισσότερο εννοιολογική. Η Java δεν προσφέρει κάποια διάκριση μεταξύ της απλής συσχέτισης και της συσσωμάτωσης. Αν ο σχεδιαστής χρησιμοποιήσει τη συσσωμάτωση στη σχεδίαση, θα πρέπει να συμφωνήσει με τους προγραμματιστές για την ερμηνεία της συσσωμάτωσης κατά την υλοποίηση. Μία πιθανή εννοιολογική ερμηνεία της συσσωμάτωσης (χωρίς να είναι και η μόνη) είναι ότι το όλο δεν μπορεί να λειτουργήσει χωρίς το τμήμα του. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης29
30
Συσσωμάτωση 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης30 public class Car { Engine engine; public void drive() throws CarException { if (engine == null ) { throw new CarException(); } // ο κώδικας της οδήγησης } Ο κώδικας υλοποίησης της συσσωμάτωσης δεν αλλάζει σε σχέση με τη συσχέτιση. Η συσσωμάτωση υλοποιείται ως ένα πεδίο τύπου Engine στην κλάση Car. Η διαφορά είναι στην υλοποίηση της μεθόδου drive. Δεν μπορούμε να οδηγήσουμε ένα αυτοκίνητο χωρίς τον κινητήρα του, οπότε η κλήση της μεθόδου drive, χωρίς να υπάρχει κινητήρας, δίδει (ρίχνει) εξαίρεση.
31
Σύνθεση Η σύνθεση είναι μία ιδιαίτερη περίπτωση της συσχέτισης όλου / τμήματος, μόνο που συνοδεύεται με κάποιους περιορισμούς. Οι περιορισμοί είναι ότι το αντικείμενο τμήμα ανήκει αποκλειστικά σε ένα αντικείμενο όλο και ότι το αντικείμενο όλο διαχειρίζεται πλήρως τον κύκλο ζωής του αντικειμένου τμήμα. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης31
32
Σύνθεση 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης32 public class Borrower { private Address address = new Address(); public void setStreet(String street) { address.setStreet(street); } public String getStreet() { return address.getStreet(); } public void setNumber(String number) { address.setNumber(number); } public String getNumber() { return address.getNumber(); } //Όλες οι μέθοδοι πρόσβασης της Address }
33
Κληρονομικότητα και διεπαφές Η χρήση της κληρονομικότητας, της υλοποίησης και των διεπαφών παρέχει συγκεκριμένες οδηγίες στον προγραμματιστή για τη μετάβαση από το σχέδιο στον κώδικα. Η μεταφορά της κληρονομικότητας και της υλοποίησης των διεπαφών από τη UML στη Java είναι και πάλι σχεδόν αυτόματη. Η μεγαλύτερη ίσως ασυνέπεια μεταξύ της UML και της Java είναι ότι η Java δεν υποστηρίζει την πολλαπλή κληρονομικότητα. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης33
34
Κληρονομικότητα και διεπαφές 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης34
35
Κληρονομικότητα και διεπαφές public interface Transport { public void move(); } public interface Vehicle extends Transport { public void drive(); } public abstract class AutoMobile implements Vehicle{ public void drive() { // Η αφηρημένη κλάση AutoMobile υλοποιεί τη μέθοδο drive } public void move() { // Η αφηρημένη κλάση AutoMobile υλοποιεί τη μέθοδο move } } 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης35
36
Κληρονομικότητα και διεπαφές public class Car extends AutoMobile{ // Η κλάση Car κληρονομεί την υλοποίηση της μεθόδου drive. // Η μέθοδος drive μπορεί να επαναοριστεί } public class Truck extends AutoMobile{ // Η κλάση Truck κληρονομεί την υλοποίηση της μεθόδου drive. // Η μέθοδος drive μπορεί να επαναοριστεί } public class Boat implements Transport{ public void move() { // Η κλάση Boat υλοποιεί τη μέθοδο move } } 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης36
37
Διαγράμματα ακολουθίας 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης37
38
Διαγράμματα ακολουθίας public class Order { private Set orderLines = new HashSet (); public int getTotal() { int total = 0; for(OrderLine orderLine : orderLines) { total += orderLine.getSubTotal(); } return total; } } public class OrderLine { private int quantity; private Product product; public int getSubTotal() { return product.getPrice(quantity); } } public class Product { private int price; public int getPrice(int quantity) { return price * quantity; } } 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης38
39
Συστάσεις αντικειμενοστρεφούς σχεδίασης συστάσεις για τη σχεδίαση μεμονωμένων κλάσεων, συστάσεις για την κληρονομικότητα και τον πολυμορφισμό, και συστάσεις για τη συνεργασία αντικειμένων 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης39
40
Σχεδίαση κλάσεων Μία κλάση θα πρέπει να απεικονίζει μία αφαίρεση. Η δημόσια διεπαφή μίας κλάσης θα πρέπει να είναι σταθερή και συνεπής με το επίπεδο αφαίρεσης της κλάσης. Μία κλάση θα πρέπει να έχει υψηλή συνεκτικότητα, εξυπηρετώντας ένα συγκεκριμένο και καλά ορισμένο σκοπό. Οι πράξεις (μέθοδοι) που επιδρούν σε κάποια δεδομένα θα πρέπει να βρίσκονται στην κλάση που είναι τα δεδομένα αυτά. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης40
41
Σχεδίαση κλάσεων Όλα τα δεδομένα μίας κλάσης θα πρέπει να έχουν ιδιωτική ορατότητα. Η δημόσια διεπαφή θα πρέπει να κρύβει λεπτομέρειες της υλοποίησής της. Η συνεκτικότητα θα πρέπει να αξιολογείται όχι μόνο στο επίπεδο της κλάσης ως ολότητας, αλλά και σε καθεμία από τις λειτουργίες της. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης41
42
Μεταβίβαση και κληρονομικότητα Η κληρονομικότητα είναι ένα από τα βασικότερα μέσα για την επαναχρησιμοποίηση λογισμικού. Το άλλο μέσο επαναχρησιμοποίησης του λογισμικού είναι η μεταβίβαση (delegation) που σε ένα αντικειμενοστρεφές σύστημα λογισμικού είναι εξίσου σημαντική με την κληρονομικότητα. Η ιδέα της μεταβίβασης είναι ότι μία κλάση μεταβιβάζει δικές της αρμοδιότητες σε κάποια άλλη κλάση, την οποία και χρησιμοποιεί μέσω ανταλλαγής μηνυμάτων. Όποτε μπορούμε, προτιμούμε τη μεταβίβαση έναντι της κληρονομικότητας (λόγω καλύτερης σύζευξης) 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης42
43
Μεταβίβαση και κληρονομικότητα 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης43
44
Κανόνες για τη χρήση μεταβίβασης και κληρονομικότητας Εάν πολλές κλάσεις έχουν κοινά δεδομένα αλλά όχι κοινή συμπεριφορά, τότε δημιουργείται μία νέα κλάση που ομαδοποιεί τα δεδομένα και οι κλάσεις συσχετίζονται με τη νέα κλάση με χρήση της μεταβίβασης. Εάν πολλές κλάσεις έχουν κοινή συμπεριφορά αλλά όχι δεδομένα, τότε δημιουργούμε είτε αφηρημένη κλάση την οποία κληρονομούν οι κλάσεις που μας ενδιαφέρουν ή μία διεπαφή την οποία υλοποιούν. Εάν πολλές κλάσεις έχουν κοινά δεδομένα και συμπεριφορά, τότε ορίζουμε μία νέα αφηρημένη ή συγκεκριμένη κλάση την οποία κληρονομούν οι κλάσεις που μας ενδιαφέρουν και η οποία ορίζει τα κοινά δεδομένα και την κοινή συμπεριφορά. Εάν πολλές κλάσεις έχουν κοινή δημόσια διεπαφή, χωρίς να έχουν κοινή υλοποίηση και πρόκειται να χρησιμοποιηθούν πολυμορφικά, τότε ορίζεται μία διεπαφή την οποία υλοποιούν οι κλάσεις. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης44
45
Η μεταβίβαση αντί της κληρονομικότητας στο σύστημα δανεισμού 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης45
46
Η μεταβίβαση αντί της κληρονομικότητας στο σύστημα δανεισμού 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης46 Αρχική εκδοχή
47
Η μεταβίβαση αντί της κληρονομικότητας στο σύστημα δανεισμού 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης47 Μεταβίβαση
48
Κληρονομικότητα Η κληρονομικότητα είναι από τα ισχυρότερα εργαλεία που παρέχονται στο σχεδιαστή και τον προγραμματιστή του λογισμικού. Όμως η χρήση της ενέχει κάποιους κινδύνους. Εάν τελικά αποφασίσουμε να χρησιμοποιήσουμε την κληρονομικότητα, υπάρχουν δύο πρόσθετοι σημαντικοί έλεγχοι για να διαπιστώσουμε τη σωστή χρήση της. Είναι η εφαρμογή του κανόνα «είναι-ένα» και η αρχή της υποκατάστασης. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης48
49
Κληρονομικότητα - ο κανόνας «είναι-ένα» Με την εφαρμογή του κανόνα «είναι-ένα» κάθε υποκλάση θα πρέπει να είναι μία λογική εξειδίκευση της υπερκλάσης της. Για παράδειγμα, εκφράσεις «ο κύκλος είναι ένα σχήμα», βοηθούν στον ορισμό της κλάσης Κύκλος ως υποκλάση της κλάσης Σχήμα. Η εφαρμογή του κανόνα στο επίπεδο της σχεδίασης θα πρέπει να περιλαμβάνει υποχρεωτικά τη δημόσια διεπαφή των κλάσεων. Η δημόσια διεπαφή της υποκλάσης θα πρέπει να υπακούει στη δημόσια διεπαφή της υπερκλάσης της. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης49
50
Η αρχή της υποκατάστασης Η αρχή της υποκατάστασης μας λέει ότι κάθε υποκλάση θα πρέπει να υποκαθιστά πλήρως την υπερκλάση της. Τα αντικείμενα μίας υποκλάσης θα πρέπει να χρησιμοποιούνται ως αντικείμενα της υπερκλάσης, χωρίς να δημιουργούνται παρενέργειες. Με την εφαρμογή της αρχής της υποκατάστασης εξετάζουμε εάν μία υποκλάση είναι πράγματι εξειδίκευση της υπερκλάσης της. Ένας απλός πρακτικός έλεγχος για την εφαρμογή της αρχής είναι να θεωρήσουμε ότι οι χρήστες της υποκλάσης χρησιμοποιούν τα αντικείμενά μέσω αναφορών στην υπερκλάση της. Ελέγχουμε δηλαδή τη συμπεριφορά της υποκλάσης, όταν οι χρήστες της δε γνωρίζουν την ύπαρξή της. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης50
51
Η αρχή της υποκατάστασης 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης51 Bird bird = new Penguin(); bird.fly();
52
Η αρχή της υποκατάστασης Στη σχεδίαση του σχήματος 8-46 ικανοποιείται ο κανόνας «είναι- ένα» αλλά παραβιάζεται η αρχή της υποκατάστασης. Η κλάση Bird έχει τη λειτουργία fly. Την κλάση την κληρονομεί η κλάση Penguin η οποία όμως δεν έχει κάποια υλοποίηση της μεθόδου fly. Μία πιθανή λύση είναι να έχουμε επίσης τη λειτουργία fly στη κλάση Penguin παρέχοντας μία κενή υλοποίηση. Έτσι όμως δε λύνουμε το πρόβλημα. Το πρόβλημα βρίσκεται στη σχεδίαση που επιλέξαμε. Εάν όντως η κλάση Penguin είναι υποκλάση της κλάσης Bird, τότε η λειτουργία fly δε θα έπρεπε να δηλωθεί στην κλάση Bird, γιατί υπάρχει τουλάχιστο μία υποκλάση της που παραβιάζει την υποκατάσταση. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης52
53
Η αρχή της υποκατάστασης 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης53 Η κληρονομικότητα της κλάσης Square ως προς την κλάση Rectangle είναι σε συμφωνία με τον κανόνα «είναι-ένα» και σύμφωνο με τη διαίσθησή μας για τη σχέση γενίκευσης και εξειδίκευσης, μιας και το τετράγωνο είναι πράγματι μία ειδική περίπτωση του ορθογωνίου παραλληλογράμμου.
54
Η αρχή της υποκατάστασης public class Rectangle { private int width; private int length; public void setWidth(int width) { this.width = width; } public int getWidth() { return width; } public void setLength(int length) { this.length = length; } public int getLength() { return length; } } 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης54
55
Η αρχή της υποκατάστασης p ublic class Square extends Rectangle { public void setWidth(int width) { super.setWidth(width); super.setLength(width); } public void setLength(int length) { super.setWidth(length); super.setLength(length); } } Το ενδιαφέρον σημείο στην παραπάνω υλοποίηση είναι ότι επαναορίσαμε τις μεθόδους setWidth και setLength στην κλάση Square, έτσι ώστε όλες οι πλευρές του τετραγώνου να είναι ίσες. Αν κάνουμε χρήση των αντικειμένων των κλάσεων χρησιμοποιώντας τους τύπους που έχουν δηλωθεί, δεν έχουμε κάποιο πρόβλημα. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης55
56
Η αρχή της υποκατάστασης Έστω για παράδειγμα ο παρακάτω κώδικας: Rectangle myRectangle = new Rectangle(); myRectangle.setLength(5); myRectangle.setWidth(10); System.out.println("Length = " + myRectangle.getLength()); System.out.println("Width = "+ myRectangle.getWidth()); Square mySquare= new Square(); mySquare.setLength(5); mySquare.setWidth(10); System.out.println("Length = " + mySquare.getLength()); System.out.println("Width = "+ mySquare.getWidth()); 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης56
57
Η αρχή της υποκατάστασης Από την εκτέλεση του παραπάνω κώδικα περιμένουμε ότι το μήκος και το πλάτος του παραλληλογράμμου θα είναι 5 και 10 αντίστοιχα, ενώ για το τετράγωνο θα είναι 10 και για τις δύο τιμές. Ένα παραλληλόγραμμο συμπεριφέρεται ως παραλληλόγραμμο και ένα τετράγωνο συμπεριφέρεται ως τετράγωνο. Η κληρονομικότητα όμως μας δίνει και τη δυνατότητα του παρακάτω κώδικα: Rectangle myRectangle = new Square(); myRectangle.setLength(5); myRectangle.setWidth(10); System.out.println("Length = " + myRectangle.getLength()); System.out.println("Width = "+ myRectangle.getWidth()); 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης57
58
Η αρχή της υποκατάστασης Αυτό που κάναμε είναι ότι εκχωρήσαμε σε μία αναφορά του τύπου Rectangle ένα αντικείμενο της κλάσης Square. Μετά τη δημιουργία του αντικειμένου εκχωρούμε ως μήκος την τιμή 5 και ως πλάτος την τιμή 10. Επειδή όμως χρησιμοποιούμε αντικείμενο της κλάσης Square και λόγω του πολυμορφισμού, θα λάβουμε στην έξοδο ως μήκος και πλάτος των πλευρών την τιμή 10. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης58
59
Σχεδίαση βάσει συμβολαίου Το ερώτημα που προκύπτει είναι βέβαια ποιοι είναι αυτοί οι κανόνες οι οποίοι οδηγούν στην παραβίαση της αρχής της υποκατάστασης και πώς αυτοί οι κανόνες διατυπώνονται. Επίσης κάτι εξίσου σημαντικό είναι πώς θα γνωρίζει ο χρήστης μίας κλάσης τους κανόνες αυτούς. Την απάντηση στο ερώτημα αυτό μας τη δίνει η σχεδίαση βάσει συμβολαίου (design by contract) που προτάθηκε από τον Meyer [Meyer 97]. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης59
60
Σχεδίαση βάσει συμβολαίου Κεντρική έννοια της σχεδίασης βάσει συμβολαίου είναι οι ισχυρισμοί (assertions) οι οποίοι χωρίζονται σε τρεις κατηγορίες και είναι: Προϋποθέσεις (preconditions). Είναι οι συνθήκες οι οποίες θα πρέπει να ισχύουν ως προϋπόθεση για την εκτέλεση μίας μεθόδου της κλάσης. Οι προϋποθέσεις δεν ελέγχονται από τη μέθοδο αλλά από τις μονάδες λογισμικού που χρησιμοποιούν τη μέθοδο. Μετασυνθήκες (postconditions). Είναι οι συνθήκες που θα πρέπει να ισχύουν μετά την εκτέλεση μίας μεθόδου. Αναλλοίωτα (invariants). Είναι οι συνθήκες που θα πρέπει να είναι αληθείς για όλα τα στιγμιότυπα της κλάσης. Ένα αναλλοίωτο μπορεί να είναι ψευδές κατά τη διάρκεια εκτέλεσης μίας μεθόδου της κλάσης, θα πρέπει όμως να επανέλθει σε αληθές, όταν η μέθοδος αυτή ολοκληρωθεί. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης60
61
Σχεδίαση βάσει συμβολαίου Οι προϋποθέσεις και οι μετασυνθήκες αφορούν τις πράξεις της κλάσης μεμονωμένα, ενώ τα αναλλοίωτα αφορούν την κλάση στο σύνολό της. Θα μπορούσαμε επομένως, όταν σχεδιάζουμε μια κλάση, να διατυπώσουμε τα αναλλοίωτα της κλάσης και τις προϋποθέσεις και μετασυνθήκες για κάθε μέθοδό της. Ένα αναλλοίωτο για παράδειγμα για την κλάση Square είναι ότι το πλάτος και το μήκος είναι πάντα ίσα. Δεν επιτρέπεται η παραβίαση του αναλλοίωτου σε καμία από τις μεθόδους της κλάσης. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης61
62
Σχεδίαση βάσει συμβολαίου και κληρονομικότητα Αυτό που κάνει η σχεδίαση βάσει συμβολαίου είναι ότι οι ισχυρισμοί διατυπώνονται σαφώς από το σχεδιαστή μίας κλάσης. Οι προϋποθέσεις και οι μετασυνθήκες αποτελούν και το συμβόλαιο της κλάσης. Κάθε χρήστης της κλάσης θα πρέπει εκτός από τη διεπαφή της κλάσης να λαμβάνει υπόψη του και το συμβόλαιό της. Το συμβόλαιο μίας κλάσης θα πρέπει να λαμβάνεται υπόψη και στη χρήση της κληρονομικότητας. Η κληρονομικότητα όμως περιπλέκει τους ισχυρισμούς της σχεδίασης βάσει συμβολαίου, επειδή αφορά τις προϋποθέσεις τις μετασυνθήκες και τα αναλλοίωτα της υποκλάσεις. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης62
63
Σχεδίαση βάσει συμβολαίου και κληρονομικότητα Οι κανόνες που ισχύουν για τη χρήση της κληρονομικότητας είναι: Όλα τα αναλλοίωτα μίας κλάσης ισχύουν και για τις υποκλάσεις της. Κατά τον επαναορισμό μίας μεθόδου μίας κλάσης σε μία υποκλάση οι προϋποθέσεις αντικαθίστανται από τις ίδιες ή ασθενέστερες. Κατά τον επαναορισμό μίας μεθόδου μίας κλάσης σε μία υποκλάση οι μετασυνθήκες αντικαθίστανται από τις ίδιες ή ισχυρότερες. Αν δούμε την κλάση Square, θα δούμε ότι παραβιάζει ένα αναλλοίωτο της κλάσης Rectangle, ότι το πλάτος και το μήκος αλλάζουν ανεξάρτητα. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης63
64
Κανόνες για τις ιεραρχίες κλάσεων Η συστηματική χρήση της κληρονομικότητας καταλήγει στην δημιουργία ιεραρχιών κληρονομικότητας. Ορισμένοι κανόνες για τον ορισμό των ιεραρχιών είναι [McConnell 04, Riel 96]: Μία ιεραρχία θα πρέπει να έχει όσο το δυνατό μικρότερο βάθος. Οι κοινές ιδιότητες και λειτουργίες σε μία ιεραρχία κληρονομικότητας θα πρέπει να τοποθετούνται όσο το δυνατό ψηλότερα στην ιεραρχία. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης64
65
Κανόνες για τις ιεραρχίες κλάσεων Η ύπαρξη μόνο ενός αντικειμένου σε μία κλάση υποδεικνύει πιθανή λανθασμένη χρήση της κληρονομικότητας. Είναι συνήθως αποτέλεσμα σύγχυσης αντικειμένων και κλάσεων. Αυτός ο κανόνας έχει βέβαια και τις εξαιρέσεις του. Μία υποκλάση γνωρίζει εξ ορισμού την υπερκλάση της, ενώ οι υπερκλάσεις δε θα πρέπει να γνωρίζουν τίποτα για τις υποκλάσεις τους. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης65
66
Πολυμορφισμός Ο πολυμορφισμός είναι ο συμπληρωματικός μηχανισμός της κληρονομικότητας. Με τη χρήση του πολυμορφισμού αποφασίζουμε στο χρόνο εκτέλεσης και όχι κατά τη μεταγλώττιση, για την υλοποίηση μίας διεπαφής. Έχουμε ήδη συναντήσει τους δύο μηχανισμούς για την επίτευξη του πολυμορφισμού. Ο πρώτος μηχανισμός είναι η κληρονομικότητα των κλάσεων και ο δεύτερος είναι η υλοποίηση των διεπαφών. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης66
67
Πολυμορφισμός Με την κληρονομικότητα κλάσεων έχουμε κληρονομικότητα διεπαφών και υλοποίησης, ενώ με τις διεπαφές κληρονομικότητα μόνο των διεπαφών. Ο πολυμορφισμός είναι ένας άριστος μηχανισμός για να διαχειριστούμε και να αποκρύψουμε στοιχεία μεταβλητότητας, όταν εφαρμόζουμε την αρχή της απόκρυψης πληροφοριών. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης67
68
Πολυμορφισμός Οι πηγές της μεταβλητότητας είναι πολλές. Η μεταβλητότητα μπορεί να αφορά αλγορίθμους, πρόσβαση σε συσκευές και εξωτερικές πηγές δεδομένων, διεπαφές χρήστη κ.ά. Η αναγνώριση των στοιχείων που είτε έχουμε την πρόθεση να αλλάξουν είτε περιμένουμε να αλλάξουν λόγω αλλαγών των απαιτήσεων είναι από τα πιο σημαντικές ενδείξεις για τη χρήση του πολυμορφισμού. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης68
69
Πολυμορφισμός Μία βασική χρήση του πολυμορφισμού είναι η απαλοιφή της λογικής που βασίζεται σε συνθήκες ελέγχου (conditional logic). Εκτός επομένως από τη συνειδητή επιλογή του πολυμορφισμού για τους λόγους που αναφέρθηκαν παραπάνω υπάρχουν και ορισμένες σοβαρές ενδείξεις που συστήνουν τη χρήση του. Η βασικότερη ένδειξη είναι η ύπαρξη συνθηκών ελέγχου (προτάσεις if και switch) στον κώδικα, οι οποίες επηρεάζουν και τη συμπεριφορά των αντικειμένων. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης69
70
Πολυμορφισμός Τα σημεία που δίνουμε τη μεγαλύτερη προσοχή είναι δύο: Όταν η χρήση των προτάσεων if και switch συνοδεύεται από έλεγχο τύπων. Για παράδειγμα, η γλώσσα Java συμπεριλαμβάνει τον τελεστή instanceοf ο οποίος ελέγχει για το αν κάποιο αντικείμενο είναι αντικείμενο κάποιας συγκεκριμένης κλάσης. Όταν ο έλεγχος επηρεάζει επιλογές για τη συμπεριφορά των αντικειμένων, τότε θα πρέπει να αντικαθίσταται ο έλεγχος του τύπου από πολυμορφισμό. Όταν η χρήση των προτάσεων if και switch ελέγχει την τιμή μίας ιδιότητας ενός αντικειμένου η οποία συνοδεύεται από επιλογές για τη συμπεριφορά του αντικειμένου. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης70
71
Πολυμορφισμός Η πρώτη περίπτωση χρήσης της if που συνοδεύεται από έλεγχο τύπων είναι παραστατική στο παρακάτω τμήμα κώδικα: if ( shape instanceof Rectangle ) { shape.drawRectangle(); } else { shape.drawCircle(); } Το παραπάνω τμήμα κώδικα χρησιμοποιεί τον τελεστή instanceof της Java για να βρει τον τύπο που ανήκει ένα αντικείμενο, έτσι ώστε να καλέσει τη σωστή μέθοδο. Το τμήμα κώδικα παρακάτω ελέγχει την τιμή ενός πεδίου του αντικείμενου με τον ίδιο σκοπό. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης71
72
Πολυμορφισμός switch (shape.type) { case Shape.RECTANGLE: shape.drawRectangle(); break; default: shape.drawCircle(); } Και για τις δύο παραπάνω περιπτώσεις συνίσταται φυσικά η χρήση του πολυμορφισμού. Ορίζουμε τη μέθοδο draw στην κλάση Shape και αφήνουμε τις υποκλάσεις Rectangle και Circle να τις επαναορίσουν. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης72
73
Συνεργασία αντικειμένων Από τα πρώτα βήματα της εξέτασης ενός προβλήματος ορίζουμε κλάσεις με δεδομένα και συμπεριφορά. Η λειτουργικότητα του λογισμικού παρέχεται με τη συνεργασία (collaboration) αντικειμένων. Για την υλοποίηση μίας περίπτωσης χρήσης δημιουργείται μία γειτονιά αντικειμένων τα οποία επικοινωνούν μέσω της ανταλλαγής μηνυμάτων. Οι αρχικές γειτονιές των αντικειμένων έχουν προσδιοριστεί ως ένα βαθμό από την ανάλυση των περιπτώσεων χρήσης. Η σχεδίαση του λογισμικού αφορά αφενός τον ορισμό των αρμοδιοτήτων των κλάσεων και αφετέρου τον τρόπο που επικοινωνούν τα αντικείμενα των κλάσεων. Οι αρμοδιότητες των κλάσεων προκύπτουν από τα διαγράμματα κλάσεων και η συνεργασία των αντικειμένων τους παρουσιάζεται με τα διαγράμματα ακολουθίας ή τα διαγράμματα επικοινωνίας. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης73
74
Χρήση των διαγραμμάτων ακολουθίας στη σχεδίαση Τα διαγράμματα ακολουθίας μάς βοηθούν να μοντελοποιήσουμε τη συμπεριφορά των αντικειμένων για την κάλυψη των απαιτήσεων. Η κύρια εργασία είναι η ανάθεση των αρμοδιοτήτων σε κλάσεις λογισμικού, η οποία συμπληρώνει ή αναθεωρεί αρμοδιότητες που έχουν ανατεθεί από την ανάλυση. Τα βασικά χαρακτηριστικά της χρήσης των διαγραμμάτων ακολουθίας είναι: Τα διαγράμματα ακολουθίας εμφανίζουν αλληλεπιδράσεις και συνεργασία αντικειμένων και όχι αλγορίθμους. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης74
75
Χρήση των διαγραμμάτων ακολουθίας στη σχεδίαση Τα διαγράμματα ακολουθίας λειτουργούν ως μέσο επικοινωνίας στην ομάδα ανάπτυξης. Τα διαγράμματα ακολουθίας λειτουργούν ως μέσο διερεύνησης εναλλακτικών λύσεων. Τα διαγράμματα ακολουθίας λειτουργούν συμπληρωματικά με τα διαγράμματα κλάσεων. Τα διαγράμματα ακολουθίας μπορούν να λειτουργήσουν ως μέσο λεπτομερούς σχεδίασης του λογισμικού. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης75
76
Ομοιόμορφη κατανομή αρμοδιοτήτων Μία από τις κεντρικές ιδέες της αντικειμενοστρεφούς σκέψης είναι η ομοιόμορφη κατανομή των αρμοδιοτήτων στις κλάσεις του λογισμικού. Σε ένα καλά σχεδιασμένο σύστημα λογισμικού δεν υπάρχει κάποια κλάση που αποτελεί κεντρικό σημείο αναφοράς της σχεδίασης. Αντίθετα, η συμπεριφορά του συστήματος προκύπτει από τη συνεργασία αντικειμένων με διαφορετικές αρμοδιότητες. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης76
77
Ομοιόμορφη κατανομή αρμοδιοτήτων Θα πρέπει επομένως να αποφεύγονται οι λεγόμενες θεϊκές κλάσεις, οι οποίες είτε γνωρίζουν πολλά είτε εκτελούν σημαντικό μέρος της λειτουργικότητας του λογισμικού. Η ομοιόμορφη κατανομή των αρμοδιοτήτων παράγει λογισμικό του οποίου οι κλάσεις έχουν λίγες και συνεκτικές αρμοδιότητες και η επιθυμητή συμπεριφορά επιτυγχάνεται με τη συνεργασία των αντικειμένων τους. Οι διεπαφές των κλάσεων ορίζουν τον τρόπο με τον οποίο ένα αντικείμενο παρέχει τις υπηρεσίες του στην υπόλοιπη γειτονιά των αντικειμένων. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης77
78
Κεντροποιημένος υπολογισμός προθεσμίας επιστροφής αντιτύπου 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης78
79
Κατανεμημένο υπολογισμός με χρήση της μεταβίβασης 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης79
80
Σύζευξη Η χαλαρή σύζευξη των μονάδων λογισμικού είναι ένα από τα σημαντικότερα ποιοτικά κριτήρια της καλής σχεδίασης. Όπως και με τη συνεκτικότητα, εφαρμόζεται και στις απλούστερες μονάδες λογισμικού που στην προκειμένη περίπτωση είναι οι κλάσεις. Υψηλή σύζευξη σημαίνει υψηλός βαθμός εξάρτησης μεταξύ δύο κλάσεων. Η σύζευξη μεταξύ κλάσεων εμφανίζεται, όταν: Υπάρχει συσχέτιση μεταξύ των κλάσεων. Αντικείμενα μίας κλάσης καλούν λειτουργίες της δεύτερης. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης80
81
Σύζευξη Αντικείμενο μίας κλάσης χρησιμοποιεί ένα αντικείμενο της δεύτερης κλάσης, σε περιπτώσεις που: α) λαμβάνει το αντικείμενο ως παράμετρο, β) το αντικείμενο επιστρέφεται από την αποστολή κάποιου μηνύματος και γ) το αντικείμενο δημιουργείται κατά την εκτέλεση κάποιας μεθόδου. Μία κλάση είναι υποκλάση κάποιας άλλης. Η σύζευξη που είναι αποτέλεσμα της κληρονομικότητας έχει δύο όψεις. Από τη μία υψηλή σύζευξη σημαίνει ότι κάνουμε ορθή χρήση της κληρονομικότητας. Από την άλλη η υψηλή σύζευξη σημαίνει ότι η ιεραρχία της κληρονομικότητας είναι επιρρεπής σε αλλαγές, ιδιαίτερα όταν αυτές γίνονται στα πρώτα επίπεδα της ιεραρχίας. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης81
82
Εμφάνιση της σύζευξης στα διαγράμματα UML 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης82
83
Σύζευξη και συνεκτικότητα των οντοτήτων του συστήματος δανεισμού 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης83
84
Σύζευξη και συνεκτικότητα των οντοτήτων του συστήματος δανεισμού 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης84
85
Σύζευξη και συνεκτικότητα των οντοτήτων του συστήματος δανεισμού 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης85
86
Σύζευξη και συνεκτικότητα των οντοτήτων του συστήματος δανεισμού 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης86
87
Επικοινωνία Αντικειμένων Η συνεργασία των αντικειμένων διέπεται από ορισμένους κανόνες για την επίτευξη ποιοτικής σχεδίασης [McConnell 04, Riel 96, Wirfs-Brock 02]. Οι πιο σημαντικοί είναι: Θα πρέπει να ελαχιστοποιείται ο αριθμός των μηνυμάτων μεταξύ των συνεργαζόμενων αντικειμένων. Θα πρέπει να ελαχιστοποιείται ο αριθμός των διαφορετικών μηνυμάτων μεταξύ συνεργαζόμενων αντικειμένων. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης87
88
Επικοινωνία Αντικειμένων Θα πρέπει να ελαχιστοποιείται ο αριθμός των παραμέτρων στην αποστολή ενός μηνύματος. Εάν ένα μήνυμα έχει ως παραμέτρους τις τιμές πολλών ιδιοτήτων ενός αντικειμένου θα πρέπει να εξετάσουμε την περίπτωση να στείλουμε το ίδιο το αντικείμενο ως παράμετρο. Θα πρέπει να είμαστε πολύ προσεκτικοί, όταν οι παράμετροι είναι πρωταρχικοί τύποι. Όταν κάποια παράμετρος είναι αφαίρεση κάποιου τύπου, τότε θα πρέπει να δημιουργούμε απλούς τύπους και αντικείμενα τιμές. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης88
89
Επικοινωνία Αντικειμένων Θα πρέπει να ελαχιστοποιούνται τα καθολικά δεδομένα ή τα καθολικά σημεία πρόσβασης. Η χρήση καθολικών δεδομένων δημιουργεί υψηλή σύζευξη των κλάσεων με τα δεδομένα αυτά. Η σύζευξη αυτή είναι επίσης δύσκολο να εντοπιστεί, γιατί η χρήση τους γίνεται εντός των μεθόδων των κλάσεων και δεν είναι τμήμα της δημόσιας διεπαφής τους. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης89
90
Επικοινωνία Αντικειμένων 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης90
91
Επικοινωνία Αντικειμένων 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης91
92
Επικοινωνία Αντικειμένων Το παρακάτω τμήμα κώδικα παρουσιάζει την υλοποίηση του διαγράμματος ακολουθίας του σήματος 8-56. public class Borrower { private BorrowerCategory category; public BorrowerCategory getCategory() { return category; } public boolean canBorrow() { int pendingItems; if (getCategory() == null ) { return false; } 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης92
93
Επικοινωνία Αντικειμένων pendingItems = countPendingItems(); return getCategory().canBorrow(pendingItems); } } public class BorrowerCategory { private int maxLendingItems; public boolean canBorrow(int pendingItems) { return maxLendingItems > pendingItems; } } 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης93
94
Επικοινωνία Αντικειμένων 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης94 Δανεισμός αντιτύπου
95
Επικοινωνία Αντικειμένων 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης95 Δημιουργία Δανεισμού
96
Επικοινωνία Αντικειμένων Παρακάτω παρουσιάζεται ο κώδικας για το διάγραμμα ακολουθίας του σχήματος. public class Item { public Loan borrow(Borrower borrower) { if (borrower == null ) { return null; } if (!borrower.canBorrow()) { return null; } Loan loan = new Loan(); loan.setItem(this); loan.setBorrower(borrower); loan.setLoanDate(Calendar.getInstance()); return loan; } } 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης96
97
Επικοινωνία Αντικειμένων 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης97 Συνολικό Διάγραμμα Δανεισμού
98
Σχεδίαση πακέτων Τα πακέτα στη σχεδίαση τοποθετούνται σε υψηλότερο επίπεδο των κλάσεων. Χρησιμοποιούμε τα πακέτα για να τμηματοποιήσουμε το λογισμικό σε διαχειρίσιμες μονάδες του λογισμικού. Τα πακέτα μας βοηθούν επίσης να παρακολουθήσουμε την ανάθεση του λογισμικού στα μέλη της ομάδας ανάπτυξης. Η ανάπτυξη του λογισμικού είναι μία ομαδική προσπάθεια και πρέπει να υπάρχει κάποιος τρόπος ανάθεσης μίας μονάδας λογισμικού σε ένα ή περισσοτέρους μηχανικούς λογισμικού της ομάδας ανάπτυξης. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης98
99
Σχεδίαση πακέτων Συνήθως η ανάθεση της κωδικοποίησης γίνεται σε επίπεδο πακέτου και όχι σε επίπεδο μεμονωμένης κλάσης. Εκτός από την οργάνωση της ανάπτυξης τα πακέτα προσφέρουν και μία βάση για τον τρόπο παράταξης (deployment) του λογισμικού η οποία γίνεται σε φυσικές μονάδες λογισμικού όπως π.χ. σε αρχεία jar ή dll. Σε ένα πολύπλοκο σύστημα λογισμικού επιθυμούμε να παραδίδουμε μία φυσική μονάδα λογισμικού ανεξάρτητα από τις υπόλοιπες φυσικές μονάδες. Τα πακέτα καθοδηγούν σε σημαντικό βαθμό και την οργάνωση του λογισμικού και σε φυσικές μονάδες λογισμικού. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης99
100
Εξαρτήσεις πακέτων 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης100 Δύο πακέτα έχουν σχέση εξάρτησης, όταν υπάρχει κάποιου είδους εξάρτησης στα περιεχόμενά τους.
101
Ορατότητα σε πακέτα 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης101 Με το σχήμα 8-61 δείχνουμε ότι εκτός του πακέτου banking είναι γνωστή μόνη η αφηρημένη κλάση Transaction. Οι κλάσεις Deposit και Withdrawal είναι γνωστές μόνο σε κλάσεις εντός του πακέτου banking.
102
Συνεκτικότητα πακέτων Το κριτήριο της συνεκτικότητας θα μας καθοδηγήσει στον τρόπο που δημιουργούνται τα πακέτα και στον τρόπο που επιλέγονται οι κλάσεις που θα τοποθετηθούν εντός των πακέτων. Το βασικότερο ίσως κριτήριο για την επίτευξη υψηλής συνεκτικότητας είναι να τοποθετούνται σε ένα πακέτο οι κλάσεις με ισχυρή εξάρτηση. Όταν τοποθετούμε κλάσεις σε ένα πακέτο, θα πρέπει να έχουμε υπόψη μας τα παρακάτω: Στο ίδιο πακέτο τοποθετούνται κλάσεις με ισχυρές στατικές εξαρτήσεις. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης102
103
Συνεκτικότητα πακέτων Στο ίδιο πακέτο τοποθετούνται κλάσεις που εξυπηρετούν τον ίδιο ή παρόμοιο σκοπό. Όταν τοποθετούμε κλάσεις με ισχυρές εξαρτήσεις επιδιώκουμε ταυτόχρονα και την επίτευξη της τοπικότητας των αλλαγών. Κλάσεις χωρίς εξαρτήσεις μπορούν να τοποθετηθούν σε διαφορετικά πακέτα, γιατί ανεξάρτητες κλάσεις παρέχουν και ευκαιρίες επαναχρησιμοποίησης. Τα πακέτα είναι ένας βασικός μηχανισμός για τη δημιουργία βιβλιοθηκών κλάσεων (class libraries). 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης103
104
Συνεκτικότητα πακέτων 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης104
105
Σύζευξη πακέτων Η σύζευξη μεταξύ των πακέτων προκύπτει από τη σύζευξη των περιεχομένων τους. Η δημιουργία πακέτων με σκοπό τη μείωση της σύζευξης συμβάλλει στη διαχείριση των αλλαγών και ιδιαίτερα στην επίτευξη της τοπικότητας των αλλαγών. Ένα φαινόμενο αυξημένης σύζευξης πακέτων είναι η εμφάνιση κυκλικών εξαρτήσεων σε ένα διάγραμμα πακέτων της UML. 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης105
106
Σύζευξη πακέτων 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης106 Απάλειψη κυκλικών εξαρτήσεων σε πακέτα
107
Σύζευξη πακέτων 2009ΟΠΑ -Τεχνολογία Λογισμικού – Εμμ. Γιακουμάκης107 Εξάρτηση και σταθερότητα
Παρόμοιες παρουσιάσεις
© 2024 SlidePlayer.gr Inc.
All rights reserved.