Αντικειμενοστρεφής προγραμματισμός

Στην πληροφορική αντικειμενοστρεφή προγραμματισμό (object-oriented programming)[1][2] ή ΑΠ, ονομάζουμε ένα προγραμματιστικό υπόδειγμα το οποίο εμφανίστηκε στα τέλη της δεκαετίας του 1970 και καθιερώθηκε κατά τη δεκαετία του 1990, αντικαθιστώντας σε μεγάλο βαθμό το παραδοσιακό υπόδειγμα του δομημένου προγραμματισμού. Πρόκειται για μία μεθοδολογία ανάπτυξης προγραμμάτων, υποστηριζόμενη από κατάλληλες γλώσσες προγραμματισμού, όπου ο χειρισμός σχετιζόμενων δεδομένων και των διαδικασιών που επενεργούν σε αυτά γίνεται από κοινού, μέσω μίας δομής δεδομένων που τα περιβάλλει ως αυτόνομη οντότητα με ταυτότητα και δικά της χαρακτηριστικά. Αυτή η δομή δεδομένων καλείται αντικείμενο και αποτελεί πραγματικό στιγμιότυπο στη μνήμη ενός σύνθετου, και πιθανώς οριζόμενου από τον χρήστη, τύπου δεδομένων που ονομάζεται κλάση (class). Η κλάση προδιαγράφει τόσο δεδομένα όσο και τις διαδικασίες οι οποίες επιδρουζν επάνω τους· αυτή υπήρξε η πρωταρχική καινοτομία του ΑΠ.

Έτσι μπορεί να οριστεί μία προδιαγραφή δομής αποθήκευσης (π.χ. μία κλάση «τηλεόραση») η οποία να περιέχει τόσο ιδιότητες (π.χ. μία μεταβλητή (variable) «τρέχον κανάλι») όσο και πράξεις ή χειρισμούς επί αυτών των ιδιοτήτων (π.χ. μία διαδικασία (method/function) «άνοιγμα της τηλεόρασης»). Στο εν λόγω παράδειγμα κάθε υλική τηλεόραση (κάθε αντικείμενο αποθηκευμένο πραγματικά στη μνήμη) αναπαρίσταται ως ξεχωριστό, «φυσικό» στιγμιότυπο αυτής της πρότυπης, ιδεατής κλάσης. Επομένως μόνο τα αντικείμενα καταλαμβάνουν χώρο στη μνήμη του υπολογιστή ενώ οι κλάσεις αποτελούν απλώς «καλούπια». Οι αιτίες που ώθησαν στην ανάπτυξη του ΑΠ ήταν οι ίδιες με αυτές που οδήγησαν στην ανάπτυξη του δομημένου προγραμματισμού (ευκολία συντήρησης, οργάνωσης, χειρισμού και επαναχρησιμοποίησης κώδικα μεγάλων και πολύπλοκων εφαρμογών), όμως τελικώς η αντικειμενοστρέφεια επικράτησε καθώς μπορούσε να ανταπεξέλθει σε προγράμματα πολύ μεγαλύτερου όγκου και πολυπλοκότητας.

Ιστορικό

Οι περισσότερες αντικειμενοστρεφείς έννοιες εμφανίστηκαν αρχικά στη γλώσσα προγραμματισμού Simula 67, η οποία ήταν προσανατολισμένη στην εκτέλεση προσομοιώσεων του πραγματικού κόσμου. Οι ιδέες της Simula 67 επηρέασαν κατά τη δεκαετία του '70 την ανάπτυξη της Smalltalk, της γλώσσας που εισήγαγε τον όρο αντικειμενοστρεφής προγραμματισμός. Η Smalltalk αναπτύχθηκε από τον Άλαν Κέι (Alan Key) της εταιρείας Xerox στο πλαίσιο μίας εργασίας με στόχο τη δημιουργία ενός χρήσιμου, αλλά και εύχρηστου, προσωπικού υπολογιστή. Όταν η τελική έκδοση της Smalltalk έγινε διαθέσιμη το 1980 η έρευνα για την αντικατάσταση του δομημένου προγραμματισμού με ένα πιο σύγχρονο υπόδειγμα ήταν ήδη εν εξελίξει. Στη γλώσσα αυτή όλοι οι τύποι δεδομένων ήταν κλάσεις (δεν υπήρχαν δηλαδή πια παραδοσιακές δομές δεδομένων παρά μόνο αντικείμενα).

Την ίδια περίπου εποχή, και επίσης με επιρροές από τη Simula, ολοκληρωνόταν η ανάπτυξη της C++ ως μίας ισχυρής επέκτασης της δημοφιλούς γλώσσας προγραμματισμού C στην οποία είχαν "μεταμοσχευθεί" αντικειμενοστρεφή χαρακτηριστικά. Η επιρροή της C++ καθ' όλη της δεκαετία του '80 ήταν καταλυτική με αποτέλεσμα τη σταδιακή κυκλοφορία αντικειμενοστρεφών εκδόσεων πολλών γνωστών διαδικαστικών γλωσσών προγραμματισμού. Κατά το πρώτο ήμισυ της δεκαετίας του '90 η βαθμιαία καθιέρωση στους μικροϋπολογιστές των γραφικών διασυνδέσεων χρήστη (GUI), για την ανάπτυξη των οποίων ο ΑΠ φαινόταν ιδιαιτέρως κατάλληλος, και η επίδραση της C++ οδήγησαν στην επικράτηση της αντικειμενοστρέφειας ως βασικού προγραμματιστικού υποδείγματος.

