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

Εισαγωγή στα σχέδια σχεδιασμού, Μέρος 1: Ιστορικό και ταξινόμηση προτύπων σχεδίασης

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

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

Τι είναι ένα σχέδιο σχεδίασης;

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

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

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

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

  1. ΕΝΑ όνομα που περιγράφει το σχέδιο σχεδίασης και μας δίνει ένα λεξιλόγιο για να το συζητήσουμε
  2. ΕΝΑ πρόβλημα που προσδιορίζει το πρόβλημα σχεδιασμού που πρέπει να λυθεί μαζί με το πλαίσιο στο οποίο παρουσιάζεται το πρόβλημα
  3. ΕΝΑ λύση στο πρόβλημα, το οποίο (σε ένα πλαίσιο σχεδιασμού λογισμικού) θα πρέπει να προσδιορίσει τις τάξεις και τα αντικείμενα που συμβάλλουν στο σχεδιασμό μαζί με τις σχέσεις τους και άλλους παράγοντες
  4. Μια εξήγηση του συνέπειες της χρήσης του σχεδιαστικού μοτίβου

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

Αξιολόγηση ενός σχεδιαστικού μοτίβου

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

Έχοντας το σκεφτεί αυτό, καταλαβαίνουμε το πρόβλημα που προσπαθούμε να λύσουμε και τη λύση που προσφέρει το πρότυπο Composite. Αλλά ποιες είναι οι συνέπειες από τη χρήση αυτού του προτύπου;

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

Τι συμβαίνει με τους ελέγχους τύπου χρόνου εκτέλεσης;

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

Είναι επίσης δυνατό να επιλέξετε ένα κατάλληλο σχέδιο σχεδίασης και να το χρησιμοποιήσετε εσφαλμένα. ο Κλείδωμα με διπλό έλεγχο το μοτίβο είναι ένα κλασικό παράδειγμα. Το κλείδωμα με διπλό έλεγχο μειώνει τα γενικά έξοδα απόκτησης κλειδαριών δοκιμάζοντας πρώτα ένα κριτήριο κλειδώματος χωρίς να αποκτήσει πραγματικά την κλειδαριά και, στη συνέχεια, αποκτώντας την κλειδαριά μόνο εάν ο έλεγχος υποδεικνύει ότι απαιτείται κλείδωμα. Ενώ φαινόταν καλό σε χαρτί, το κλείδωμα με διπλό έλεγχο στο JDK 1.4 είχε κάποιες κρυφές πολυπλοκότητες. Όταν το JDK 5 επέκτεινε τη σημασιολογία του πτητικός λέξη-κλειδί, οι προγραμματιστές μπόρεσαν τελικά να αποκομίσουν τα οφέλη από το μοτίβο κλειδώματος διπλού ελέγχου.

Περισσότερα σχετικά με το διπλό έλεγχο κλειδώματος

Βλέπε "Κλείδωμα με διπλό έλεγχο: Έξυπνο, αλλά σπασμένο" και "Μπορεί να επιδιορθωθεί το διπλό έλεγχο κλειδώματος;" (Brian Goetz, JavaWorld) για να μάθετε περισσότερα σχετικά με το γιατί αυτό το μοτίβο δεν λειτούργησε στο JDK 1.4 και νωρίτερα. Για περισσότερες πληροφορίες σχετικά με τον καθορισμό DCL στο JDK 5 και μεταγενέστερες εκδόσεις, ανατρέξτε στην ενότητα "Η δήλωση« Το διπλό έλεγχο κλειδώματος είναι σπασμένη »(Πανεπιστήμιο του Μέριλαντ Τμήμα Επιστήμης Υπολογιστών, David Bacon, et al.).

Αντι-μοτίβα

Όταν ένα σχέδιο σχεδίασης χρησιμοποιείται συνήθως αλλά δεν είναι αποτελεσματικό και / ή αντιπαραγωγικό, το σχέδιο σχεδίασης είναι γνωστό ως αντι-μοτίβο. Κάποιος μπορεί να υποστηρίξει ότι το διπλό ελεγχόμενο κλείδωμα όπως χρησιμοποιείται στο JDK 1.4 και νωρίτερα ήταν αντι-μοτίβο. Θα έλεγα ότι ήταν απλώς μια κακή ιδέα σε αυτό το πλαίσιο. Για μια κακή ιδέα να εξελιχθεί σε αντι-μοτίβο, πρέπει να πληρούνται οι ακόλουθες προϋποθέσεις (βλ. Πόροι).

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

Ενώ το διπλό ελεγχόμενο κλείδωμα στο JDK 1.4 πληρούσε την πρώτη απαίτηση ενός anti-pattern, δεν πληρούσε το δεύτερο: αν και θα μπορούσατε να χρησιμοποιήσετε συγχρονισμένος για την επίλυση του προβλήματος της τεμπέλης αρχικοποίησης σε ένα περιβάλλον πολλαπλών νημάτων, κάτι τέτοιο θα είχε χάσει τον λόγο για τη χρήση διπλού ελέγχου κλειδώματος.

