Εναρξη Μαθήµατος Κατανεµηµένα Συστήµατα ΙΙ Μάθηµα Ελεύθερης Επιλογής, Εαρινού Εξαµήνου Τοµέας Εφαρµογών και Θεµελιώσεων Ιωάννης Χατζηγιαννάκης Τετάρτη, 11 Μαρτίου, 2009 Αίθουσα ΑΠ7 Ο σκοπός του µαθήµατος: Σχεδιασµός κατανεµηµένων συστηµάτων (distributed systems) Τεχνικές και εργαλεία ανάπτυξης κατανεµηµένων εφαρµογών Προγραµµατισµό κατανεµηµένων εφαρµογών (distributed systems programming) Το µάθηµα ϑα διεξαχθεί γύρω από δύο άξονες: Τεχνολογίες Υλοποίησης ιαλέξεις Project Τυπικά Θέµατα Υλη Μαθήµατος (1) Θεωρία ιαλέξεις 2 ώρες την εβδοµάδα Τετάρτη 11:00-13:00, ΑΠ7 4 ϑεµατικές ενότητες Θέµατα Σχεδιασµού Τεχνολογίες Υλοποίησης Κατανεµηµένων Συστηµάτων Εργαλεία Ανάπτυξης Λογισµικού Ειδικές Πλατφόρµες Βαθµολογία Project -- 100% Θέµατα Σχεδιασµού 1. Επικοινωνία ιεργασιών 2. Σχήµατα Επικοινωνίας Request - Reply, Server - Client 3. Κλήση Αποµακρυσµένων ιαδικασιών 4. Κατανεµηµένα Αντικείµενα 5. Κατανεµηµένες Ουρές Μηνυµάτων 6. Ρεύµατα Επικοινωνίας 7. Java Enterprise Edition Τεχνολογίες Υλοποίησης Κατανεµηµένων Συστηµάτων 1. Java Server Pages 2. Java Remote Method Invocation (RMI) 3. Java Persistance -- Hibernate 4. Spring Framework
Υλη Μαθήµατος (2) Project Εργαλεία Ανάπτυξης Λογισµικού 1. CVS, Subversion 2. GForge, SourceForge, TRAC 3. IDEA IntelliJ Ειδικές Πλατφόρµες Java Micro Edition (ME) SUN Small Programmable Object Technology (SPOT) isense Google Geo API Google Android Υποχρεωτικό το 100% του τελικού ϐαθµού Πρακτικό Οµαδικό Καταγραφή Προδιαγραφών ενός Κατανεµηµένου Συστήµατος Σχεδιασµός Κατανεµηµένου Συστήµατος Μελέτη ενός προβλήµατος των ΚΣ Σχεδιασµός Κατανεµηµένου Αλγορίθµου Προγραµµατισµός / Ανάπτυξη Παρουσίαση Project 2009 Σύνοψη 2 ης ιάλεξης 1. Ανάθεση και χρονοπρογραµµατισµός ερωτηµάτων (Queries) σε δίκτυα αισθητήρων και ελεκτών 2. Σύστηµα ελέγχου δικτύου και εντοπισµού παρείσφρυσης (Intrusion Detection System) 3. Σύστηµα εντοπισµού ϑέσης σε εσωτερικούς χώρους µε χρήση πολλαπλών τεχνολογιών επικοινωνίας και καµερών 4. Συγχρονισµός ϱολογιών ετερογενών συσκευών µε χρήση πολλαπλών τεχνολογιών επικοινωνίας 5. Extremely Massive Multiplayer Browser-based Games 6. Computing Using Volunteer Resources (BOINC) Προηγούµενο Μάθηµα Θέµατα Μαθήµατος ιαδικασία Project Κατανεµηµένα Συστήµατα ΙΙ Αντικειµενοστραφής Προγραµµατισµός σε JAVA Βασικές Βιβλιοθήκες JAVA Βοηθητικά Εργαλεία Ανάπτυξης Κώδικα Σύνοψη Μαθήµατος Σύνοψη Μαθήµατος Βιβλιογραφία Επόµενη ιάλεξη
Interfaces Κατά την ανάπτυξη λογισµικού και συστηµάτων πληροφορικής είναι σηµαντικό οι προγραµµατιστές/µηχανικοί να συµφωνήσουν σε ένα κοινό API (προγραµµατιστική διεπαφή) Ενα συµβόλαιο που περιγράφει τον τρόπο επικοινωνίας µεταξύ των διαφορετικών τµηµάτων του συστήµατος. Κάθε οµάδα αναπτύσσει το τµήµα της χωρίς να έχει γνώση για τις τεχνικές λεπτοµέρειες των άλλων τµηµάτων. Η JAVA επιτρέπει την περιγραφή των κοινών διεπαφών µε την χρήση των Interfaces Ενα Interface δεν είναι αντικείµενο Λέµε ότι µια κλάση υλοποιεί ένα interface Μπορούµε να κάνουµε extend ένα interface Interfaces -- Παράδειγµα (1) Ας υποθέσουµε µια µελλοντική κοινωνία όπου τα αυτοκίνητα ελέγχονται πλήρως από υπολογιστικά συστήµατα Οι ϐιοµηχανίες αυτοκινήτων γράφουν λογισµικό (σε JAVA -- ϕυσικά) που χειρίζονται την κίνηση των αυτοκινήτων Εναρξη, Επιτάχυνση, Στροφή,... Κάποιες εταιρείες γράφουν ειδικό λογισµικό για την πλοήγηση των αυτοκινήτων µε την χρήση GPS Εντοπίζουν την ϑέση του οχήµατος, υπολογίζουν την διαδροµή και οδηγούν το αυτοκίνητο Οι αυτοκίνητο-ϐιοµηχανίες αποφασίζουν σε ένα κοινό interface που περιγράφει αναλυτικά τις µεθόδους που επιτρέπουν την πλοήγηση ενός αυτοκίνητου Οι άλλες εταιρείες χρησιµοποιούν το interface για να οδηγήσουν το αυτοκίνητο Interfaces -- Παράδειγµα (2) Interfaces -- Παράδειγµα (3) public interface OperateCar { // method signatures int turn(direction direction, double radius, double startspeed, double endspeed); int changelanes(direction direction, double startspeed, double endspeed); int signalturn(direction direction, boolean signalon); int getradarfront(double distancetocar, double speedofcar); int getradarrear(double distancetocar, double speedofcar);... public class OperateBMW760i implements OperateCar { // the OperateCar method signatures, // with implementation -- for example: int signalturn(direction direction, boolean signalon) { //code to turn BMW s LEFT turn indicator lights on //code to turn BMW s LEFT turn indicator lights off //code to turn BMW s RIGHT turn indicator lights on //code to turn BMW s RIGHT turn indicator lights off // other members, as needed -- for example, // helper classes not visible to clients of interface
Interfaces -- Παράδειγµα (4) Μπορούµε να χειριστούµε ένα αντικείµενο µέσω ενος Interface που υλοποιεί... σαν να ήταν αντικείµενο του συγκεκριµένου τύπου Με αυτόν τον τρόπο ο προγραµµατιστής έχει πρόσβαση µόνο στις µεθόδους που ορίζει το interface. OperateBMW760i car = new OperateBMW760i(); OperateCar op = car; op.signalturn(mydir, false); Μια κλάση µπορεί να υλοποιεί περισσότερα από ένα interface Interfaces -- Παράδειγµα (5) Interfaces και Κληρονοµικότητα Ενα interface µπορεί να κληρονοµεί ένα ή περισσότερα interfaces Λέµε ότι το νέο interface κάνει extend ένα άλλο interface public interface GroupedInterface extends Interface1, Interface2, Interface3 { // constant declarations double E = 2.718282; // method signatures void dosomething (int i, double x); int dosomethingelse(string s); Ολοι οι ορισµοί µεταβλητών είναι αυτόµατα public, static και final (δηλαδή constants) Interfaces -- Παράδειγµα (6) public interface Relatable { // this (object calling islargerthan) and // other must be instances of the same class // returns 1, 0, -1 if this is greater // than, equal to, or less than other public int islargerthan(relatable other); Οποιαδήποτε κλάση µπορεί να υλοποιήσει το interface Relatable αν υπάρχει κάποιος τρόπος να συγκρίνει το σχετικό της µέγεθος µε άλλα αντικείµενα που το υλοποιούν Αν γνωρίζουµε ότι µια κλάση υλοποιεί το interface Relatable τότε γνωρίζουµε ότι µπορούµε να συγκρίνουµε τα µεγέθη των αντικειµένων που έχουν αρχικοποιηθεί από αυτή την κλάση public class RectanglePlus implements Relatable { public int width = 0; public int height = 0; public Point origin; // four constructors public RectanglePlus() { origin = new Point(0, 0); public RectanglePlus(Point p) { origin = p; public RectanglePlus(int w, int h) { origin = new Point(0, 0); width = w; height = h;
Interfaces -- Παράδειγµα (7) public RectanglePlus(Point p, int w, int h) { origin = p; width = w; height = h; // a method for moving the rectangle public void move(int x, int y) { origin.x = x; origin.y = y; // a method for computing the area of the rectangle public int getarea() { return width * height; Interfaces ως τύποι δεδοµένων Οποτε ορίζουµε ένα νέο interface ορίζουµε και ένα νέο τύπο δεδοµένων Μπορούµε να χρησιµοποιήσουµε το όνοµα του interface όπως χρησιµοποιούµε οποιοδήποτε άλλο τύπο δεδοµένων Μεταβλητές µε τύπο ένα interface χρησιµοποιούνται αποκλειστικά για αναφορές σε αντικείµενα (reference variable) public Object findlargest(object object1, Object object2) { Relatable obj1 = (Relatable)object1; Relatable obj2 = (Relatable)object2; if ( (obj1).islargerthan(obj2) > 0) return object1; else return object2; Packages Η JAVA επιτρέπει την δόµηση του κώδικα µε την χρήση πακέτων (packages) Μπορούµε να τοποθετήσουµε µια κλάση σε ένα πακέτο Ενα πακέτο µπορεί να περιέχει όσες κλάσεις ϑέλουµε και υπο-πακέτα Οι ϕάκελοι που περιέχουν τον κώδικα πρέπει να ακολουθούν την ιεραρχία των πακέτων package: graphics class name: graphics.rectangle pathname: graphics\rectangle.java Καλύτερη διαχείριση του κώδικα Packages -- ηµιουργία Για κάθε κλάση/interface δηλώνουµε το πακέτο που ανήκει πριν τον ορισµό Το statement package πρέπει να είναι στην πρώτη γραµµή του αρχείου //in the Draggable.java file package graphics; public interface Draggable {... Αν δεν ορίσουµε πακέτο τότε η κλάση/interface ανήκει στο κεντρικό-ανώνυµο πακέτο
Packages -- Χρήση Για να χρησιµοποιήσουµε µια κλάση/interface από ένα συγκεκριµένο πακέτο Προσθέτουµε το όνοµα του πακέτου πριν το όνοµα της κλάσης/interface graphics.draggable graphics.rectangle myrect = new graphics.rectangle(); Μπορούµε να δηλώσουµε εξάρχής τα πακέτα που ϑέλουµε να χρησιµοποιήσουµε µε το statement import import graphics.*; Τώρα χρησιµοποιούµε τις κλάσεις/interfaces χωρίς το όνοµα του πακέτου Rectangle myrectangle = new Rectangle(); Μπορούµε να κάνουµε import συγκεκριµένες κλάσεις/interfaces από ένα πακέτο import graphics.draggable; Packages -- Ιεραρχία Η ονοµασία των πακέτων µπορεί να ακολουθεί ιεραρχική δοµή java.awt java.awt.color java.awt.font... Οι ϕάκελοι που περιέχουν τα αρχεία κάθε πακέτου επίσης ακολουθούν την ιεραρχική δοµή java\awt java\awt\color java\awt\font... Οµως όταν κάνουµε import ένα πακέτο δεν γίνονται αυτόµατα import και όλα τα πακέτα του επόµενου επιπέδου! Generic Types -- Παράδειγµα (1) Σε οποιοδήποτε µη-τετριµµένο λογισµικό τα bugs υπάρχουν πάντα! Με τον αντικειµενοστραφή προγραµµατισµό, η δηµιουργία bugs µπορεί να δηµιουργηθούν πολύ εύκολα όταν χειριζόµαστε πολλαπλούς τύπους κλάσεων public class Box { private Object object; public void add(object object) { this.object = object; public Object get() { return object; Generic Types -- Παράδειγµα (2) Εφόσον η µέθοδος δέχεται ως παράµετρο ένα Object µπορούµε να περάσουµε οποιοδήποτε τύπο κλάσης επιθυµούµε public class BoxDemo1 { public static void main(string[] args) { // ONLY place Integer objects into this box! Box integerbox = new Box(); integerbox.add(new Integer(10)); Integer someinteger = (Integer)integerBox.get();.out.println(someInteger);
Generic Types -- Παράδειγµα (3) Generic Types -- Παράδειγµα (4) public class BoxDemo2 { public static void main(string[] args) { // ONLY place Integer objects into this box! Box integerbox = new Box(); // Imagine this is one part of a large // application modified by one programmer. integerbox.add("10"); // the type is now String //... and this is another, perhaps written // by a different programmer Integer someinteger = (Integer)integerBox.get(); System.out.println(someInteger); Οταν εκτελέσουµε το BoxDemo2... Exception in thread "main" java.lang.classcastexception: java.lang.string cannot be cast to java.lang.inte at BoxDemo2.main(BoxDemo2.java:6) Ο compiler δεν µπορεί να εντοπίσει το σφάλµα Εποµένως αναγκαστικά ϑα διαπιστώσουµε το πρόβληµα κατά την εκτέλεση (runtime) Generic Types Declaration Generic Types -- Χρήση // T stands for "Type" public class Box<T> { private T t; public void add(t t) { this.t = t; public T get() { return t; Για να χρησιµοποιήσουµε ένα γενικό τύπο πρέπει να καθορίσουµε τον τύπο T -- λέµε ότι κάνουµε ένα generic type invocation Box<Integer> integerbox = new Box<Integer>(); Μπορούµε να το παροµοιάσουµε µε τον τρόπο που περνάµε παραµέτρους σε µια συνάρτηση... εδώ περνάµε ως παράµετρο τον τύπο Μια κλήση µιας γενικής κλάσης ονοµάζεται parameterized type Αντικαταστήσαµε όλες τις χρήσεις του τύπου Object µε τον γενικό τύπο T
Generic Types -- Παράδειγµα (5) Generic Types -- Παράδειγµα (6) Αν παραβιάσουµε τον παραµετροποιηµένο τύπο... public class BoxDemo3 { public static void main(string[] args) { Box<Integer> integerbox = new Box<Integer>(); integerbox.add(new Integer(10)); Integer someinteger = integerbox.get(); System.out.println(someInteger); Εκτός απο την ευκολία στον εντοπισµό σφαλµάτων κατά το compilation... επιταχύνεται και η εκτέλεση του κώδικα! Για κάθε type casting η JAVA εκτελεί εσωτερικούς ελέγχους που καθυστερούν την εκτέλεση Generic Methods BoxDemo3.java:5: add(java.lang.integer) in Box<java.lang.Integer> cannot be applied to (java.lang.string) integerbox.add("10"); ˆ 1 error Μπορούµε να χρησιµοποιήσουµε περισσότερους από 1 παραµετροποιηµένους τύπους public class Box<T,E> {... Generic Methods -- Παράδειγµα Μπορούµε να χρησιµοποιήσουµε παραµετροποιηµένους τύπους κατά τον ορισµό συναρτήσεων public class Box<T> { public <U> void inspect(u u){ System.out.println("T: " + t.getclass().getname()); System.out.println("U: " + u.getclass().getname()); public static void main(string[] args) { Box<Integer> integerbox = new Box<Integer>(); integerbox.add(new Integer(10)); integerbox.inspect("some text"); Θα δώσει ως έξοδο T: java.lang.integer U: java.lang.string
Bounded Type Parameters Σε ορισµένες περιπτώσεις ϑέλουµε να περιορίσουµε τον παραµετροποιηµένο τύπο public <U extends Number> void inspect(u u){ System.out.println("T: " + t.getclass().getname()); System.out.println("U: " + u.getclass().getname()); Μπορούµε να δηλώσουµε επιπλέον τύπους Collections Οι συλλογές (collections) είναι γνωστές και ως Containers Είναι αντικείµενα που περιέχουν άλλα αντικείµενα Επιτρέπουν την αποθήκευση, διαχείριση και µεταφορά δεδοµένων Παραδείγµατα: Vector, Hashtable, array Στην JAVA οι συλλογές ορίζουν ένα πλαίσιο εργασίας γνωστό και ως Collections framework Ορίζει συγκεκριµένες κοινές διεπαφές (interfaces) Υλοποιεί κλάσεις που ακολουθούν τις διεπαφές (implementations) Προσφέρει συγκεκριµένους αλγόριθµους για την διαχείριση του περιεχοµένου Βοηθάει στην γρήγορη ανάπτυξη κώδικα µείωση του κώδικα Οι υλοποιήσεις είναι υψηλού επιπέδου επιταχύνει τον κώδικα <U extends Number & MyInterface> Collections -- Interfaces Collection Interface Ολες οι διεπαφές είναι υλοποιηµένες µέσω γενικού προγραµµατισµού public interface Collection<E> {... List<String> list = new ArrayList<String>(c); public interface Collection<E> extends Iterable<E> { int size(); boolean isempty(); boolean contains(object element); boolean add(e element); boolean remove(object element); Iterator<E> iterator(); boolean containsall(collection<?> c); boolean addall(collection<? extends E> c); boolean removeall(collection<?> c); boolean retainall(collection<?> c); void clear(); Object[] toarray(); <T> T[] toarray(t[] a);
Collection Interface -- Πρόσβαση στα περιεχόµενα ύο ϐασικοί τρόποι υπάρχουν για την πρόσβαση στα δεδοµένα 1. Με την χρήση του construct for-each 2. Με την χρήση Iterators Iterators Επιτρέπουν την προσπέλαση στα δεδοµένα ανεξάρτητα από την δοµή for (Object o : collection) System.out.println(o); Εναλλακτικά µπορούµε να µετατρέψουµε µια συλλογή σε πίνακα Object[] a = c.toarray(); String[] a = c.toarray(new String[0]); public interface Iterator<E> { boolean hasnext(); E next(); void remove(); //optional static void filter(collection<?> c) { for(iterator<?> it = c.iterator();it.hasnext();) if (!cond(it.next())) it.remove(); Set Interface -- Γενικά Set Interface Ενα Set είναι µια συλλογή που δεν επιτρέπει διπλές εγγραφές Λογική αφαίρεση του µαθηµατικού συνόλου Η JAVA προσφέρει διάφορες υλοποιήσεις του interface Set 1. HashSet -- τα περιεχόµενα αποθηκεύονται σε hash table 2. TreeSet -- τα περιεχόµενα αποθηκεύονται σε red-black tree 3. LinkedHashSet -- τα περιεχόµενα αποθηκεύονται σε hash table µαζί µε µια ϐοηθητική linked list για γρήγορη σειριακή προσπέλαση Ευκολία στην χρήση... Collection c =... Collection<Type> nodups = new HashSet<Type>(c); Collection<Type> nodups = new LinkedHashSet<Type>(c); public interface Set<E> extends Collection<E> { int size(); boolean isempty(); boolean contains(object element); boolean add(e element); boolean remove(object element); Iterator<E> iterator(); boolean containsall(collection<?> c); boolean addall(collection<? extends E> c); boolean removeall(collection<?> c); boolean retainall(collection<?> c); void clear(); Object[] toarray(); <T> T[] toarray(t[] a);
IDEA IntelliJ 8.0 Subversion (SVN) Ενα ιδιαίτερα προηγµένο ενοποιηµένο περιβάλλον ανάπτυξης κώδικα JAVA Εστιάζει στην παραγωγικότητα του προγραµµατιστή Αυτόµατη παραγωγή κώδικα Αυτόµατη µορφοποίηση κώδικα Αυτόµατη εισαγωγή σχολείων JavaDOC Αυτόµατη αναδιοργάνωση κώδικα... http://www.jetbrains.com/idea License Key User Name: University of Patras License Key 1: 60878-YLS34-60U2Q-4DXFC-3VVO2-Q49X6 Ενα σύστηµα διαχείρισης εκδόσεων κώδικα (version management system) Εξέλιξη του CVS (Concurrent Versioning System) Βασικό εργαλείο κατά την ανάπτυξη κώδικα ανεξάρτητα από το µέγεθος της οµάδας ηµιουργεί repositories για την αποθήκευση του κώδικα Για κάθε αρχείο και ϕάκελο διατηρεί όλες τις προηγούµενες εκδόσεις Μπορούµε να ανατρέξουµε σε προηγούµενες εκδόσεις, να εντοπίσουµε τις διαφορές Κάθε ϕορά που κάνουµε µια αλλαγή σε κάποιο αρχείο/φάκελο του repository αυξάνει κατά ένα το revision number Μπορεί να παίξει τον ϱόλο backup http://subversion.tigris.org/ Subversion (SVN) -- Βασικές Εννοιες Σε ένα κεντρικό σύστηµα δηµιουργούµε ένα νέο repository Εγκαθιστούµε ένα SVN Server Χρησιµοποιούµε την εντολή svnadmin create <directory> Από ένα τερµατικό συνδεόµαστε µε το repository κάνοντας checkout Εγκαθιστούµε ένα SVN Client Χρησιµοποιούµε την εντολή svn checkout <repository-url> Προσθέτουµε νέα αρχεία/φακέλους µε την εντολή svn add <file> Ενηµερώνουµε τα τοπικά αρχεία µε τις τελευταίες αλλαγές µε την εντολή svn update Μεταφέρουµε στο repository τις τοπικές αλλαγές µε την εντολή svn commit Για να σβήσουµε ένα αρχείο από το repository χρησιµοποιούµε την εντολή svn delete <file> Subversion (SVN) -- Λογισµικά Για την εγκατάσταση ενός SVN Server Αναλόγως το ΛΣ του κεντρικού συστήµατος Μπορεί να συνδεθεί µε κάποιον Web Server Μπορεί να τρέξει και ως standalone server Ενας πολύ καλός client για τα Windows -- Tortoise SVN http://tortoisesvn.tigris.org/ Ενσωµατώνει τις λειτουργίες του Subversion στον Explorer Ενας καλός client για τα Linux -- KDE SVN http://kdesvn.alwins-world.de/ Το IDEA IntelliJ έχει εναν ενσωµατωµένο SVN Client Για την εξαγωγή στατιστικών σε ένα repository µπορούµε να χρησιµοποιήσουµε το http://sourceforge.net/projects/svnstat
Σύνοψη 2 ης ιάλεξης Σύνοψη Μαθήµατος Προηγούµενο Μάθηµα Θέµατα Μαθήµατος ιαδικασία Project Κατανεµηµένα Συστήµατα ΙΙ Αντικειµενοστραφής Προγραµµατισµός σε JAVA Βασικές Βιβλιοθήκες JAVA Βοηθητικά Εργαλεία Ανάπτυξης Κώδικα Σύνοψη Μαθήµατος Σύνοψη Μαθήµατος Βιβλιογραφία Επόµενη ιάλεξη Αντικειµενοστραφής Προγραµµατισµός σε JAVA Interface Package Generic Types Collections Framework Βοηθητικά Εργαλεία Ανάπτυξης Κώδικα IDEA IntelliJ Subversion (SVN) Βιβλιογραφία Επόµενη ιάλεξη Trail: Learning the Java Language http://java.sun.com/docs/books/tutorial/ java/toc.html Trail: Collections http://java.sun.com/docs/books/tutorial/ collections/index.html Version Control with Subversion http://svnbook.red-bean.com/ The world s largest Open Source software development web site http://sourceforge.net/ Επανάληψη στη JAVA Θέµατα Σχεδιασµού Σχεδιαστικά Θέµατα Project