Το 1995 η εμφάνιση της Java, μίας ιδιαίτερα επιτυχημένης, πλήρως αντικειμενοστρεφούς γλώσσας που έμοιαζε συντακτικώς με τη C/C++ και προσέφερε πρωτοποριακές για την εποχή δυνατότητες, έδωσε νέα ώθηση στον ΑΠ. Παράλληλα εμφανίστηκαν ποικίλες άτυπες βελτιώσεις στο βασικό προγραμματιστικό υπόδειγμα, όπως οι αντικειμενοστρεφείς γλώσσες μοντελοποίησης λογισμικού, τα σχεδιαστικά πρότυπα κ.λπ. Το 2001 η Microsoft εστίασε την προσοχή της στην πλατφόρμα .NET, μία ανταγωνιστική της Java πλατφόρμα ανάπτυξης και εκτέλεσης λογισμικού, η οποία ήταν εξ ολοκλήρου προσανατολισμένη στην αντικειμενοστρέφεια.

Έννοιες

Κεντρική ιδέα στον αντικειμενοστρεφή προγραμματισμό είναι η κλάση (class), μία αυτοτελής και αφαιρετική αναπαράσταση κάποιας κατηγορίας αντικειμένων, είτε φυσικών αντικειμένων του πραγματικού κόσμου είτε νοητών, εννοιολογικών αντικειμένων, σε ένα περιβάλλον προγραμματισμού. Πρακτικώς είναι ένας τύπος δεδομένων, ή αλλιώς το προσχέδιο μιας δομής δεδομένων με δικά της περιεχόμενα, τόσο μεταβλητές όσο και διαδικασίες. Τα περιεχόμενα αυτά δηλώνονται είτε ως δημόσια (public) είτε ως ιδιωτικά (private), με τα ιδιωτικά να μην είναι προσπελάσιμα από κώδικα εκτός της κλάσης. Οι διαδικασίες των κλάσεων συνήθως καλούνται μέθοδοι (methods) και οι μεταβλητές τους γνωρίσματα (attributes) ή πεδία (fields). Μία κλάση πρέπει ιδανικά να είναι εννοιολογικά αυτοτελής, να περιέχει δηλαδή μόνο πεδία τα οποία περιγράφουν μία κατηγορία αντικειμένων και δημόσιες μεθόδους οι οποίες επενεργούν σε αυτά όταν καλούνται από το εξωτερικό πρόγραμμα, χωρίς να εξαρτώνται από άλλα δεδομένα ή κώδικα εκτός της κλάσης, και επαναχρησιμοποιήσιμη, να αποτελεί δηλαδή μαύρο κουτί δυνάμενο να λειτουργήσει χωρίς τροποποιήσεις ως τμήμα διαφορετικών προγραμμάτων.

Αντικείμενο (object) είναι το στιγμιότυπο μίας κλάσης, δηλαδή αυτή καθαυτή η δομή δεδομένων (με αποκλειστικά δεσμευμένο χώρο στη μνήμη) βασισμένη στο «καλούπι» που προσφέρει η κλάση. Παραδείγματος χάριν, σε μία αντικειμενοστρεφή γλώσσα προγραμματισμού θα μπορούσαμε να ορίσουμε κάποια κλάση ονόματι BankAccount, η οποία αναπαριστά έναν τραπεζικό λογαριασμό, και να δηλώσουμε ένα αντικείμενο της με όνομα MyAccount. Το αντικείμενο αυτό θα έχει δεσμεύσει χώρο στη μνήμη με βάση τις μεταβλητές και τις μεθόδους που περιγράψαμε όταν δηλώσαμε την κλάση. Έτσι, στο αντικείμενο θα μπορούσε να περιέχεται ένα γνώρισμα Balance (=υπόλοιπο) και μία μέθοδος GetBalance (=επίστρεψε το υπόλοιπο). Ακολούθως, θα μπορούσαμε να δημιουργήσουμε ακόμα ένα ή περισσότερα αντικείμενα της ίδιας κλάσης, τα οποία θα είναι διαφορετικές δομές δεδομένων (διαφορετικοί τραπεζικοί λογαριασμοί στο παράδειγμα). Τα αντικείμενα μιας κλάσης μπορούν να προσπελάσουν τα ιδιωτικά περιεχόμενα άλλων αντικειμένων της ίδιας κλάσης.

Ενθυλάκωση δεδομένων (data encapsulation) καλείται η ιδιότητα που προσφέρουν οι κλάσεις να «κρύβουν» τα ιδιωτικά δεδομένα τους από το υπόλοιπο πρόγραμμα και να εξασφαλίζουν πως μόνο μέσω των δημόσιων μεθόδων τους θα μπορούν αυτά να προσπελαστούν. Αυτή η τακτική παρουσιάζει μόνο οφέλη καθώς εξαναγκάζει κάθε εξωτερικό πρόγραμμα να φιλτράρει το χειρισμό που επιθυμεί να κάνει στα πεδία μίας κλάσης μέσω των ελέγχων που μπορούν να περιέχονται στις δημόσιες μεθόδους της κλάσης.

Αφαίρεση δεδομένων καλείται η ιδιότητα των κλάσεων να αναπαριστούν αφαιρετικά πολύπλοκες οντότητες στο προγραμματιστικό περιβάλλον. Μία κλάση αποτελεί ένα αφαιρετικό μοντέλο κάποιας κατηγορίας αντικειμένων. Επίσης, οι κλάσεις προσφέρουν και αφαίρεση ως προς τον υπολογιστή, εφόσον η καθεμία μπορεί να θεωρηθεί ένας μικρός και αυτάρκης υπολογιστής (με δική του κατάσταση, μεθόδους και μεταβλητές).

