XP μέθοδος για τη Διαχείριση Έργων Λογισμικού Ενότητα 2- XP- Απλότητα και Αυξητική Ανάπτυξη Δρ. Δημήτριος Τσέλιος Καθηγητής Εφαρμογών Τμήμα Μηχανικών Πληροφορικής Τ.Ε.- ΤΕΙ Θεσσαλίας Μεταπτυχιακό Πρόγραμμα Μηχανική Λογισμικού για Διαδικτυακές & Φορητές Εφαρμογές 1
Απλότητα και Αυξητική Σχεδίαση Ο μεγάλος στόχος του XP είναι να βοηθήσει τις ομάδες να φτιάξουν λογισμικό που θα μπορεί να επεκταθεί και εύκολα να αλλαχθεί. Οι πρακτικές και τα εργαλεία δεν αλλάζουν θεμελιωδώς (από μόνα τους) τη σχεδίαση λογισμικού. 2
Κώδικας και Σχεδίαση Συνήθως οι έμπειροι προγραμματιστές δημιουργούν πιο περίπλοκο κώδικα. Αυτό γίνεται γιατί συχνά θέλουν λύσουν όχι μόνο το σημερινό τους πρόβλημα αλλά και το αυριανό. Παίρνοντας αποφάσεις την τελευταία υπεύθυνη στιγμή αποφεύγουμε τον περίπλοκο κώδικα και αυτό είναι ένα μέσο για πετύχουμε την απλότητα. 3
Code smells και Antipatterns- Πως θα πεις ότι είσαι αρκετά έξυπνος (1) Η πολυπλοκότητα δεν προσδίδει αξία στο έργο. Οι ομάδες XP λειτουργούν επαναληπτικά παίρνοντας αποφάσεις την τελευταία υπεύθυνη στιγμή. Ένας τρόπος για να κατανοηθεί το XP και να βελτιωθεί η δουλειά είναι η αναγνώριση patterns. Υπάρχει όμως και το antipattern: ένα pattern συμπεριφοράς της ομάδας που δημιουργεί προβλήματα στο έργο. Η αναγνώριση και η απομάκρυνση των antipatterns οδηγεί στην εύρεση λύσεων που βοηθούν την απλότητα της διαχείρισης του έργου. 4
Code smells και Antipatterns- Πως θα πεις ότι είσαι αρκετά έξυπνος (2) Οι ομάδες XP ψάχνουν για Code smells και τα διορθώνουν. Ο κώδικας έχει επίσης antipatterns και η απομάκρυνση τους οδηγεί σε αφαίρεση πολυπλοκότητας από το codebase. Όταν ένα antipattern συσχετίζεται με τη δομή ή τη σχεδίαση του κώδικα τότε λέγεται code smell. Σκοπός των XP ομάδων είναι ο εντοπισμός και η απομάκρυνση των code smells. 5
Code smells και Antipatterns- Πως θα πεις ότι είσαι αρκετά έξυπνος (3) Shotgun surgery: όταν γίνεται προσπάθεια για τροποποίηση ενός κώδικα και αυτή η αλλαγή απαιτεί την τροποποίηση πολλών άλλων σχετιζόμενων τμημάτων κώδικα. Μία περίπτωση code smell είναι ο half-baked κώδικας. Αυτός δημιουργείται όταν ένας προγραμματιστής θέλει να χρησιμοποιήσει ένα object και πρέπει να αρχικοποιήσει και μια σειρά από άλλα objects με ένα συγκεκριμένο τρόπο. Μία άλλη περίπτωση είναι οι πολύ μεγάλες classes ή ο duplicated code. Στη δεύτερη περίπτωση πολλές φορές γίνονται τροποποιήσεις δεν κάποια αντίγραφα του κώδικα ενώ κάποια άλλα μένουν ανέπαφα. 6
Code smells και Antipatterns- Πως θα πεις ότι είσαι αρκετά έξυπνος (4) Πολύ μεγάλες classes και duplicated code 7
Code smells και Antipatterns- Πως θα πεις ότι είσαι αρκετά έξυπνος (5) Άλλα code smells έχουν σχέση με τη συνολική σχεδίαση του κώδικα, όπως το spaghetti code, συνώνυμο του πολύπλοκου και μπερδεμένου κώδικα. Πιο δύσκολη περίπτωση είναι το lasagna code όπου υπάρχουν και πολλά επίπεδα με leaks μεταξύ των επιπέδων. 8
Code smells και Antipatterns- Πως θα πεις ότι είσαι αρκετά έξυπνος (6) Smell codes σε σχέση με τη συνολική σχεδίαση 9
Όλα αυτά έχουν σχέση με τη δομή του κώδικα και όχι με το τι κάνει ο κώδικας (1) Το hook είναι κάτι που τοποθετείται σε μια τάξη (java class) για να χειριστεί μια μελλοντική περίπτωση. Έτσι όμως δημιουργείται μια σειρά από hooks που είναι δύσκολο στο τέλος να θυμηθεί ο προγραμματιστής για ποιο λόγο τα έφτιαξε μετά από καιρό. Μια άλλη περίπτωση είναι το edge case. Είναι μια κατάσταση που εμφανίζεται σπάνια και κάτω από συγκεκριμένο σύνολο συνθηκών. Θα πρέπει να μπει μια ξεκάθαρη γραμμή γιατί η λίστα των πιθανών edge cases είναι ανεξάντλητη. 10
Όλα αυτά έχουν σχέση με τη δομή του κώδικα και όχι με το τι κάνει ο κώδικας (2) Συχνά μια ομάδα έργου οδηγείται σε φιλονικίες για τον καθορισμό των περιπτώσεων edge cases που θα υλοποιήσει. Τα hooks και edge cases οδηγούν στο framework trap, ένα antipattern που πηγάζει από την εξυπνάδα των προγραμματιστών. Σύμφωνα με αυτό, ο developer για να λύσει ένα απλό πρόβλημα γράφει ένα μεγαλύτερο κώδικα από ότι χρειάζεται έτσι ώστε να αντιμετωπίσει μελλοντικά παρόμοια προβλήματα. 11
Όλα αυτά έχουν σχέση με τη δομή του κώδικα και όχι με το τι κάνει ο κώδικας (3) Συχνά μια ομάδα έργου οδηγείται σε φιλονικίες για τον καθορισμό των περιπτώσεων edge cases που θα υλοποιήσει. Τα hooks και edge cases οδηγούν στο framework trap, ένα antipattern που πηγάζει από την εξυπνάδα των προγραμματιστών. Σύμφωνα με αυτό, ο developer για να λύσει ένα απλό πρόβλημα γράφει ένα μεγαλύτερο κώδικα από ότι χρειάζεται έτσι ώστε να αντιμετωπίσει μελλοντικά παρόμοια προβλήματα. 12
Όλα αυτά έχουν σχέση με τη δομή του κώδικα και όχι με το τι κάνει ο κώδικας (4) «Πάντα υλοποίησε πράγματα μόνο όταν τα χρειάζεσαι πραγματικά, όχι αυτά που προβλέπεις ότι θα χρειαστείς». Ron Jeffries Ο όρος YAGNI ή «You Ain t Gonna Need It». 13
Τι γίνεται όταν ο developer πέσει στο framework trap Τι γίνεται όταν ο developer πέσει στο framework trap 14
Τι γίνεται με το reusable framework; (1) Δεν έχει νόημα κάθε έργο σας να γίνεται και framework. Άλλο πράγμα είναι το Reusable Code και άλλο το framework trap. Ποια είναι όμως η διαφορά μεταξύ μιας library και ενός framework; Η διαφορά είναι πως η βιβλιοθήκη αποτελείται από μικρά reusable components. Αν ένα component κάνει πολλές δουλειές τότε θα πρέπει να διασπαστεί. Αυτό ονομάζεται separation of concerns. 15
Τι γίνεται με το reusable framework; (2) Ένα framework είναι ο συνδυασμός πολλών μικρών reusable τμημάτων κώδικα που συνιστούν ένα πολύ μεγάλο σύστημα. Όταν χρησιμοποιείται ένα έτοιμο framework όπως το.νετ τότε πολλά μικρά τμήματα κώδικα που είναι τμήματα του.νετ προστίθενται αυτόματα στον κώδικα μας. Τα frameworks είναι πιο πολύπλοκα από τα libraries. Μερικές ομάδες θεωρούν ότι φτιάχνοντας ένα πολύπλοκο framework θα λύσουν όλα τα προβλήματα τους. 16
Τι γίνεται με το reusable framework; (3) Κτίζοντας ένα πολύπλοκο framework 17
Τι γίνεται με το reusable framework; (4) Παράδειγμα framework-oriented σκέψης είναι η δημιουργία ενός build script που θα καλύπτει όλα τα έργα. Τότε η οποιαδήποτε αλλαγή μπορεί να προκαλέσει τεράστια προβλήματα. Ο developer που προτιμά να συνδυάζει διάφορα πράγματα σε ένα μεγάλο unit από το να διαχωρίζει τον κώδικα σε πολλά μικρά units δεν είναι συμβατός με τη λογική του XP. 18
Τι γίνεται με το reusable framework; (5) Ένα framework όπου φαίνεται ότι μια καλή ιδέα σήμερα γίνεται μπελάς αύριο. 19
Τι κάνουμε τελικά; (1) Συνεπώς, τα Code Smells αυξάνουν την πολυπλοκότητα και πρέπει να απομακρύνονται. Φτιάξτε τον κώδικα και τις σχεδιαστικές αποφάσεις την Last Responsible Moment. Η ιδέα αυτή χρησιμοποιείται από τις ομάδες Scrum για να επιτύχουν την απλότητα στον σχεδιασμό του έργου. 20
Τι κάνουμε τελικά; (2) Οι ομάδες XP χρησιμοποιούν κάτι ανάλογο για να πάρουν αποφάσεις για την αρχιτεκτονική, τη σχεδίαση και τον κώδικα. Οι ομάδες XP μπορούν να το κάνουν αυτό γιατί δουλεύουν με το refactoring του κώδικα, κάτι που προσφέρεται από πολλά IDE. 21
Τι κάνουμε τελικά; (3) Οι ομάδες XP χρησιμοποιούν κάτι ανάλογο για να πάρουν αποφάσεις για την αρχιτεκτονική, τη σχεδίαση και τον κώδικα. Οι ομάδες XP μπορούν να το κάνουν αυτό γιατί δουλεύουν με το refactoring του κώδικα, κάτι που προσφέρεται από πολλά IDE. 22
Τι κάνουμε τελικά; (4) Παράδειγμα refactoring με C# Η αρχική μορφή του κώδικα 23
Τι κάνουμε τελικά; (4) Παράδειγμα refactoring με C# Η τελική μορφή του κώδικα μετά το refactoring 24
Ρυθμίζοντας το Τεχνικό Χρέος με refactoring (1) Τα σχεδιαστικά προβλήματα και τα προβλήματα κώδικα αθροίζονται με το χρόνο δημιουργώντας ένα technical debt. Κάθε ομάδα θα πρέπει να βρίσκει χρόνο για τη σταδιακή απομείωση του (πχ. με την τεχνική slack). Ο τρόπος για την απομείωση είναι ένα συνεχές refactoring. Όμως το refactoring δεν είναι μια μορφή rework που δημιουργεί τελικά bugs; Το refactoring σε συνδυασμό με τις υπόλοιπες πρακτικές αποφεύγει τη δημιουργία bugs. Χρησιμοποιείστε τη Συνεχή Ολοκλήρωση για βρεθούν σχεδιαστικά προβλήματα. 25
Ρυθμίζοντας το Τεχνικό Χρέος με Η Συνεχής Ολοκλήρωση αποκαλύπτει τα προβλήματα νωρίς refactoring (2) 26
Fail-fast σύστημα: ένα σύστημα φτιαγμένο για να αναφέρει γρήγορα τα λάθη. Όταν τα προβλήματα εντοπίζονται γρήγορα τότε ευκολότερα διορθώνονται 27
Αποφύγετε τον μονολιθικό σχεδιασμό (1) Τι είναι μονολιθικός σχεδιασμός 28
Αποφύγετε τον μονολιθικό σχεδιασμό (2) Είναι ο σχεδιασμός που οδηγεί σε μεγάλα αλληλοσυνδεόμενα units που έχουν πολλές αλληλεξαρτήσεις και δύσκολα διαχωρίζονται. Tightly coupled code: είναι ένα τυπικό unit με πολλές συνδέσεις με άλλα τμήματα του συστήματος. Στόχος είναι ο decoupled code. 29
Αυξητική Σχεδίαση και Ολιστικές Πρακτικές του XP (1) Εκτός των 10 πρακτικών που παρουσιάστηκαν σε προηγούμενη ενότητα υπάρχουν και άλλες 3 πρακτικές, οι ολιστικές πρακτικές. Λέγονται έτσι γιατί δουλεύουν μαζί και δεν διαχωρίζονται. Αυξητική Σχεδίαση: το σχέδιο γίνεται τμηματικά και αθροίζεται στη συνολική αρχιτεκτονική. Αυτή είναι η λογική σχεδιασμού των open source έργων. 30
Αυξητική Σχεδίαση και Ολιστικές Πρακτικές του XP (2) Αυξητική Σχεδίαση που οδηγεί σε πιο στιβαρό και διατηρήσιμο σύστημα 31
Αυξητική Σχεδίαση και Ολιστικές Πρακτικές του XP (3) Συχνά αυτή η πρακτική δεν εφαρμόζεται γιατί υπάρχουν εμπόδια που τίθενται από τη διοίκηση της εταιρείας για την οποία η ομάδα εργάζεται. Η διοίκηση συνήθως πιέζει για αποτελέσματα και περισσότερα features. Τότε απαιτείται η ομαδική εργασία και σε αυτό βοηθούν οι επόμενες πρακτικές. 32
Αυξητική Σχεδίαση και Ολιστικές Πρακτικές του XP (4) Energized Work: είναι η δημιουργία ενός περιβάλλοντος όπου κάθε μέλος της ομάδας έχει την ελευθερία να κάνει τη δουλειά του. Στόχος είναι η ανάπτυξη καλών συνηθειών που θα οδηγούν φυσιολογικά σε κώδικα που θα αλλάζει εύκολα. 33
Αυξητική Σχεδίαση και Ολιστικές Πρακτικές του XP (5) Η ανάπτυξη λογισμικού είναι ξεκάθαρα πνευματική άσκηση. Η λύση σε κάποιο πρόβλημα μπορεί να έλθει κάποια άσχετη στιγμή και όχι κατά τη διάρκεια του τυπικού χρόνου εργασίας. Είναι επίσης γνωστό ότι χρειάζεται χρόνος (15 με 45 λεπτά) για να έρθει σε συγκέντρωση ο developer, έτσι ώστε να είναι παραγωγικός. 34
Αυξητική Σχεδίαση και Ολιστικές Πρακτικές του XP (6) Η έλλειψη σεβασμού, οι μη ρεαλιστικές προθεσμίες και η πίεση δημιουργούν ένα unenergized περιβάλλον. Αντίθετα πρέπει να δοθεί κάποια αυτονομία στον developer. Έτσι υλοποιείται η agile αρχή του διατηρήσιμου ρυθμού. Οι υπερωρίες δεν οδηγούν τελικά στην αύξηση της παραγωγικότητας. 35
Αυξητική Σχεδίαση και Ολιστικές Πρακτικές του XP (7) Whole Team: είναι η πρακτική που βοηθά τα άτομα να γίνουν ομάδα. Όταν αντιμετωπίζουν μαζί τα προβλήματα τότε λύνουν πιο εύκολα. Οι αποφάσεις λαμβάνονται ομαδικά. Έτσι αναγνωρίζεται ότι ο καθένας μπορεί να κάνει λάθη και έτσι αποφεύγεται το CYA. 36
Αυξητική Σχεδίαση και Ολιστικές Πρακτικές του XP (8) Η σχεδίαση XP, η ομαδική εργασία και οι ολιστικές πρακτικές διαμορφώνουν ένα οικοσύστημα που δημιουργεί καινοτομία. Για να συμβεί αυτό θα πρέπει η ομάδα να αποκτήσει το ορθό mindset για το XP. Διαφορετικά οι πρακτικές θα εφαρμόζονται ως κάποια formalities που πρέπει να γίνουν. 37
Αυξητική Σχεδίαση και Ολιστικές Πρακτικές Όλες οι πρακτικές σχετίζονται μεταξύ τους και ενισχύουν η μία την άλλη του XP (9) 38
Αυξητική Σχεδίαση έναντι Σχεδίαση για Επαναχρησιμοποίηση (1) Η αλλαγή του mindset για το XP γίνεται σταδιακά και οδηγεί στην αυξητική σχεδίαση. Το Unix toolset είναι ένα τυπικό παράδειγμα αυξητικής σχεδίασης. Τα εργαλεία του Unix είναι βασισμένα στη φιλοσοφία της απλότητας. Όταν τα units αλληλεπιδρούν με απλό τρόπο τότε το σύστημα μπορεί να μεγαλώσει αυξητικά. 39
Αυξητική Σχεδίαση έναντι Σχεδίαση για Επαναχρησιμοποίηση (2) Χρησιμοποιώντας τα εργαλεία του Unix ως παράδειγμα διαπιστώνουμε ότι υπάρχουν απλοί τρόποι επικοινωνίας μεταξύ των units μέσω των pipes (<, >, ). Απλά integration tests οδηγούν σε αυτό το αποτέλεσμα. Όταν τα tests γίνονται εύκολα τότε υπάρχει εύκολα αλληλεπίδραση μεταξύ των units. Η καλή σχεδίαση προκύπτει από απλές αλληλεπιδράσεις. 40
Αυξητική Σχεδίαση έναντι Σχεδίαση για Επαναχρησιμοποίηση (3) Emergence: σύνθετη συμπεριφορά που προκύπτει από απλά συστήματα. Emergent design: η σχεδίαση που δημιουργεί σύνθετα αποτελέσματα από απλά units και απλές αλληλεπιδράσεις μεταξύ τους. Με άλλα λόγια, οι ομάδες που φτιάχνουν απλό κώδικα αποκτούν τη νοοτροπία της υιοθέτησης της αλλαγής. 41
Βιβλιογραφία Learning Agile, Andrew Stellman & Jennifer Greene, O Reilly, 2015, σελίδες 219-268 42