Αντι-μοτίβα αδιεξόδου

Η αναγνώριση αντι-μοτίβων αποτελεί προϋπόθεση για την αποφυγή τους. Διαβάστε τη σειρά τριών μερών του Obi Ezechukwu για μια εισαγωγή σε τρία αντι-μοτίβα που φημίζονται για το αδιέξοδο:

  • Χωρίς διαιτησία
  • Συγκέντρωση εργαζομένων
  • Αυξητικό κλείδωμα

Ιστορικό μοτίβου σχεδίασης

Τα σχέδια σχεδίασης χρονολογούνται από τα τέλη της δεκαετίας του 1970 με τη δημοσίευση του Γλώσσα μοτίβου: Πόλεις, κτίρια, κατασκευές από τον αρχιτέκτονα Christopher Alexander και μερικούς άλλους. Αυτό το βιβλίο εισήγαγε μοτίβα σχεδιασμού σε αρχιτεκτονικό πλαίσιο, παρουσιάζοντας 253 μοτίβα που σχημάτισαν συλλογικά αυτό που οι συγγραφείς ονόμασαν α γλώσσα προτύπων.

Η ειρωνεία των σχεδιαστικών προτύπων

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

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

Εν τω μεταξύ, οι Kent Beck και Ward Cunningham είχαν αρχίσει να μελετούν μοτίβα και την εφαρμογή τους στη σχεδίαση λογισμικού. Το 1987, χρησιμοποίησαν μια σειρά προτύπων σχεδιασμού για να βοηθήσουν την Semiconductor Test Systems Group της Tektronix, η οποία αντιμετώπιζε προβλήματα με την ολοκλήρωση ενός έργου σχεδιασμού. Οι Beck και Cunningham ακολούθησαν τις συμβουλές του Αλεξάνδρου για σχεδιασμό με επίκεντρο τον χρήστη (επιτρέποντας στους εκπροσώπους των χρηστών του έργου να καθορίσουν το αποτέλεσμα του σχεδιασμού), ενώ παράλληλα τους έδωσαν κάποια σχέδια σχεδίασης για να διευκολύνουν τη δουλειά.

Ο Erich Gamma συνειδητοποίησε επίσης τη σημασία των επαναλαμβανόμενων σχεδίων σχεδίασης ενώ εργαζόταν στη διδακτορική του διατριβή. Πίστευε ότι τα σχέδια σχεδίασης θα μπορούσαν να διευκολύνουν το έργο της σύνταξης επαναχρησιμοποιήσιμου αντικειμενοστρεφούς λογισμικού και σκέφτηκε πώς να τα τεκμηριώσει και να τα επικοινωνήσει αποτελεσματικά. Πριν από το Ευρωπαϊκό Συνέδριο του 1991 για τον Αντικειμενοστρεφή Προγραμματισμό, οι Gamma και Richard Helm άρχισαν να καταγράφουν μοτίβα.

Σε ένα εργαστήριο OOPSLA που πραγματοποιήθηκε το 1991, οι Gamma και Helm ενώθηκαν από τους Ralph Johnson και John Vlissides. Αυτό Συμμορία των τεσσάρων (GoF), όπως στη συνέχεια ήταν γνωστά, συνέχισε να γράφει το δημοφιλές Σχέδια σχεδίασης: Στοιχεία επαναχρησιμοποιήσιμου αντικειμενοστραφούς λογισμικού, που τεκμηριώνει 23 σχέδια σχεδίασης σε τρεις κατηγορίες.

Η σύγχρονη εξέλιξη των σχεδιαστικών προτύπων

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

Το 1994 εγκαινιάστηκε ένας μη κερδοσκοπικός οργανισμός που εδρεύει στις ΗΠΑ, γνωστός ως Hillside Group Γλώσσες προτύπων προγραμμάτων, μια ομάδα ετήσιων συνεδρίων με στόχο την ανάπτυξη και τη βελτίωση της τέχνης των σχεδίων σχεδιασμού λογισμικού. Αυτά τα συνεχιζόμενα συνέδρια απέδωσαν πολλά παραδείγματα μοτίβων σχεδιασμού για συγκεκριμένο τομέα. Για παράδειγμα, τα σχέδια σχεδίασης σε ένα πλαίσιο ταυτόχρονης ταυτότητας.

Christopher Alexander στην OOPSLA

Η κεντρική ομιλία του OOPSLA 96 παραδόθηκε από τον αρχιτέκτονα Christopher Alexander. Ο Αλέξανδρος σκέφτηκε το έργο του και τον τρόπο με τον οποίο η αντικειμενοστρεφής κοινότητα προγραμματισμού είχε χτυπήσει και χάσει το σημάδι στην υιοθέτηση και προσαρμογή των ιδεών του σχετικά με τις γλώσσες προτύπων στο λογισμικό. Μπορείτε να διαβάσετε ολόκληρη τη διεύθυνση του Αλεξάνδρου: "Οι ρίζες της θεωρίας των προτύπων: το μέλλον της θεωρίας και η δημιουργία ενός ζωντανού κόσμου."