Κληρονομικότητα ονομάζεται η ιδιότητα των κλάσεων να επεκτείνονται σε νέες κλάσεις, ρητά δηλωμένες ως κληρονόμους (υποκλάσεις ή 'θυγατρικές κλάσεις'), οι οποίες μπορούν να επαναχρησιμοποιήσουν τις μεταβιβάσιμες μεθόδους και ιδιότητες της γονικής τους κλάσης αλλά και να προσθέσουν δικές τους. Στιγμιότυπα των θυγατρικών κλάσεων μπορούν να χρησιμοποιηθούν όπου απαιτούνται στιγμιότυπα των γονικών (εφόσον η θυγατρική είναι κατά κάποιον τρόπο μία πιο εξειδικευμένη εκδοχή της γονικής), αλλά το αντίστροφο δεν ισχύει. Παράδειγμα κληρονομικότητας είναι μία γονική κλάση Vehicle (=Όχημα) και οι δύο πιο εξειδικευμένες υποκλάσεις της Car (=Αυτοκίνητο) και Bicycle (=Ποδήλατο), οι οποίες λέμε ότι "κληρονομούν" από αυτήν. Πολλαπλή κληρονομικότητα είναι η δυνατότητα που προσφέρουν ορισμένες γλώσσες προγραμματισμού μία κλάση να κληρονομεί ταυτόχρονα από περισσότερες από μία γονικές. Από μία υποκλάση μπορούν να προκύψουν νέες υποκλάσεις που κληρονομούν από αυτήν, με αποτέλεσμα μία ιεραρχία κλάσεων που συνδέονται μεταξύ τους "ανά γενιά" με σχέσεις κληρονομικότητας.

Υπερφόρτωση μεθόδου (method overloading) είναι η κατάσταση κατά την οποία υπάρχουν, στην ίδια ή σε διαφορετικές κλάσεις, μέθοδοι με το ίδιο όνομα και πιθανώς διαφορετικά ορίσματα. Αν πρόκειται για μεθόδους της ίδιας κλάσης διαφοροποιούνται μόνο από τις διαφορές τους στα ορίσματα και στον τύπο επιστροφής.

Υποσκέλιση μεθόδου (method overriding) είναι η κατάσταση κατά την οποία μία θυγατρική κλάση και η γονική της έχουν μία μέθοδο ομώνυμη και με τα ίδια ορίσματα. Χάρη στη δυνατότητα του πολυμορφισμού ο μεταγλωττιστής «ξέρει» πότε να καλέσει ποια μέθοδο, βασισμένος στον τύπο του τρέχοντος αντικειμένου. Δηλαδή πολυμορφισμός είναι η δυνατότητα των αντικειμενοστρεφών μεταγλωττιστών να αποφασίζουν δυναμικά ποια είναι η κατάλληλη να κληθεί μέθοδος σε συνθήκες υποσκέλισης.

Αφηρημένη κλάση (abstract class) είναι μία κλάση που ορίζεται μόνο για να κληρονομηθεί σε θυγατρικές υποκλάσεις και δεν υπάρχουν δικά της στιγμιότυπα (αντικείμενα). Η αφηρημένη κλάση ορίζει απλώς ένα "συμβόλαιο" το οποίο θα πρέπει να ακολουθούν οι υποκλάσεις της όσον αφορά τις υπογραφές των μεθόδων τους (όπου ως υπογραφή ορίζεται το όνομα, τα ορίσματα και η τιμή επιστροφής μίας διαδικασίας). Μία αφηρημένη κλάση μπορεί να έχει και μη αφηρημένες μεθόδους οι οποίες υλοποιούνται στην ίδια την κλάση (αν και φυσικά μπορούν να υποσκελίζονται σε υποκλάσεις). Αντιθέτως, οι αφηρημένες μέθοδοί της είναι απλώς ένας ορισμός της υπογραφής τους και εναπόκειται στις υποκλάσεις να τις υλοποιήσουν. Μία αφηρημένη κλάση που δεν έχει γνωρίσματα και όλες οι μέθοδοί της είναι αφηρημένες και δημόσιες καλείται διασύνδεση (interface). Οι κλάσεις που κληρονομούν από μία διασύνδεση λέγεται ότι την "υλοποιούν".

Ακολουθεί ένα απλό παράδειγμα σε γλώσσα προγραμματισμού Java:

interface Logger {
   public void log(String msg);
}

class ConsoleLogger implements Logger {
   public void log(String msg) {
      System.err.println("\nConsole logging..." + msg + "\n");
   }
}

class FileLogger implements Logger {
   public void log(String msg) {
       System.out.println("\nFile logging..." + msg + "\n");
   }
}

public class LogTest {
    public static void main(String[] args) {
       if (args.length != 1) {
           System.out.println("\nError. Exiting...");
           return;
       }
       Logger logg;
       String choice = args[0];
       if (choice.equals("FileLogger")) {
          logg = new FileLogger();
       } else if (choice.equals("ConsoleLogger")) {
          logg = new ConsoleLogger();
       } else {
          System.err.println("\nError. Exiting...");
          return;
       }
       logg.log("Log This!");
    }
}

Στο παραπάνω παράδειγμα ορίζουμε μία διασύνδεση Logger η οποία παρέχει την υπογραφή μίας μεθόδου log, που υποθέτουμε πως πρέπει να καταγράφει κάπου πληροφορίες για τα σφάλματα που συναντά η εφαρμογή όταν εκτελείται (οι πληροφορίες αυτές τής μεταβιβάζονται με το αλφαριθμητικό όρισμα msg). Η κλάση ConsoleLogger και η κλάση FileLogger είναι δύο διαφορετικές κλάσεις που υλοποιούν τη διασύνδεση Logger και υποσκελίζουν, η καθεμία με διαφορετικό τρόπο, τη μέθοδο log ώστε η μία να καταγράφει πληροφορίες στην οθόνη και η άλλη σε κάποιο αρχείο.

