Όλα όσα πρέπει να ξέρετε για τις στερεές αρχές στην Java

Σε αυτό το άρθρο θα μάθετε λεπτομερώς για το τι είναι οι στερεές αρχές στην Ιάβα με παραδείγματα και τη σημασία τους με το πραγματικό παράδειγμα.

Στον κόσμο του (OOP), υπάρχουν πολλές οδηγίες σχεδιασμού, πρότυπα ή αρχές. Πέντε από αυτές τις αρχές συνήθως ομαδοποιούνται και είναι γνωστές με το αρκτικόλεξο SOLID. Ενώ καθεμία από αυτές τις πέντε αρχές περιγράφει κάτι συγκεκριμένο, επικαλύπτονται επίσης έτσι ώστε η υιοθέτηση μιας από αυτές συνεπάγεται ή οδηγεί στην υιοθέτηση άλλης. Σε αυτό το άρθρο θα κατανοήσουμε τις SOLID αρχές στην Java.



Ιστορία των αρχών SOLID στην Ιάβα

Ο Robert C. Martin έδωσε πέντε αντικειμενοστρεφείς αρχές σχεδίασης και το ακρωνύμιο 'S.O.L.I.D' χρησιμοποιείται για αυτό. Όταν χρησιμοποιείτε όλες τις αρχές του S.O.L.I.D σε συνδυασμό, γίνεται ευκολότερο για εσάς να αναπτύξετε λογισμικό που μπορεί να διαχειριστεί εύκολα. Τα άλλα χαρακτηριστικά της χρήσης του S.O.L.I.D είναι:



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

Όταν χρησιμοποιείτε την αρχή του S.O.L.I.D στην κωδικοποίησή σας, αρχίζετε να γράφετε τον κώδικα που είναι και αποδοτικός και αποτελεσματικός.



Ποια είναι η έννοια του S.O.L.I.D;

Το Solid αντιπροσωπεύει πέντε αρχές της java που είναι:

  • μικρό : Αρχή της ενιαίας ευθύνης
  • Ή : Ανοιχτή αρχή
  • μεγάλο : Αρχή υποκατάστασης Liskov
  • Εγώ : Αρχή διαχωρισμού διεπαφής
  • ρε : Αρχή αντιστροφής εξάρτησης

Σε αυτό το blog, θα συζητήσουμε λεπτομερώς και τις πέντε αρχές SOLID της Java.



Αρχή της ενιαίας ευθύνης στην Java

Τι λέει?

Ο Robert C. Martin το περιγράφει ότι μια τάξη πρέπει να έχει μόνο μία και μόνο ευθύνη.

talend open studio για φροντιστήριο ενοποίησης δεδομένων

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

Η αρχή μπορεί να γίνει κατανοητή με ένα παράδειγμα. Φανταστείτε ότι υπάρχει μια τάξη που εκτελεί τις ακόλουθες λειτουργίες.

  • Συνδέθηκε σε μια βάση δεδομένων

  • Διαβάστε ορισμένα δεδομένα από πίνακες βάσης δεδομένων

  • Τέλος, γράψτε το σε ένα αρχείο.

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

Για παράδειγμα, μια κατηγορία αυτοκινήτου μπορεί να ξεκινήσει ή να σταματήσει, αλλά το καθήκον της πλύσης ανήκει στην κατηγορία CarWash. Σε ένα άλλο παράδειγμα, μια κλάση βιβλίων έχει ιδιότητες για να αποθηκεύσει το δικό της όνομα και κείμενο. Αλλά η εργασία εκτύπωσης του βιβλίου πρέπει να ανήκει στην κατηγορία Εκτυπωτής βιβλίων. Η κλάση εκτυπωτή βιβλίων ενδέχεται να εκτυπωθεί στην κονσόλα ή σε άλλο μέσο, ​​αλλά τέτοιες εξαρτήσεις καταργούνται από την κατηγορία βιβλίων

Γιατί απαιτείται αυτή η Αρχή;

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

Ένα παράδειγμα για την αποσαφήνιση αυτής της αρχής:

Ας υποθέσουμε ότι σας ζητείται να εφαρμόσετε μια υπηρεσία UserSetting όπου ο χρήστης μπορεί να αλλάξει τις ρυθμίσεις, αλλά πριν από αυτό ο χρήστης πρέπει να γίνει έλεγχος ταυτότητας. Ένας τρόπος για να εφαρμοστεί αυτό θα ήταν:

δημόσια τάξη UserSettingService {public void changeEmail (User user) {if (checkAccess (user)) {// Χορήγηση επιλογής για αλλαγή}} public boolean checkAccess (User user) {// Επαληθεύστε εάν ο χρήστης είναι έγκυρος. }}

Όλα φαίνονται καλά έως ότου θέλετε να χρησιμοποιήσετε ξανά τον κωδικό checkAccess σε κάποιο άλλο μέρος Ή εάν θέλετε να κάνετε αλλαγές στον τρόπο με τον οποίο το checkAccess γίνεται. Και στις 2 περιπτώσεις θα καταλήγατε να αλλάζετε την ίδια τάξη και στην πρώτη περίπτωση θα πρέπει να χρησιμοποιήσετε το UserSettingService για να ελέγξετε και την πρόσβαση.
Ένας τρόπος για να το διορθώσετε είναι να αποσυνθέσετε το UserSettingService σε UserSettingService και SecurityService. Και μετακινήστε τον κωδικό checkAccess στο SecurityService.

δημόσια τάξη UserSettingService {public void changeEmail (User user) {if (SecurityService.checkAccess (user)) {// Χορήγηση επιλογής για αλλαγή}}} δημόσια κλάση SecurityService {δημόσια στατική boolean checkAccess (χρήστης χρήστη) {// ελέγξτε την πρόσβαση. }}

Άνοιγμα κλειστής αρχής στην Java

Ο Robert C. Martin το περιγράφει ότι τα στοιχεία λογισμικού πρέπει να είναι ανοιχτά για επέκταση, αλλά κλειστά για τροποποίηση.

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

  • Κληρονομιά από την τάξη

  • Αντικατάσταση των απαιτούμενων συμπεριφορών από την τάξη

  • Επέκταση ορισμένων συμπεριφορών της τάξης

Ένα εξαιρετικό παράδειγμα αρχής ανοιχτού κλεισίματος μπορεί να γίνει κατανοητό με τη βοήθεια των προγραμμάτων περιήγησης. Θυμάστε να εγκαταστήσατε επεκτάσεις στο πρόγραμμα περιήγησης Chrome;

Βασική λειτουργία του προγράμματος περιήγησης chrome είναι η περιήγηση σε διαφορετικούς ιστότοπους. Θέλετε να ελέγξετε τη γραμματική όταν γράφετε ένα email χρησιμοποιώντας το πρόγραμμα περιήγησης chrome; Εάν ναι, μπορείτε απλά να χρησιμοποιήσετε την επέκταση γραμματικής, σας παρέχει έλεγχο γραμματικής στο περιεχόμενο.

Αυτός ο μηχανισμός όπου προσθέτετε πράγματα για την αύξηση της λειτουργικότητας του προγράμματος περιήγησης είναι μια επέκταση. Ως εκ τούτου, το πρόγραμμα περιήγησης είναι ένα τέλειο παράδειγμα λειτουργικότητας που είναι ανοιχτό για επέκταση αλλά είναι κλειστό για τροποποίηση. Με απλά λόγια, μπορείτε να βελτιώσετε τη λειτουργικότητα προσθέτοντας / εγκαθιστώντας πρόσθετα στο πρόγραμμα περιήγησής σας, αλλά δεν μπορείτε να δημιουργήσετε κάτι νέο.

Γιατί απαιτείται αυτή η αρχή;

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

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

ορθογώνιο δημόσιας τάξης {δημόσιο διπλό μήκος δημόσιο διπλό πλάτος}

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

δημόσια τάξη AreaCalculator {public double calculRectangleArea (ορθογώνιο ορθογώνιο) {return ορθογώνιο.length * ορθογώνιο. εύρος}}

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

δημόσιος κύκλος κατηγορίας {δημόσια διπλή ακτίνα}

Στη συνέχεια τροποποιούμε το Areacalculatorτάξη για προσθήκη υπολογισμών κύκλων μέσω νέας μεθόδου calculCircleaArea ()

δημόσια τάξη AreaCalculator {public double calculRectangleArea (ορθογώνιο ορθογώνιο) {return ορθογώνιο.length * ορθογώνιο. εύρος} δημόσιο διπλό υπολογισμόCircleArea (Circle circle) {return (22/7) * circle.radius * circle.radius}}

Ωστόσο, σημειώστε ότι υπήρχαν ελαττώματα στον τρόπο που σχεδιάσαμε τη λύση μας παραπάνω.

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

Το AreaCalculator θα πρέπει να συνεχίσει να προσθέτει τη λογική υπολογισμού τους σε νεότερες μεθόδους. Δεν επεκτείνουμε πραγματικά το εύρος των σχημάτων, αλλά κάνουμε απλώς μια λύση κομμάτι γεύματος (bit-by-bit) για κάθε σχήμα που προστίθεται.

Τροποποίηση του παραπάνω σχεδιασμού για συμμόρφωση με την αρχή που ανοίγει / κλείνει:

Ας δούμε τώρα έναν πιο κομψό σχεδιασμό που επιλύει τα ελαττώματα στον παραπάνω σχεδιασμό ακολουθώντας την αρχή Open / Closed. Πρώτα απ 'όλα θα κάνουμε τον σχεδιασμό επεκτάσιμο. Για αυτό πρέπει πρώτα να ορίσουμε έναν τύπο βάσης Shape και να έχουμε Circle & Rectangle υλοποίηση διεπαφής Shape.

δημόσια διεπαφή Σχήμα {public double calculArea ()} δημόσια τάξη Rectangle υλοποιεί Σχήμα {διπλό μήκος διπλό πλάτος δημόσιο διπλό calculArea () {return length * width}} δημόσια τάξη Circle υλοποιεί Σχήμα {δημόσια διπλή ακτίνα δημόσιο διπλό calculArea () {return (22 / 7) * ακτίνα * ακτίνα}}

Υπάρχει μια βασική διεπαφή Shape. Όλα τα σχήματα υλοποιούν τώρα τη βασική διεπαφή Shape. Η διεπαφή σχήματος έχει μια αφηρημένη μέθοδο calculArea (). Τόσο ο κύκλος όσο και το ορθογώνιο παρέχουν τη δική τους παράκαμψη υλοποίησης της μεθόδου calculArea () χρησιμοποιώντας τα δικά τους χαρακτηριστικά.
Έχουμε φέρει έναν βαθμό επεκτασιμότητας, καθώς τα σχήματα είναι πλέον ένα παράδειγμα διασυνδέσεων Shape. Αυτό μας επιτρέπει να χρησιμοποιήσουμε το Shape αντί για μεμονωμένες τάξεις
Το τελευταίο σημείο που αναφέρεται παραπάνω καταναλωτής αυτών των σχημάτων. Στην περίπτωσή μας, ο καταναλωτής θα είναι η κατηγορία AreaCalculator που θα μοιάζει τώρα με αυτό.

δημόσια τάξη AreaCalculator {public double calculShapeArea (σχήμα σχήματος) {return σχήμα.calculateArea ()}}

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

Αρχή υποκατάστασης Liskov στην Ιάβα

Ο Robert C. Martin το περιγράφει ότι οι παράγωγοι τύποι πρέπει να είναι πλήρως υποκατάστατοι για τους βασικούς τους τύπους.

Η αρχή υποκατάστασης Liskov προϋποθέτει ότι το q (x) είναι ιδιοκτησία, αποδεδειγμένο για οντότητες του x που ανήκει στον τύπο T. Τώρα, σύμφωνα με αυτήν την αρχή, το q (y) θα πρέπει τώρα να είναι αποδεδειγμένο για αντικείμενα y που ανήκουν στον τύπο S και το S είναι στην πραγματικότητα ένας δευτερεύων τύπος T. Τώρα είστε μπερδεμένοι και δεν ξέρετε τι σημαίνει στην πραγματικότητα η αρχή υποκατάστασης Liskov; Ο ορισμός του μπορεί να είναι λίγο περίπλοκος, αλλά στην πραγματικότητα, είναι αρκετά εύκολο. Το μόνο πράγμα είναι ότι κάθε υποκατηγορία ή παράγωγη κλάση πρέπει να είναι υποκατάστατη από τη μητρική ή βασική τάξη.

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

Γιατί απαιτείται αυτή η αρχή;

Αυτό αποφεύγει την κατάχρηση κληρονομιάς. Μας βοηθά να συμμορφωθούμε με τη σχέση «είναι-α». Μπορούμε επίσης να πούμε ότι οι υποκατηγορίες πρέπει να πληρούν μια σύμβαση που ορίζεται από την βασική κατηγορία. Υπό αυτήν την έννοια, σχετίζεται μεΣχεδιασμός με σύμβασηπου περιγράφηκε για πρώτη φορά από τον Bertrand Meyer. Για παράδειγμα, είναι δελεαστικό να πούμε ότι ένας κύκλος είναι ένας τύπος έλλειψης, αλλά οι κύκλοι δεν έχουν δύο εστίες ή μεγάλους / δευτερεύοντες άξονες.

Το LSP εξηγείται ευρέως χρησιμοποιώντας το παράδειγμα τετραγώνου και ορθογωνίου. αν υποθέσουμε μια σχέση ISA μεταξύ τετραγώνου και ορθογωνίου. Έτσι, ονομάζουμε 'Το τετράγωνο είναι ορθογώνιο'. Ο παρακάτω κώδικας αντιπροσωπεύει τη σχέση.

δημόσια τάξη ορθογώνιο {ιδιωτικό int μήκος ιδιωτικό int εύρος public int getLength () {return length} public void setLength (int length) {this.length = length} public int getBreadth () {return width} public void setBreadth (int εύρος) { this.breadth = εύρος} δημόσιο int getArea () {return this.length * this.breadth}}

Παρακάτω είναι ο κωδικός για το Square. Σημειώστε ότι το τετράγωνο εκτείνεται ορθογώνιο.

πώς να δημιουργήσετε μια σειρά αντικειμένων
δημόσια τάξη Το τετράγωνο επεκτείνει το ορθογώνιο {public void setBreadth (int εύρος) {super.setBreadth (εύρος) super.setLength (εύρος)} δημόσιο σύνολο κενού (μήκος int) {super.setLength (μήκος) super.setBreadth (μήκος)}}

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

δημόσια κλάση LSPDemo {public void calculArea (Rectangle r) {r.setBreadth (2) r.setLength (3) assert r.getArea () == 6: printError ('area', r) assert r.getLength () == 3: printError ('length', r) assert r.getBreadth () == 2: printError ('εύρος', r)} private String printError (String errorIdentifer, Rectangle r) {return 'Μη αναμενόμενη τιμή' + errorIdentifer + ' για παράδειγμα του '+ r.getClass (). getName ()} δημόσιος στατικός κενός κενός (String [] args) {LSPDemo lsp = new LSPDemo () // Μια παρουσία του ορθογωνίου περνάει lsp.calculateArea (νέο ορθογώνιο ()) // Παρουσιάζεται μια παρουσία του τετραγώνου lsp.calculateArea (νέο τετράγωνο ())}}

Το μάθημα δείχνει την Αρχή Υποκατάστασης Liskov (LSP) Σύμφωνα με την αρχή, οι συναρτήσεις που χρησιμοποιούν αναφορές στις βασικές κλάσεις πρέπει να είναι σε θέση να χρησιμοποιούν αντικείμενα προερχόμενης κλάσης χωρίς να το γνωρίζουν.

Έτσι, στο παράδειγμα που φαίνεται παρακάτω, η συνάρτηση calculArea που χρησιμοποιεί την αναφορά του 'Rectangle' θα πρέπει να μπορεί να χρησιμοποιεί τα αντικείμενα της παραγόμενης κλάσης όπως το τετράγωνο και να πληροί την απαίτηση που θέτει ο ορισμός ορθογωνίου. Θα πρέπει να σημειωθεί ότι σύμφωνα με τον ορισμό του ορθογωνίου, τα ακόλουθα πρέπει πάντα να ισχύουν λαμβάνοντας υπόψη τα παρακάτω δεδομένα:

  1. Το μήκος πρέπει να είναι πάντα ίσο με το μήκος που περνά ως είσοδος στη μέθοδο, setLength
  2. Το πλάτος πρέπει πάντα να είναι ίσο με το πλάτος που μεταδίδεται ως είσοδος στη μέθοδο, setBreadth
  3. Η έκταση πρέπει πάντα να είναι ίση με το προϊόν του μήκους και του πλάτους

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

Η κλάση Square δεν χρειάζεται μεθόδους όπως το setBreadth ή το setLength. Η κλάση LSPDemo θα πρέπει να γνωρίζει τις λεπτομέρειες των παραγόμενων κλάσεων του ορθογωνίου (όπως το τετράγωνο) για να κωδικοποιήσει κατάλληλα για να αποφευχθεί το σφάλμα σφάλματος. Η αλλαγή στον υπάρχοντα κώδικα παραβιάζει την αρχή του κλειστού κλεισίματος.

Αρχή διαχωρισμού διεπαφής

Ο Robert C. Martin το περιγράφει ότι οι πελάτες δεν πρέπει να υποχρεωθούν να εφαρμόσουν περιττές μεθόδους που δεν θα χρησιμοποιήσουν.

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

Για παράδειγμα, μία διεπαφή καταγραφής για τη σύνταξη και ανάγνωση αρχείων καταγραφής είναι χρήσιμη για μια βάση δεδομένων, αλλά όχι για μια κονσόλα. Η ανάγνωση αρχείων καταγραφής δεν έχει νόημα για έναν καταγραφέα κονσόλας. Προχωρώντας με αυτό το άρθρο SOLID Principles in Java.

Γιατί απαιτείται αυτή η αρχή;

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

Τώρα ας δημιουργήσουμε ένα Java Interface για το εστιατόριο και να το ονομάσουμε ως RestaurantInterface.java.

δημόσια διεπαφή RestaurantInterface {public void acceptOnlineOrder () public void takeTelephoneOrder () public void payOnline () public void walkInCustomerOrder () public void payInPerson ()}

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

Ας ξεκινήσουμε εφαρμόζοντας το RestaurantInterface για διαδικτυακούς πελάτες ως OnlineClientImpl.java

δημόσια τάξη OnlineClientImpl εφαρμόζει το RestaurantInterface {public void acceptOnlineOrder () {// λογική για την πραγματοποίηση ηλεκτρονικής παραγγελίας} public void takeTelephoneOrder () {// Δεν ισχύει για ηλεκτρονική παραγγελία ρίξτε νέα UnsupportedOperationException ()} δημόσια άκυρη payOnline () {// λογική πληρωμής online} public void walkInCustomerOrder () {// Δεν ισχύει για ηλεκτρονική παραγγελία ρίξτε νέο UnsupportedOperationException ()} public void payInPerson () {// Δεν ισχύει για ηλεκτρονική παραγγελία ρίξτε νέο UnsupportedOperationException ()}}
  • Επειδή ο παραπάνω κωδικός (OnlineClientImpl.java) προορίζεται για παραγγελίες στο διαδίκτυο, ρίξτε το UnsupportedOperationException.

  • Οι διαδικτυακοί, τηλεφωνικοί και πελάτες-πελάτες χρησιμοποιούν την εφαρμογή RestaurantInterface ειδικά για καθένα από αυτούς.

  • Οι τάξεις υλοποίησης για τον πελάτη Telephonic και τον πελάτη Walk-in θα έχουν μη υποστηριζόμενες μεθόδους.

  • Δεδομένου ότι οι 5 μέθοδοι αποτελούν μέρος του RestaurantInterface, οι κλάσεις υλοποίησης πρέπει να εφαρμόσουν και τις 5 από αυτές.

  • Οι μέθοδοι που κάθε μία από τις κλάσεις υλοποίησης ρίχνει το UnsupportedOperationException. Όπως μπορείτε να δείτε ξεκάθαρα - η εφαρμογή όλων των μεθόδων είναι αναποτελεσματική.

    καλύτερο λογισμικό για προγραμματισμό java
  • Οποιαδήποτε αλλαγή σε οποιαδήποτε από τις μεθόδους του RestaurantInterface θα μεταδοθεί σε όλες τις τάξεις υλοποίησης. Η διατήρηση του κώδικα αρχίζει να γίνεται πραγματικά δυσκίνητη και τα αποτελέσματα της παλινδρόμησης των αλλαγών θα συνεχίσουν να αυξάνονται.

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

Για να ξεπεράσουμε τα προαναφερθέντα προβλήματα, εφαρμόζουμε την Αρχή Διαχωρισμού Διασύνδεσης για να αναμορφώσουμε τον παραπάνω σχεδιασμό.

  1. Διαχωρίστε τις λειτουργίες πληρωμής και τοποθέτησης παραγγελιών σε δύο ξεχωριστές λιτές διεπαφές, PaymentInterface.java και OrderInterface.java.

  2. Καθένας από τους πελάτες χρησιμοποιεί μία υλοποίηση, κάθε ένα από το PaymentInterface και το OrderInterface. Για παράδειγμα - το OnlineClient.java χρησιμοποιεί το OnlinePaymentImpl και το OnlineOrderImpl και ούτω καθεξής.

  3. Η αρχή της ενιαίας ευθύνης επισυνάπτεται τώρα ως διεπαφή πληρωμής (PaymentInterface.java) και διεπαφή παραγγελιών (OrderInterface).

  4. Η αλλαγή σε οποιαδήποτε από τις διεπαφές παραγγελίας ή πληρωμής δεν επηρεάζει την άλλη. Είναι ανεξάρτητα τώρα. Δεν θα χρειαστεί να κάνετε εικονική εφαρμογή ή να ρίξετε ένα UnsupportedOperationException, καθώς κάθε διεπαφή έχει μόνο μεθόδους που θα χρησιμοποιεί πάντα.

Μετά την εφαρμογή του ISP

Αρχή αντιστροφής εξάρτησης

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

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

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

Γιατί απαιτείται αυτή η αρχή;

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

δημόσια τάξη Μαθητής {ιδιωτική διεύθυνση Διεύθυνση δημόσιος μαθητής () {διεύθυνση = νέα διεύθυνση ()}}

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

Με αυτό, καταλήγουμε σε αυτό το SOLID Principles στην Java.

Δείτε το από την Edureka, μια αξιόπιστη διαδικτυακή εταιρεία εκμάθησης με δίκτυο περισσότερων από 250.000 ικανοποιημένων μαθητών σε όλο τον κόσμο. Το μάθημα εκπαίδευσης και πιστοποίησης Java J2EE και SOA της Edureka έχει σχεδιαστεί για φοιτητές και επαγγελματίες που θέλουν να γίνουν προγραμματιστές Java. Το μάθημα έχει σχεδιαστεί για να σας δώσει μια πρώτη αρχή στον προγραμματισμό Java και να σας εκπαιδεύσει τόσο για τις βασικές όσο και για τις προηγμένες ιδέες Java μαζί με διάφορα πλαίσια Java όπως το Hibernate & Spring.

Έχετε μια ερώτηση για εμάς; Παρακαλώ αναφέρετέ το στην ενότητα σχολίων αυτού του ιστολογίου 'SOLID Principles in Java' και θα επικοινωνήσουμε μαζί σας το συντομότερο δυνατό.