Το 1998 κυκλοφόρησε ο Mark Grand Μοτίβα στην Ιάβα. Αυτό το βιβλίο περιελάμβανε μοτίβα σχεδίασης που δεν βρέθηκαν στο βιβλίο GoF, συμπεριλαμβανομένων μοτίβων ταυτότητας. Η Grand χρησιμοποίησε επίσης την Unified Modeling Language (UML) για να περιγράψει τα σχέδια σχεδίασης και τις λύσεις τους. Τα παραδείγματα του βιβλίου εκφράστηκαν και περιγράφηκαν στη γλώσσα Java.

Σχέδια σχεδιασμού λογισμικού κατά ταξινόμηση

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

Άλλοι τύποι σχεδίων σχεδίασης

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

Δημιουργικά μοτίβα

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

  • Περίληψη εργοστάσιο: Αυτό το μοτίβο παρέχει μια διεπαφή για να ενθυλακώσει μια ομάδα μεμονωμένων εργοστασίων που έχουν ένα κοινό θέμα χωρίς να καθορίσουν τις συγκεκριμένες κατηγορίες τους.
  • Οικοδόμος: Διαχωρίζει την κατασκευή ενός σύνθετου αντικειμένου από την αναπαράστασή του, επιτρέποντας στην ίδια διαδικασία κατασκευής να δημιουργεί διάφορες αναπαραστάσεις. Η αφαίρεση των βημάτων της κατασκευής αντικειμένων επιτρέπει διαφορετικές υλοποιήσεις των βημάτων για την κατασκευή διαφορετικών αναπαραστάσεων των αντικειμένων.
  • Εργοστασιακή μέθοδος: Ορίζει μια διεπαφή για τη δημιουργία ενός αντικειμένου, αλλά επιτρέπει στις υποκατηγορίες να αποφασίσουν ποια κλάση θα δημιουργήσει. Αυτό το μοτίβο επιτρέπει σε μια τάξη να αναβάλλει την κατάσταση σε υποκατηγορίες. Η έγχυση εξάρτησης είναι ένα σχετικό πρότυπο. (Δείτε πόρους.)
  • Οκνηρή προετοιμασία: Αυτό το μοτίβο μας δίνει έναν τρόπο να καθυστερήσουμε τη δημιουργία αντικειμένων, την αναζήτηση βάσης δεδομένων ή μια άλλη ακριβή διαδικασία μέχρι την πρώτη φορά που απαιτείται το αποτέλεσμα.
  • Multiton: Επεκτείνει την ιδέα του singleton για να διαχειριστεί έναν χάρτη με εμφανίσεις τάξεων ως ζεύγη κλειδιού-τιμής και παρέχει ένα παγκόσμιο σημείο πρόσβασης σε αυτά.
  • Συλλογή αντικειμένων: Διατηρήστε ένα σύνολο αρχικοποιημένων αντικειμένων έτοιμων προς χρήση, αντί να διατεθούν και να καταστραφούν κατά παραγγελία. Σκοπός είναι να αποφευχθούν οι δαπανηρές αποκτήσεις πόρων και η ανάκτηση με την ανακύκλωση αντικειμένων που δεν χρησιμοποιούνται πλέον.
  • Πρωτότυπο: Καθορίζει τα είδη αντικειμένων που θα δημιουργηθούν χρησιμοποιώντας μια πρωτότυπη παρουσία και, στη συνέχεια, δημιουργήστε νέα αντικείμενα αντιγράφοντας αυτό το πρωτότυπο. Η πρωτοτυπική παρουσία κλωνοποιείται για τη δημιουργία νέων αντικειμένων.
  • Η απόκτηση πόρων είναι η προετοιμασία: Αυτό το μοτίβο διασφαλίζει ότι οι πόροι αρχικοποιούνται αυτόματα και σωστά και ανακτώνται δεσμεύοντάς τους στη διάρκεια ζωής των κατάλληλων αντικειμένων. Οι πόροι αποκτώνται κατά την αρχικοποίηση των αντικειμένων, όταν δεν υπάρχει πιθανότητα να χρησιμοποιηθούν πριν να είναι διαθέσιμοι, και αποδεσμεύονται με την καταστροφή των ίδιων αντικειμένων, η οποία είναι εγγυημένη ότι θα πραγματοποιηθεί ακόμη και σε περίπτωση σφαλμάτων.
  • Μοναδικό χαρτί: Διασφαλίζει ότι μια τάξη έχει μόνο μία παρουσία και παρέχει ένα παγκόσμιο σημείο πρόσβασης σε αυτήν την παρουσία.
$config[zx-auto] not found$config[zx-overlay] not found