Το πρόγραμμα LogTest είναι ένα μικρό δοκιμαστικό πρόγραμμα το οποίο δέχεται ως όρισμα γραμμής εντολών το πού επιθυμεί ο χρήστης να γίνεται η καταγραφή και δημιουργεί ένα στιγμιότυπο της αντίστοιχης κλάσης: της ConsoleLogger ή της FileLogger. Το στιγμιότυπο αυτό δηλώνεται με τον γενικότερο τύπο Logger, τον τύπο δηλαδή της διασύνδεσης που υλοποιούν και οι δύο κλάσεις, αλλά χάρη στον πολυμορφισμό καλείται αυτομάτως η κατάλληλη εκδοχή της μεθόδου log.

Αρχές αντικειμενοστρεφούς σχεδίασης

Με το πέρασμα του χρόνου κωδικοποιήθηκαν κάποιες ανεπίσημες αρχές για την ορθή σχεδίαση αντικειμενοστρεφών συστημάτων λογισμικού. Οι αρχές αυτές παρουσιάστηκαν κατά καιρούς σε βιβλία και άρθρα ακαδημαϊκών και αναγνωρισμένων μηχανικών λογισμικού. Οι σπουδαιότερες αρχές είναι οι παρακάτω:

  • Αρχή ανοιχτότητας-κλειστότητας (open-closed principle), του δημιουργού της γλώσσας προγραμματισμού Eiffel Μπέρτραντ Μέιερ. Η αρχή αυτή δηλώνει πως τα συστατικά ενός προγράμματος πρέπει να είναι "ανοιχτά" ως προς την επέκταση των δυνατοτήτων του συστήματος αλλά "κλειστά" ως προς αλλαγές στην υλοποίηση του. Πρακτικώς αυτό σημαίνει οι διάφορες κλάσεις και τα υπόλοιπα τμήματα λογισμικού να μη χρειάζεται να τροποποιηθούν σε περίπτωση που προστεθεί νέα λειτουργικότητα στο σύστημα (π.χ. μία νέα κλάση) προκειμένου να την αξιοποιήσουν. Βεβαίως είναι αδύνατο να μη χρειάζεται να τροποποιηθεί τίποτα, οπότε αυτό που επιτάσσει στην πραγματικότητα η εν λόγω αρχή είναι η ελαχιστοποίηση και η συγκέντρωση, κατά προτίμηση σε ένα μικρό τμήμα του κώδικα, των γραμμών που θα πρέπει να αλλάξουν. Αυτό συνήθως επιτυγχάνεται μέσω αφαίρεσης (με αφηρημένες κλάσεις ή διασυνδέσεις και πραγματικές κλάσεις που κληρονομούν από αυτές) και με χρήση του πολυμορφισμού. Έτσι, στο παράδειγμα της προηγούμενης ενότητας αν προσθέσουμε και μία τρίτη υλοποίηση της διασύνδεσης Logger, την PrinterLogger η οποία "καταγράφει" σφάλματα αποστέλλοντας τα προς εκτύπωση, ο κώδικας του προγράμματος γίνεται:
public class LogTest {
    public static void main(String[] args) {
       if (args.length != 1) {
           System.out.println("\nError. Exiting...");
           return;
       }
       Logger logg;
       String choice = args[0];
       if (choice.equals("FileLogger")) {
          logg = new FileLogger();
       } else if(choice.equals("ConsoleLogger")) {
          logg = new ConsoleLogger();
       } else if(choice.equals("PrinterLogger")) {
          logg = new PrinterLogger();
       } else {
          System.err.println("\nError. Exiting...");
          return;
       }
       logg.log("Log This!");
    }
}

Όπως φαίνεται μόνη αλλαγή είναι η προσθήκη μίας ακόμα δήλωσης else if. Η εντολή

