Επαναχρησιμοποίηση Κώδικα 3/3 – 3 OOP

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

Μία άλλη προσέγγιση λοιπόν είναι για να έχουμε διαθέσιμο κώδικα που έχουμε ήδη αναπτύξει σε άλλα προγράμματα είναι να χρησιμοποιήσουμε τις τεχνικές του αντικειμενοστρεφούς προγραμματισμού (OOP – Object Oriented Programming). Τα άρθρα δεν είναι για πολλές θεωρίες … θεωρούμε λοιπόν ότι ξέρετε τι είναι και πως υλοποιείται στη γλώσσα Πάϊθον και προχωρούμε, για εσάς που δεν ξέρετε ακόμα OOP, διαβάστε και επιστρέψτε δριμύτεροι, ή συνεχίστε με δική σας ευθύνη.

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

def unique(a_list):
    '''Η συνάρτηση επιστρέφει μία 
    νέα λίστα με τα μοναδικά στοιχεία της 1ης'''
    new_list = []
    for item in a_list:
        if item not in new_list:
            new_list.append(item)
    return new_list

def pop_all(item, a_list):
    '''Η Συνάρτηση διαγράφει τα στοιχεία
    item από τη λίστα a_list'''
    i = 0
    while i <= len(a_list)-1:
        if item == a_list[i]:
            a_list.pop(i)
        else:
            i += 1
    return a_list

Σκεφτόμαστε το εξής: Οι λίστες έχουν τη δική τους κλάση με ένα σωρό μεθόδους (συναρτήσεις που εκτελούν ενέργειες πάνω σε αντικείμενα) όπως reverse, sort, append, pop κ.ά. έτοιμες. Μήπως μπορούμε να προσθέσουμε και άλλες εφόσον και αυτές που υλοποιήσαμε παραπάνω έχουν παρόμοια χαρακτηριστικά ?

Το να φτιάξουμε μία νέα κλάση και να βάλουμε τις δικές μας μόνο, είναι βεβαίως βεβαίως μία λύση, στην προκειμένη όμως περίπτωση εφόσον ενεργούμε πάνω σε λίστες, θα απωλέσουμε αυτές που μας παρέχει εγγενώς η κλάση της λίστας. Γι’ αυτό λοιπόν φτιάχνουμε όχι μία νέα κλάση  αλλά υποκλάση (ή παράγωγη κλάση) που θα κληρονομήσει όλα τα χαρακτηριστικά (ιδιότητες και μεθόδους) της βασικής κλάσης (υπερκλάσης). Ας γράψουμε λοιπόν τα παρακάτω:

class MyList(list):

    def unique(self):
        '''Η μέθοδος επιστρέφει μία 
        νέα λίστα με τα μοναδικά στοιχεία της 1ης'''
        new_list = []
        for item in self:
            if item not in new_list:
                new_list.append(item)
        return MyList(new_list)

    def pop_all(self, item):
        '''Η μέθοδος διαγράφει τα στοιχεία
        item από το αντικείμενο'''
        i = 0
        while i <= len(self)-1:
            if item == self[i]:
                self.pop(i)
            else:
                i += 1
        return self
      

if __name__ == '__main__':
    pass

και ας εκτελέσουμε από τη γραμμή του διερμηνέα τις παρακάτω εντολές:

>>> x = [1,2,3,4,5,4,3,2,1]
>>> y = MyList(x)
>>> type(x) <type 'list'>
>>> type(y) <class '__main__.MyList'>

δημιουργήσαμε δύο αντικείμενα το x & y στιγμιότυπα των κλάσεων list & MyList αντίστοιχα.

Εκτελούμε τώρα τις εντολές:

>>> y.pop_all(2)
[1, 3, 4, 5, 4, 3, 1]
>>> y
[1, 3, 4, 5, 4, 3, 1]
>>> type(y)
<class '__main__.MyList'>

η «μαϊλίστα» y διαθέτει τη μέθοδο pop_all.

Εκτελούμε επίσης τις εντολές:

>>> z = y.unique()
>>> type(y)
<class '__main__.MyList'>
>>> type(z)
<class '__main__.MyList'>
>>> print z
[1, 3, 4, 5]

καθώς και τη μέθοδο unique. Προσέξτε τώρα το εξής: η μέθοδος pop_all τροποποιεί την αρχική λίστα, ενώ η μέθοδος unique επιστρέφει μία νέα «μαϊλίστα» αφήνοντας ανέπαφη την αρχική. Το βλέπουμε ξανά παρακάτω:

>>> x = [1,2,3,4,5,4,3,2,1]
>>> y = MyList(x)
>>> z = y.unique()
>>> y
[1, 2, 3, 4, 5, 4, 3, 2, 1]
>>> z
[1, 2, 3, 4, 5]
>>> type(y)
<class '__main__.MyList'>
>>> type(z)
<class '__main__.MyList'>

Εκτελούμε τώρα τις εντολές:

>>> z.reverse()
>>> z
[5, 4, 3, 1]
>>> z.sort()
>>> z
[1, 3, 4, 5]
>>> x.unique()

Traceback (most recent call last):
 File "<pyshell#20>", line 1, in <module>
 x.unique()
AttributeError: 'list' object has no attribute 'unique'

Το νέο αντικείμενο «μαϊλίστας» z διαθέτει όλες τις μεθόδους αφού τις έχει κληρονομήσει από την αρχική κλάση της λίστας. Ενώ το αντικείμενο x που είναι μία απλή λίστα δε διαθέτει τις νέες μεθόδους pop_all & unique. Έτσι εάν επιθυμούμε να έχουμε διαθέσιμο τον κωδικά μας ενθυλακώνοντας τις συναρτήσεις μας σε κλάσεις μπορούμε να έχουμε ένα ισχυρό και επεκτάσιμο σχεδιασμό στην υλοποίηση των εφαρμογών μας.

Χμμ αυτά λοιπόν για σήμερα ….

Η μίνα σειρά επαναχρησιμοποίησης κώδικα έλαβε τέλος. Ελπίζω να τη βρήκατε χρήσιμη. Εάν πάλι χαθήκατε στις πολλές πληροφορίες, δοκιμάστε κάτι διαφορετικό:

Αποτέλεσμα εικόνας για lost

Δημοσιεύθηκε στην Προγραμματισμός. Αποθηκεύστε τον μόνιμο σύνδεσμο.

Αφήστε μια απάντηση