Προγραμματισμός

Εξερεύνηση της αρχής της υποκατάστασης Liskov

Ο όρος SOLID είναι ένα δημοφιλές αρκτικόλεξο που αναφέρεται σε ένα σύνολο πέντε αρχών της αρχιτεκτονικής λογισμικού. Αυτά περιλαμβάνουν: SRP (Single Responsibility), Open / Close, Liskov's Substitusi, Interface Segregation και Dependency Inversion.

Το LSP (Liskov Substitusi Principle) είναι μια θεμελιώδης αρχή του OOP και δηλώνει ότι οι παράγωγες τάξεις θα πρέπει να μπορούν να επεκτείνουν τις βασικές τους τάξεις χωρίς να αλλάζουν τη συμπεριφορά τους. Με άλλα λόγια, οι παράγωγες τάξεις πρέπει να αντικαθίστανται για τους τύπους βάσης τους, δηλαδή, μια αναφορά σε μια βασική τάξη θα πρέπει να αντικαθίσταται με μια παράγωγη τάξη χωρίς να επηρεάζεται η συμπεριφορά. Η αρχή της υποκατάστασης Liskov αντιπροσωπεύει έναν ισχυρό υποτύπο συμπεριφοράς και εισήχθη από την Barbara Liskov το έτος 1987.

Σύμφωνα με την Barbara Liskov, "Αυτό που απαιτείται εδώ είναι κάτι σαν την ακόλουθη ιδιότητα υποκατάστασης: Εάν για κάθε αντικείμενο o1 του τύπου S υπάρχει ένα αντικείμενο o2 του τύπου T έτσι ώστε για όλα τα προγράμματα P να ορίζονται με όρους T, η συμπεριφορά του P είναι αμετάβλητο όταν το o1 αντικαθιστά το o2 τότε το S είναι ένας υποτύπος του T. "

Ένα κλασικό παράδειγμα παραβίασης της αρχής αντικατάστασης του Liskov είναι το πρόβλημα ορθογωνίου - τετραγώνου. Η κατηγορία Square επεκτείνει την κατηγορία ορθογωνίου και υποθέτει ότι το πλάτος και το ύψος είναι ίσο.

Εξετάστε την ακόλουθη τάξη. Η κλάση ορθογωνίου περιέχει δύο μέλη δεδομένων - πλάτος και ύψος. Υπάρχουν επίσης τρεις ιδιότητες - Ύψος, Πλάτος και Περιοχή. Ενώ οι δύο πρώτες ιδιότητες ορίζουν το ύψος και το πλάτος του ορθογωνίου, η ιδιότητα Περιοχή έχει ένα λήπτη που επιστρέφει την περιοχή του ορθογωνίου.

 ορθογώνιο τάξης

    {

προστατευμένο int πλάτος

προστατευμένο ύψος

δημόσιο εικονικό int πλάτος

        {

παίρνω

            {

πλάτος επιστροφής

            }

σειρά

            {

πλάτος = τιμή;

            }

        }

 

δημόσιο εικονικό ύψος

        {

παίρνω

            {

ύψος επιστροφής

            }

σειρά

            {

ύψος = τιμή;

            }

        }

               

δημόσια περιοχή int

        {

παίρνω

            {

ύψος επιστροφής * πλάτος;

            }

         }    

    }

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

τάξη τετράγωνο: ορθογώνιο

    {

δημόσια παράκαμψη int Width

        {

παίρνω

            {

πλάτος επιστροφής

            }

σειρά

            {

πλάτος = τιμή;

ύψος = τιμή;

            }

        }

δημόσια παράκαμψη int Ύψος

        {

παίρνω

            {

πλάτος επιστροφής;

            }

σειρά

            {

πλάτος = τιμή;

ύψος = τιμή;

            }

        }

    }

Εξετάστε μια άλλη τάξη που ονομάζεται ObjectFactory.

 κλάση ObjectFactory

    {

δημόσιο στατικό ορθογώνιο GetRectangleInstance ()

        {

επιστροφή νέου τετραγώνου ();

        }

    }

Σημειώστε ότι οι ρυθμιστές για τις ιδιότητες Πλάτος και Ύψος στην κατηγορία Square έχουν παρακαμφθεί και τροποποιηθούν για να διασφαλιστεί ότι το ύψος και το πλάτος είναι τα ίδια. Ας δημιουργήσουμε τώρα μια παρουσία της κατηγορίας ορθογωνίου χρησιμοποιώντας και ορίστε τις ιδιότητες ύψους και πλάτους.

Rectangle s = ObjectFactory.GetRectangleInstance ();

s.Height = 9;

s. Πλάτος = 8;

Console.WriteLine (s.Area);

Το παραπάνω απόσπασμα κώδικα όταν εκτελείται θα εμφανίζει την τιμή 64 στην κονσόλα. Η αναμενόμενη τιμή είναι 72 δεδομένου ότι το πλάτος και το ύψος που αναφέρονται είναι 9 και 8 αντίστοιχα. Πρόκειται για παραβίαση της αρχής αντικατάστασης του Liskov. Αυτό συμβαίνει επειδή η κλάση Square που έχει επεκτείνει την κατηγορία ορθογωνίου έχει τροποποιήσει τη συμπεριφορά. Για να διασφαλιστεί ότι δεν παραβιάζεται η Αρχή αντικατάστασης Liskov, η κλάση Square μπορεί να επεκτείνει την κατηγορία Rectangle αλλά δεν πρέπει να τροποποιήσει τη συμπεριφορά. Η συμπεριφορά έχει αλλάξει τροποποιώντας τους ρυθμιστές και για τις ιδιότητες Width και Height. Οι τιμές του ύψους και του πλάτους είναι ίδιες εάν είναι τετράγωνο - δεν πρέπει να είναι ίδιες εάν είναι ορθογώνιο.

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

 δημόσια τάξη τετράπλευρη

    {

δημόσιο εικονικό ύψος {get; σειρά; }

δημόσιο εικονικό int Width {get; σειρά; }

δημόσια περιοχή int

        {

παίρνω

            {

Επιστροφή Ύψος * Πλάτος;

            }

        }

    } 

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

Η αρχή αντικατάστασης Liskov είναι μια επέκταση της αρχής Open Close και παραβιάζεται όταν έχετε γράψει κώδικα που ρίχνει "μη εφαρμοσμένες εξαιρέσεις" ή αποκρύβετε μεθόδους σε μια παράγωγη κλάση που έχουν επισημανθεί ως εικονικές στην βασική κλάση. Εάν ο κωδικός σας συμμορφώνεται με την Αρχή αντικατάστασης Liskov έχετε πολλά οφέλη. Αυτά περιλαμβάνουν: επαναχρησιμοποίηση κώδικα, μειωμένη σύνδεση και ευκολότερη συντήρηση.

$config[zx-auto] not found$config[zx-overlay] not found