logg.log("Log This!");

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

  • Αρχή υποκατάστασης Λίσκοφ (Liskov substitution principle), της επιστήμονα υπολογιστών Μπάρμπαρα Λίσκοφ. Η αρχή αυτή συμπυκνώνεται στον παρακάτω κανόνα για σχηματισμό μίας ορθής ιεραρχίας κλάσεων: μία κλάση Κ1 μπορεί να υλοποιηθεί ως υποκλάση μίας κλάσης Κ2 αν κάθε πρόγραμμα Π το οποίο λειτουργεί με αντικείμενα Κ2 συμπεριφέρεται με τον ίδιο τρόπο και με αντίστοιχα αντικείμενα Κ1. Έτσι με την αρχή υποκατάστασης Λίσκοφ φαίνεται πως για να οριστεί μία κλάση ως θυγατρική μίας άλλης δεν αρκεί να έχουν διαισθητικά μία ανάλογη εννοιολογική σχέση (π.χ. μία κλάση που αναπαριστά όχημα και μία που αναπαριστά αυτοκίνητο) αλλά, στο πλαίσιο του υπό εξέταση προγράμματος, τα αντικείμενα της υποκλάσης να έχουν πάντα την ίδια προγραμματιστική συμπεριφορά με τα αντικείμενα της υπερκλάσης υπό τις ίδιες συνθήκες.
  • Αρχή αντιστροφής εξαρτήσεων (dependency inversion principle), του γνωστού μηχανικού λογισμικού Ρόμπερτ Σέσιλ Μάρτιν. Η αρχή αυτή πρακτικά αποτελεί εκλέπτυνση της αρχής ανοιχτότητας-κλειστότητας, προϋποθέτοντας όμως χρήση και της αρχής υποκατάστασης Λίσκοφ. Αφορά ιεραρχίες κληρονομικότητας κλάσεων και τη χρήση αντικειμένων αυτών των ιεραρχιών από εξωτερικά προγράμματα. Στα πλαίσια της αρχής αντιστροφής εξαρτήσεων ένα τμήμα λογισμικού Α (π.χ. μία κλάση) το οποίο χρησιμοποιεί τις υπηρεσίες που παρέχει ένα άλλο τμήμα λογισμικού Β, καλώντας για παράδειγμα μία μέθοδό του, θεωρείται στοιχείο "υψηλότερου επιπέδου" σε σχέση με το Β. Η αρχή λέει πως τα υψηλού επιπέδου στοιχεία δεν πρέπει να εξαρτώνται από την υλοποίηση χαμηλότερου επιπέδου στοιχείων, αλλά πως και τα δύο πρέπει να βασίζονται σε ενδιάμεσα επίπεδα αφαίρεσης. Στην πράξη αυτή η αφαίρεση είναι μία διασύνδεση (ή αφηρημένη κλάση) την οποία γνωρίζει το υψηλού επιπέδου στοιχείο Α και υλοποιεί το χαμηλού επιπέδου στοιχείο Β. Ακόμα και αν το Β αλλαχθεί με μία κλάση Γ η οποία επίσης υλοποιεί την ίδια διασύνδεση, το Α θα πρέπει να συνεχίσει να λειτουργεί χωρίς καμία τροποποίηση. Η αρχή αντιστροφής εξαρτήσεων δεν είναι παρά ένα απτό παράδειγμα χρήσης ιεραρχικών επιπέδων με τη βοήθεια ενδιάμεσων αφαιρέσεων, μίας πρακτικής που εφαρμόζεται κατά κόρον στην επιστήμη υπολογιστών (για ένα άλλο παράδειγμα βλέπε δίκτυα υπολογιστών).
  • Αρχή διαχωρισμού διασυνδέσεων (interface segregation principle), του μηχανικού λογισμικού Ρόμπερτ Σέσιλ Μάρτιν. Η εν λόγω αρχή σημαίνει ότι σε περιπτώσεις όπου διαφορετικά υποσύνολα μεθόδων μίας κλάσης αφορούν διαφορετικές περιπτώσεις χρήσης της κλάσης, σκόπιμο είναι να ορίζουμε επιμέρους διασυνδέσεις τις οποίες η κλάση θα υλοποιεί. Κάθε τέτοια διασύνδεση θα ορίζει μόνο το αντίστοιχο υποσύνολο των μεθόδων.
  • Αρχή μοναδικής αρμοδιότητας (single responsibility principle), των Τομ Ντε Μάρκο και Μέιρ Πέιτζ Τζόουνς. Σύμφωνα με την αρχή αυτή κάθε κλάση θα πρέπει να έχει μόνο μία, καλά ορισμένη και διαχωρισμένη από το υπόλοιπο πρόγραμμα αρμοδιότητα, η ύπαρξη της οποίας να εξυπηρετεί έναν συγκεκριμένο σκοπό. Αν μπορούμε να εντοπίσουμε σε μία κλάση Α δύο διαφορετικές αρμοδιότητες, τότε η καλύτερη λύση είναι η διάσπαση της σε δύο κλάσεις Β' και Γ', καθεμία από τις οποίες θα λάβει ένα υποσύνολο των πεδίων και των μεθόδων της Α. Τα υποσύνολα αυτά θα είναι ξένα μεταξύ τους, οπότε με το ανάποδο σκεπτικό αν μπορούμε να διασπάσουμε μία κλάση Α σε δύο άλλες κλάσεις (π.χ. σε περίπτωση που κάποιες μέθοδοι δε χρησιμοποιούν κάποια γνωρίσματα, οπότε οι μεν μπορούν να καταλήξουν στη μία κλάση Β' και τα πεδία στην άλλη κλάση Γ') τότε πιθανώς η κλάση να παραβιάζει την αρχή μοναδικής αρμοδιότητας. Έτσι έχουν προταθεί κάποιες μετρικές οι οποίες επιχειρούν να προσδιορίσουν την έλλειψη συνοχής (cohesion) σε μία κλάση, δηλαδή το κατά πόσον οι μέθοδοι της δε σχετίζονται με τα γνωρίσματα της. Συνήθως η συνοχή αντιπαραβάλλεται με τη σύζευξη (coupling), δηλαδή το βαθμό στον οποίον μία κλάση εξαρτάται από κάποια/ες άλλη/ες, και τα δύο αυτά μεγέθη είναι αντιστρόφως ανάλογα.

Μετρικές ποιότητας

Κατά καιρούς έχουν οριστεί κάποιες μετρικές για την εκτίμηση της περιπλοκότητας και της ποιότητας μίας αντικειμενοστρεφούς σχεδίασης λογισμικού. Σε αυτές συμπεριλαμβάνονται και οι μετρικές έλλειψης συνοχής (LCOM). Ακολουθεί μία σύνοψη των σπουδαιότερων:

Weighted Methods per Class (WMC)

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

Depth of Inheritance Tree (DIT)

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

Number of Children (NOC)

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

Coupling Between Object Classes (CBO)

Το πλήθος των κλάσεων από τις οποίες εξαρτάται η τρέχουσα κλάση. Κάθε τέτοια εξάρτηση μπορεί να είναι αμφίδρομη ή μονόδρομη οποιασδήποτε κατεύθυνσης. Επομένως υψηλό CBO σημαίνει υψηλή σύζευξη (coupling) και δεν είναι επιθυμητό, καθώς αποτρέπει την επαναχρησιμοποίηση κώδικα και ζημιώνει τον αρθρωτό σχεδιασμό του προγράμματος. Όσο χαμηλότερο είναι το CBO μίας κλάσης τόσο πιθανότερο είναι να μπορεί η τελευταία να επαναχρησιμοποιηθεί ως μαύρο κουτί. Υπερβολικά υψηλές θεωρούνται οι τιμές CBO > 14.

