SOLID και το Dependency Inversion Principle

 Τι είναι το SOLID στον προγραμματισμό

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

Single Responsibility Principle - SRP:

Μια κλάση θα πρέπει να έχει μόνο ένα λόγο για να αλλάξει. Αυτό σημαίνει ότι μια κλάση θα πρέπει να είναι υπεύθυνη μόνο για ένα συγκεκριμένο καθήκον.

Open/Closed Principle - OCP:

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

Liskov Substitution Principle - LSP:

Λέει ότι ένα αντικείμενο του υποτύπου (subclass) θα πρέπει να μπορεί να χρησιμοποιηθεί αντί του αντικειμένου της υπερκλάσης (superclass) χωρίς να επηρεαστεί η σωστή λειτουργία του προγράμματος.

Interface Segregation Principle - ISP:

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

Dependency Inversion Principle - DIP:

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

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


Το Dependency Inversion Principle

Το Depencency Inversion λέει δύο πράγματα. Τα High-level modules δεν πρέπει να εξαρτώνται από τα Low-level modules. Αντίθετα, και τα δύο θα πρέπει να εξαρτώνται σε abstractions. Τα abstractions ΔΕΝ πρέπει να εξαρτώνται από  λεπτομέρειες. Αυτό με απλά λόγια σημαίνει πως όλα θα πρέπει να τα dependancies να σε κάθε κλάση να είναι interfaces και όχι implementations.

Πάμε να δούμε ένα παράδειγμα που παραβαίνει την αρχή του dependency inversion.


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


Με αυτό το τρόπο η κλάση LightSwitch δεν έχει εξάρτηση από κάποια συγκεκριμένη υλοποίηση αλλά σε ένα γενικότερο blueprint το οποίο μπορεί να έχει οποιαδήποτε υλοποίηση την οποία θα μπορούσαμε να επιλέξουμε στο runtime της εφαρμογής.