Response for a Class (RFC και RFC’)

Η μετρική αυτή ισούται με το πλήθος των μεθόδων που μπορεί να εκτελεστούν ως απάντηση στη λήψη ενός μηνύματος / συμβάντος από την τρέχουσα κλάση (έστω Α), τόσο τοπικών της μεθόδων όσο και «απομακρυσμένων» μεθόδων άλλων κλάσεων οι οποίες καλούνται άμεσα από την Α. Η μετρική RFC’ συμπεριλαμβάνει επιπλέον και τις απομακρυσμένες μεθόδους που καλούνται εμμέσως (π. χ. από άμεσα καλούμενες απομακρυσμένες μεθόδους ή, αναδρομικά, από άλλες έμμεσα καλούμενες απομακρυσμένες μεθόδους). Κάθε μέθοδος μετράται μόνο μία φορά στον υπολογισμό του RFC, ανεξαρτήτως του πόσες φορές καλείται. Υψηλή τιμή RFC υποδεικνύει υψηλές πιθανότητες σφάλματος και δυσκολία συντήρησης.

LCOM1

Μετρική έλλειψης συνοχής. Ισχύει LCOM1 = P - Q αν P > Q, διαφορετικά LCOM1 = 0. Τα P, Q υπολογίζονται με τον ακόλουθο αλγόριθμο (σε ψευδοκώδικα):

P = 0; Q = 0;
Για κάθε ζεύγος μεθόδων της κλάσης
do
{
   Αν τα σύνολα των πεδίων που χρησιμοποιούν οι δύο τρέχουσες μέθοδοι είναι ξένα μεταξύ τους
      P = P + 1;
   Διαφορετικά
      Q = Q + 1;
}

Μία τιμή LCOM1 = 0 υποδεικνύει συνεκτική κλάση, ενώ αν LCOM1 > 0 η κλάση καλό είναι να διασπαστεί. Η μετρική LCOM1 παρουσιάζει κάποια προβλήματα, όπως π.χ. ότι δίνει τιμή 0 για κλάσεις πολύ διαφορετικές μεταξύ τους.

LCOM2

Βελτιωμένη μετρική έλλειψης συνοχής. Ισχύει LCOM2 = 1 - sum(mA)/(m*a), όπου m το πλήθος των μεθόδων της κλάσης, a το πλήθος των πεδίων της, mA το πλήθος των μεθόδων που προσπελαύνουν ένα γνώρισμα και sum(mA) το άθροισμα των mA για όλα τα πεδία μίας κλάσης. Η μετρική LCOM2 αποτελεί τον μέσο όρο των ποσοστών των μεθόδων που δε χρησιμοποιούν κάθε γνώρισμα. LCOM2 = 0 (υψηλή συνοχή) σημαίνει πως όλες οι μέθοδοι της κλάσης χρησιμοποιούν όλα τα πεδία της, ενώ LCOM2 = 1 (καμία συνοχή) σημαίνει πως καμία μέθοδος δεν προσπελαύνει κανένα πεδίο.

LCOM3

Εναλλακτική μετρική έλλειψης συνοχής. Ισχύει LCOM3 = (m - sum(mA)/a) / (m-1). Η μετρική LCOM3 λαμβάνει τιμές από 0 (υψηλή συνοχή) έως 2 (καμία συνοχή). Τιμές μεγαλύτερες του 1 σημαίνουν πως με βεβαιότητα υπάρχει τουλάχιστον ένα "νεκρό γνώρισμα", δηλαδή γνώρισμα το οποίο δεν προσπελαύνεται από καμία μέθοδο της κλάσης.

UML

Μετά την ευρεία διάδοση του ΑΠ κατά τη δεκαετία του '90, το αντικειμενοστρεφές μοντέλο σχεδίασης (με κλάσεις, κληρονομικότητα, αντικείμενα και τυποποιημένες αλληλεπιδράσεις μεταξύ τους) επικράτησε ακόμη και για μοντελοποίηση που δεν περιελάμβανε καν προγραμματισμό (π. χ. σχήματα βάσεων δεδομένων). Έτσι αναπτύχθηκαν διάφορες πρότυπες γλώσσες μοντελοποίησης λογισμικού οι οποίες τυποποιούσαν οπτικά σύμβολα και συμπεριφορές με στόχο την αφαιρετική περιγραφή της λειτουργίας και της δομής ενός υπολογιστικού συστήματος. Οι γλώσσες αυτές είχαν εξαρχής έναν εμφανή αντικειμενοστρεφή προσανατολισμό. Τελικά οι πιο δημοφιλείς από αυτές ενοποιήθηκαν στο κοινό πρότυπο UML που η πρώτη του έκδοση οριστικοποιήθηκε το 1997.

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

Σχεδιαστικά πρότυπα

Κατά τα τέλη της δεκαετίας του '70 ένας αρχιτέκτονας ονόματι Κρίστοφερ Αλεξάντερ επιχείρησε να βρει και να καταγράψει αποδεδειγμένα ποιοτικούς σχεδιασμούς στον τομέα των κατασκευών. Έτσι μελέτησε πολλές διαφορετικές κατασκευές που εξυπηρετούσαν τον ίδιο σκοπό και προσπάθησε να ανακαλύψει κοινά στοιχεία, τα οποία κατηγοριοποίησε σε σχεδιαστικά πρότυπα (design patterns). Το 1987 η ιδέα της εύρεσης σχεδιαστικών προτύπων εφαρμόστηκε για πρώτη φορά στη μηχανική λογισμικού και μέχρι τα μέσα της δεκαετίας του '90 η εν λόγω έννοια είχε καθιερωθεί και εξαπλωθεί, στραμμένη πλέον στον κόσμο της αντικειμενοστρέφειας.

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

Δείτε επίσης

Παραπομπές

  1. Ο όρος object-oriented αποδόθηκε από τις ορολογικές ομάδες ΜΟΤΟ και ΕΛΟΤ/ΤΕ48/ΟΕ1 στα ελληνικά ως αντικειμενοστρεφής, αλλά η λέξη απαντάται στα ελληνικά και σαν «αντικειμενοστραφής».
  2. «Γιατί χρησιμοποιείτε τον όρο αντικειμενοστρεφής και όχι αντικειμενοστραφής;» από ιστοσελίδα του Διομήδη Σπινέλλη. Αρχειοθετήθηκε 13/01/2019. Ανακτήθηκε 13/01/2019.

Βιβλιογραφία και Πηγές


Read other articles:

Templat {{Expand language}} tidak disubtitusikan dengan benar.Artikel ini perlu dikembangkan dari artikel terkait di Wikipedia bahasa . ({{{date}}}) klik [tampil] untuk melihat petunjuk sebelum menerjemahkan. Jangan menerjemahkan teks yang berkualitas rendah atau tidak dapat diandalkan. Jika memungkinkan, pastikan kebenaran teks dengan referensi yang diberikan dalam artikel bahasa asing. Setelah menerjemahkan, {{Translated}} harus ditambahkan di ha...

 

 

Zoo in Massachusetts, United States Buttonwood Park ZooThe entrance to the Buttonwood Park Zoo41°37′48″N 70°57′10″W / 41.62996°N 70.95273°W / 41.62996; -70.95273Date opened1894;[1] August 12, 2000 (renovated)LocationNew Bedford, Massachusetts, United StatesNo. of animals250+[2]No. of species83[3]Annual visitors222,000[1]MembershipsAZA[4]Websitewww.bpzoo.org The Buttonwood Park Zoo, located in New Bedford, Massachusett...

 

 

American baseball player (born 1988) Baseball player Danny DuffyDuffy with the Kansas City Royals in 2011Texas Rangers – No. 24PitcherBorn: (1988-12-21) December 21, 1988 (age 35)Goleta, California, U.S.Bats: LeftThrows: LeftMLB debutMay 18, 2011, for the Kansas City RoyalsMLB statistics (through 2021 season)Win–loss record68–68Earned run average3.95Strikeouts1,048 Teams Kansas City Royals (2011–2021) Career highlights and awards World Series champion (2015) Medals...

Cet article est une ébauche concernant l'US Air Force et l’Allemagne. Vous pouvez partager vos connaissances en l’améliorant (comment ?) selon les recommandations des projets correspondants. Pour les articles homonymes, voir FEL. Base aérienne de FürstenfeldbruckFlugplatz Fürstenfeldbruck (de) Localisation Pays Allemagne Coordonnées 48° 12′ 15″ nord, 11° 15′ 03″ est Altitude 519 m (1 703 ft) Informations aéronautiques Code IATA FEL...

 

 

Roumanie au Concours Eurovision Pays  Roumanie Radiodiffuseur TVR Émission de présélection Selecția Națională Participations 1re participation Eurovision 1994 Participations 23 (en 2023) Meilleure place 3e (en 2005 et 2010) Moins bonne place 15e en demi-finale (en 2023) Liens externes Page officielle du diffuseur Page sur Eurovision.tv Pour la participation la plus récente, voir :Roumanie au Concours Eurovision de la chanson 2023 modifier  La Roumanie participe au Conco...

 

 

Primary antagonist in the Hindu epic Ramayana Several terms redirect here. For other uses, see Ravan (disambiguation). RavanaRavana, South India, 18th century ADDevanagariरावणSanskrit transliterationRāvaṇaAffiliationLanka, RakshasaPredecessorKubera (King of Lanka)SuccessorVibhishana (King of Lanka)AbodeLankaMountPushpaka VimanaTextsRamayana and its versionsPersonal informationParentsVishrava (father)Kaikasi (mother)SiblingsKumbhakarnaVibhishanaShurpanakhaSpouseMandodariDhanyamalini...

Artikel ini sebatang kara, artinya tidak ada artikel lain yang memiliki pranala balik ke halaman ini.Bantulah menambah pranala ke artikel ini dari artikel yang berhubungan atau coba peralatan pencari pranala.Tag ini diberikan pada November 2022. Gabrielle RayLahirGabrielle Elizabeth Clifford Cook28 April 1883Cheadle, Stockport, England, United KingdomMeninggal21 May 1973 (usia 90)Egham, Surrey, England, United KingdomPekerjaanActressTahun aktif1893–1912, 1915–1924 Gabrielle Ray (nee ...

 

 

Численность населения республики по данным Росстата составляет 4 003 016[1] чел. (2024). Татарстан занимает 8-е место по численности населения среди субъектов Российской Федерации[2]. Плотность населения — 59,00 чел./км² (2024). Городское население — 76,72[3] % (20...

 

 

Untuk orang lain dengan nama yang sama, lihat Tom Friedman (disambiguasi). Thomas FriedmanLahirThomas Loren Friedman20 Juli 1953 (umur 70)St. Louis Park, Minnesota, A.S.Tempat tinggalBethesda, MarylandAlmamaterUniversitas MinnesotaUniversitas BrandeisSt Antony's College, OxfordPekerjaanPengarang, kolumnisSuami/istriAnn BucksbaumAnakOrly dan NatalieSitus webThomasLFriedman.com Thomas Loren Friedman (lahir 20 Juli 1953) adalah jurnalis, kolumnis, dan pengarang Amerika Serikat. Ia menulis k...

2000 video gameChallenge ProMode ArenaOfficial logoDeveloper(s)CPMA team The Promode TeamDesigner(s)ConceptRichard Hoony Sandlant Gameplay design leads Andrew revelation Wise Richard Swelt Jacques Adam ix Sibson Programming – CPMA lead Kevin arQon Blenkinsopp Programming – CPM Jens Khaile Bergensten Bartlomiej HighlandeR Rychtarski Andrew D!ABLO Ryder Art / modeling lead Christopher 4nT1 CombeEngineid Tech 3 (Quake III Arena)Platform(s)Macintosh, PC (Linux/Windows)Releasebeta 3 / March...

 

 

Chronologies Données clés 1854 1855 1856  1857  1858 1859 1860Décennies :1820 1830 1840  1850  1860 1870 1880Siècles :XVIIe XVIIIe  XIXe  XXe XXIeMillénaires :-Ier Ier  IIe  IIIe Chronologies géographiques Afrique Afrique du Sud, Algérie, Angola, Bénin, Botswana, Burkina Faso, Burundi, Cameroun, Cap-Vert, République centrafricaine, Comores, République du Congo, République démocratique du Congo, Côte d'Ivoire, Djibouti, Égyp...

 

 

Artikel ini sebatang kara, artinya tidak ada artikel lain yang memiliki pranala balik ke halaman ini.Bantulah menambah pranala ke artikel ini dari artikel yang berhubungan atau coba peralatan pencari pranala.Tag ini diberikan pada November 2022. Aida Hadžialić Menteri Sekolah Menengah Keatas, Pendidikan Dewasa dan PelatihanMasa jabatan3 Oktober 2014 – 15 Agustus 2016Penguasa monarkiCarl XVI GustafPerdana MenteriStefan LöfvenPendahuluPosisi baruPenggantiAnna Ekström Informasi pr...

NGC 2694   الكوكبة الدب الأكبر[1]  رمز الفهرس NGC 2694 (الفهرس العام الجديد)MCG+09-15-056 (فهرس المجرات الموروفولوجي)PGC 25143 (فهرس المجرات الرئيسية)2MASX J08565924+5119544 (Two Micron All-Sky Survey, Extended source catalogue)Z 264-34 (فهرس المجرات وعناقيد المجرات)SDSS J085659.25+511955.0 (مسح سلون الرقمي للسماء)Z 0853.3+5132 (فهرس المج�...

 

 

2007 European Athletics U23 ChampionshipsTrack events100 mmenwomen200 mmenwomen400 mmenwomen800 mmenwomen1500 mmenwomen5000 mmenwomen10,000 mmenwomen100 m hurdleswomen110 m hurdlesmen400 m hurdlesmenwomen3000 msteeplechasemenwomen4 × 100 m relaymenwomen4 × 400 m relaymenwomenRoad events20 km walkmenwomenField eventsHigh jumpmenwomenPole vaultmenwomenLong jumpmenwomenTriple jumpmenwomenShot putmenwomenDiscus throwmenwomenHammer throwmenwomenJavelin throwmenwomenCombined eventsHeptathlonwome...

 

 

This template does not require a rating on Wikipedia's content assessment scale.It is of interest to the following WikiProjects:Ethnic groups This template is within the scope of WikiProject Ethnic groups, a collaborative effort to improve the coverage of articles relating to ethnic groups, nationalities, and other cultural identities on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.Ethnic groupsWikip...

Ernie KovacsKovacs pada set acara televisinya, 1956Nama lahirErnest Edward KovacsLahir(1919-01-23)23 Januari 1919Trenton, New Jersey, Amerika SerikatMeninggal13 Januari 1962(1962-01-13) (umur 42)Los Angeles, California, Amerika SerikatDimakamkanForest Lawn Memorial Park (Hollywood Hills)MediaSurat kabar, radio, televisi, majalah, sinemaTahun aktif1941–1962Suami/istriBette Lee Wilcox ​ ​(m. 1945; bercerai 1952)​ Edie Adams ​ R...

 

 

Devadatta Nama dalam bahasa asli(sa) देवदत्त(pi) 𑀤𑁂𑀯𑀤𑀢𑁆𑀢(zh-hant) 提婆達多(zh-hans) 提婆达多(ja) 提婆達多(th) เทวทัต(vi) Đề-bà-đạt-đa(km) ទេវទត្ត(lo) ເທວະທັດ(si) දේවදත්ත(my) ဒေဝဒတ်(ko) 제바달다 BiografiKelahiran6 abad SM Kematiank. 490 SM Data pribadiAgamaBuddhisme KegiatanPekerjaanBhiksu KeluargaKeluargaKeluarga Siddhartha Gautama AyahŚuklodana (en) dan Amritodan...

 

 

Sequence of edges which join a sequence of nodes on a given graph For the family of graphs known as paths, see Path graph. A three-dimensional hypercube graph showing a Hamiltonian path in red, and a longest induced path in bold black In graph theory, a path in a graph is a finite or infinite sequence of edges which joins a sequence of vertices which, by most definitions, are all distinct (and since the vertices are distinct, so are the edges). A directed path (sometimes called dipath[1&#...

1750 treaty between Spain and Portugal This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these messages) This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Treaty of Madrid 13 January 1750 – news · newspapers · books · scholar ·...

 

 

British Sugar plcJenisAnak perusahaanIndustriPemrosesan bit gulaBudidaya cannabisDidirikan1936Kantor pusatPeterborough, Inggris, Britania RayaCabang5Wilayah operasiUnited KingdomTokoh kunciPaul Kenward (direktur utama)ProdukGulaCannabisBioetanolPakanTopsoilPembenah tanahIndukAssociated British FoodsSitus webbritishsugar.co.uk British Sugar plc adalah anak usaha dari Associated British Foods yang merupakan satu-satunya produsen gula dari bit gula di Britania Raya. Perusahaan ini juga memproduk...