κράτος κράτος. Κατάσταση. Σκοπός του κρατικού προτύπου

κατάστασηείναι ένα μοτίβο συμπεριφοράς που σας επιτρέπει να αλλάζετε δυναμικά τη συμπεριφορά ενός αντικειμένου όταν αλλάζει η κατάστασή του.

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

Χαρακτηριστικά του μοτίβου σε Java

Περίπλοκο:

Δημοτικότητα:

Δυνατότητα εφαρμογής:Το μοτίβο κατάστασης χρησιμοποιείται συχνά στην Java για να μετατρέψει τις περίπλοκες μηχανές κατάστασης που είναι χτισμένες σε δηλώσεις διακόπτη σε αντικείμενα.

Παραδείγματα κατάστασης στις τυπικές βιβλιοθήκες Java:

  • javax.faces.lifecycle.LifeCycle#execute() (ελέγχεται από το FacesServlet: η συμπεριφορά εξαρτάται από την τρέχουσα φάση JSF)

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

Αναπαραγωγή ήχου

Η κύρια κατηγορία παίκτη αλλάζει τη συμπεριφορά της ανάλογα με την κατάσταση στην οποία βρίσκεται ο παίκτης.

πολιτείες

states/State.java:Κοινή διεπαφή κατάστασης

πακέτο site.state.example..state.example.ui.Player; /** * Κοινή διεπαφή για όλες τις καταστάσεις. */ δημόσια αφηρημένη κλάση State ( Player player; /** * Το περιβάλλον περνά από μόνο του στον κατασκευαστή της κατάστασης, έτσι ώστε η πολιτεία να μπορεί * να έχει πρόσβαση στα δεδομένα και τις μεθόδους της στο μέλλον εάν χρειαστεί. */ State(Player player) ( this.player = player ) public abstract String onLock();

states/LockedState.java:Κράτος "κλειδωμένο"

πακέτο site.state.example..state.example.ui.Player; /** * Οι συγκεκριμένες καταστάσεις εφαρμόζουν μεθόδους αφηρημένης κατάστασης με τον δικό τους τρόπο. */ δημόσια κλάση LockedState επεκτείνει την κατάσταση ( LockedState(Player player) ( super(player); player.setPlaying(false); ) @Override public String onLock() ( if (player.isPlaying()) ( player.changeState(new ReadyState (αναπαραγωγή) επιστροφή "Διακοπή αναπαραγωγής" ) else (επιστροφή "Κλειδωμένο..."; ) ) @Override δημόσια συμβολοσειρά onPlay() (player.changeState(new ReadyState(player)); Παράκαμψη δημόσιας συμβολοσειράς onNext() (επιστροφή "Κλειδωμένο..."; ) @Override public String onPrevious() (επιστροφή "Κλειδωμένο..."; ) )

states/ReadyState.java:Έτοιμη κατάσταση

πακέτο site.state.example..state.example.ui.Player; /** * Μπορούν επίσης να μεταφέρουν το περιβάλλον σε άλλες καταστάσεις. */ δημόσια κλάση ReadyState επεκτείνει την κατάσταση ( δημόσιο ReadyState(Player player) ( super(player); ) @Override public String onLock() ( player.changeState(new LockedState(player)); επιστροφή "Locked..."; ) @ Παράκαμψη δημόσιας συμβολοσειράς onPlay() ( String action = player.startPlayback(); player.changeState(new PlayingState(player)); return action; ) @Override public String onNext() ( return "Locked..."; ) @Override public String onPrevious() (επιστρέφει "Κλειδωμένο..."; ) )

states/PlayingState.java:Κατάσταση "παίζοντας".

πακέτο site.state.example..state.example.ui.Player; δημόσια κλάση PlayingState επεκτείνει την κατάσταση ( PlayingState(Player player) ( super(player); ) @Override public String onLock() ( player.changeState(new LockedState(player)); player.setCurrentTrackAfterStop(); επιστροφή "Διακοπή αναπαραγωγής"; ) @Override public String onPlay() ( player.changeState(new ReadyState(player)); return "Paused..."; ) @Override public String onNext() ( return player.nextTrack(); ) @Override public String onPrevious( ) ( επιστροφή player.previousTrack(); ) )

UI

ui/Player.java:Παίχτης

πακέτο site.state.example..state.example.states.state.example.states.State; εισαγωγή java.util.ArrayList; εισαγωγή java.util.List; δημόσια κλάση Παίκτης (ιδιωτική κατάσταση κατάστασης, ιδιωτικό παιχνίδι boolean = ψευδής, ιδιωτική λίστα playlist = νέα ArrayList<>() private int currentTrack = 0; public Player() ( this.state = new ReadyState(this); setPlaying(true); for (int i = 1; i<= 12; i++) { playlist.add("Track " + i); } } public void changeState(State state) { this.state = state; } public State getState() { return state; } public void setPlaying(boolean playing) { this.playing = playing; } public boolean isPlaying() { return playing; } public String startPlayback() { return "Playing " + playlist.get(currentTrack); } public String nextTrack() { currentTrack++; if (currentTrack >playlist.size() - 1) (currentTrack = 0; ) επιστροφή "Αναπαραγωγή" + playlist.get(currentTrack); ) δημόσια συμβολοσειρά previousTrack() (currentTrack--; if (currentTrack< 0) { currentTrack = playlist.size() - 1; } return "Playing " + playlist.get(currentTrack); } public void setCurrentTrackAfterStop() { this.currentTrack = 0; } }

ui/UI.java: GUI του προγράμματος αναπαραγωγής

πακέτο site.state.example.ui; εισαγωγή javax.swing.*; εισαγωγή java.awt.*; δημόσιας κλάσης διεπαφή χρήστη (ιδιωτικό πρόγραμμα αναπαραγωγής; ιδιωτικό στατικό JTextField textField = νέο JTextField(); δημόσια διεπαφή χρήστη (πρόγραμμα αναπαραγωγής) ( this.player = player; ) δημόσιο κενό init() ( JFrame frame = νέο JFrame ("Test player"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE = new context.setLayout(new frame.getContentPane(). (textField.add(buttons). "Play"); = new JButton("Next"); JButton prev = νέο JButton("Προηγούμενο"); prev.addActionListener(e -> textField.setText(player.getState().onPrevious())); frame.setVisible(true); frame.setSize(300, 100); buttons.add(play); buttons.add(stop); buttons.add(next); buttons.add(prev); ) )

Demo.java:Κωδικός πελάτη

πακέτο refactoring_guru.state..state.example.ui..state.example.ui.UI; /** * Επίδειξη κλάσης. Εδώ ενώνονται όλα. */ δημόσια κλάση Επίδειξη ( δημόσιο στατικό κενό main(String args) ( Player player = new player(); UI ui = new UI (player); ui.init(); ) ) "PatternΚατάσταση"Πηγή .ru

Κατάσταση είναι ένα μοτίβο συμπεριφοράς αντικειμένου που καθορίζει διαφορετικές λειτουργίες ανάλογα με την εσωτερική κατάσταση του αντικειμένου. αρχική πηγή ιστοσελίδας

Προϋποθέσεις, Εργασία, Σκοπός

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

Κίνητρο

Σκεφτείτε την τάξη TCPConnection, το οποίο αντιπροσωπεύει μια σύνδεση δικτύου. Ένα αντικείμενο αυτής της κλάσης μπορεί να βρίσκεται σε μία από πολλές καταστάσεις: Καθιερωμένος(εγκατεστημένο), Ακούγοντας(ακούγοντας), Κλειστό(κλειστό). Όταν ένα αντικείμενο TCPConnectionλαμβάνει αιτήματα από άλλα αντικείμενα, ανταποκρίνεται διαφορετικά ανάλογα με την τρέχουσα κατάσταση. Για παράδειγμα, η απάντηση σε ένα αίτημα Ανοιξε(ανοιχτό) εξαρτάται από το αν η σύνδεση είναι σε κατάσταση Κλειστόή Καθιερωμένος. Το πρότυπο κατάστασης περιγράφει πώς ένα αντικείμενο TCPConnectionμπορεί να συμπεριφέρεται διαφορετικά όταν βρίσκεται σε διαφορετικές καταστάσεις. source.ru

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

κατάσταση. Σε αυτές τις υποκατηγορίες TCPSstateεφαρμόζεται συμπεριφορά συγκεκριμένης κατάστασης. Για παράδειγμα, στις τάξεις Το TCPE ιδρύθηκεΚαι TCPΚλειστόεφαρμοσμένη συμπεριφορά συγκεκριμένης κατάστασης ΚαθιερωμένοςΚαι Κλειστόαντίστοιχα. αρχική πηγή ιστοσελίδας

ιστοσελίδα αρχική πηγή

Τάξη TCPConnectionαποθηκεύει ένα αντικείμενο κατάστασης (ένα στιγμιότυπο μιας υποκλάσης TCPSstate) αντιπροσωπεύει την τρέχουσα κατάσταση της σύνδεσης και αναθέτει όλα τα εξαρτώμενα από την κατάσταση αιτήματα σε αυτό το αντικείμενο. TCPConnectionχρησιμοποιεί το δικό του παράδειγμα της υποκλάσης TCPSstateπολύ απλό: μέθοδοι κλήσης μιας ενιαίας διεπαφής TCPSstate, μόνο ανάλογα με τη συγκεκριμένη υποκατηγορία που είναι αποθηκευμένη αυτήν τη στιγμή TCPSstate-α - το αποτέλεσμα είναι διαφορετικό, δηλ. Στην πραγματικότητα, εκτελούνται λειτουργίες που είναι συγκεκριμένες μόνο για αυτήν την κατάσταση σύνδεσης. Πηγή original.ru

Και κάθε φορά που αλλάζει η κατάσταση σύνδεσηςTCPConnectionαλλάζει το αντικείμενο κατάστασης του. Για παράδειγμα, όταν μια εγκατεστημένη σύνδεση είναι κλειστή, TCPConnectionαντικαθιστά ένα στιγμιότυπο μιας κλάσης Το TCPE ιδρύθηκεαντίγραφο TCPΚλειστό. ιστοσελίδα αρχική πηγή

Σημάδια εφαρμογής, χρήση του σχεδίου κατάστασης

Χρησιμοποιήστε το μοτίβο κατάστασης στις ακόλουθες περιπτώσεις: πηγή original.ru
  1. Όταν η συμπεριφορά ενός αντικειμένου εξαρτάται από την κατάστασή του και πρέπει να αλλάξει κατά το χρόνο εκτέλεσης. .ru
  2. Όταν ο κωδικός λειτουργίας περιέχει δηλώσεις υπό όρους που αποτελούνται από πολλούς κλάδους, στους οποίους η επιλογή κλάδου εξαρτάται από την κατάσταση. Τυπικά σε αυτή την περίπτωση η κατάσταση αντιπροσωπεύεται από απαριθμημένες σταθερές. Συχνά η ίδια δομή δηλώσεων υπό όρους επαναλαμβάνεται σε πολλές πράξεις. Αυτό σας επιτρέπει να αντιμετωπίζετε την κατάσταση ενός αντικειμένου ως ένα ανεξάρτητο αντικείμενο που μπορεί να αλλάξει ανεξάρτητα από άλλα. πηγή original.ru

Λύση

Πηγή ιστότοπου πρωτότυπος ιστότοπος

original.ru

Συμμετέχοντες του κρατικού προτύπου

πηγή original.ru
  1. Συμφραζόμενα(TCPConnection) - πλαίσιο.
    Καθορίζει μια ενιαία διεπαφή για πελάτες.
    Αποθηκεύει ένα στιγμιότυπο μιας υποκλάσης ConcreteState, που καθορίζει την τρέχουσα κατάσταση. original.ru
  2. κατάσταση(TCPSstate) - κατάσταση.
    Καθορίζει μια διεπαφή για την ενθυλάκωση της συμπεριφοράς που σχετίζεται με μια συγκεκριμένη κατάσταση περιβάλλοντος. πηγή original.ru
  3. Υποκατηγορίες ConcreteState(TCPEstablished, TCPListen, TCPClosed) - συγκεκριμένη κατάσταση.
    Κάθε υποκλάση υλοποιεί συμπεριφορά που σχετίζεται με κάποια κατάσταση περιβάλλοντος Συμφραζόμενα. αρχική πηγή ιστοσελίδας

Σχέδιο για τη χρήση του σχεδίου κατάστασης

Τάξη Συμφραζόμεναμεταβιβάζει αιτήματα στο τρέχον αντικείμενο ConcreteState. αρχική πηγή ιστοσελίδας

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

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

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

Ερωτήσεις σχετικά με την εφαρμογή του κρατικού προτύπου

Ερωτήσεις σχετικά με την εφαρμογή του κρατικού προτύπου: Πηγή original.ru
  1. Τι καθορίζει τις μεταβάσεις μεταξύ των κρατών.
    Το πρότυπο κατάστασης δεν λέει τίποτα για το ποιος συμμετέχων καθορίζει τις προϋποθέσεις (κριτήρια) για τη μετάβαση μεταξύ των καταστάσεων. Εάν τα κριτήρια είναι σταθερά, τότε μπορούν να εφαρμοστούν απευθείας στην τάξη Συμφραζόμενα. Ωστόσο, γενικά, μια πιο ευέλικτη και σωστή προσέγγιση είναι να επιτρέπονται οι ίδιες οι υποκλάσεις της τάξης κατάστασηκαθορίστε την επόμενη κατάσταση και στιγμή μετάβασης. Για να το κάνετε αυτό στην τάξη Συμφραζόμεναπρέπει να προσθέσουμε μια διεπαφή που επιτρέπει από αντικείμενα κατάστασηορίσει την κατάστασή του.
    Αυτή η αποκεντρωμένη λογική μετάβασης είναι πιο εύκολο να τροποποιηθεί και να επεκταθεί - απλά πρέπει να ορίσετε νέες υποκλάσεις κατάσταση. Το μειονέκτημα της αποκέντρωσης είναι ότι κάθε υποκατηγορία κατάστασηπρέπει να «γνωρίζει» τουλάχιστον μια υποκλάση μιας άλλης κατάστασης (στην οποία μπορεί πραγματικά να αλλάξει την τρέχουσα κατάσταση), η οποία εισάγει εξαρτήσεις υλοποίησης μεταξύ υποκλάσεων. source.ru

    Πηγή ιστότοπου πρωτότυπος ιστότοπος
  2. Πίνακας εναλλακτική.
    Υπάρχει ένας άλλος τρόπος για τη δομή του κώδικα που βασίζεται σε κατάσταση. Αυτή είναι η αρχή μιας μηχανής πεπερασμένης κατάστασης. Χρησιμοποιεί έναν πίνακα για να αντιστοιχίσει τις εισόδους στις μεταβάσεις καταστάσεων. Με τη βοήθειά του, μπορείτε να προσδιορίσετε σε ποια κατάσταση πρέπει να μεταβείτε όταν φτάνουν ορισμένα δεδομένα εισόδου. Ουσιαστικά, αντικαθιστούμε τον υπό όρους κωδικό με αναζήτηση πίνακα.
    Το κύριο πλεονέκτημα του μηχανήματος είναι η κανονικότητά του: για να αλλάξετε τα κριτήρια μετάβασης, αρκεί να τροποποιήσετε μόνο τα δεδομένα, όχι τον κώδικα. Υπάρχουν όμως και μειονεκτήματα:
    - η αναζήτηση ενός πίνακα είναι συχνά λιγότερο αποτελεσματική από την κλήση μιας συνάρτησης,
    - η παρουσίαση της λογικής μετάβασης σε ενιαία μορφή πίνακα καθιστά τα κριτήρια λιγότερο σαφή και, επομένως, πιο δυσνόητα,
    - είναι συνήθως δύσκολο να προστεθούν ενέργειες που συνοδεύουν τις μεταβάσεις μεταξύ των κρατών. Η μέθοδος του πίνακα λαμβάνει υπόψη τις καταστάσεις και τις μεταβάσεις μεταξύ τους, αλλά πρέπει να συμπληρωθεί έτσι ώστε να μπορούν να εκτελούνται αυθαίρετοι υπολογισμοί με κάθε αλλαγή κατάστασης.
    Η κύρια διαφορά μεταξύ των μηχανών καταστάσεων που βασίζονται σε πίνακα και της Κατάστασης Μοτίβου μπορεί να διατυπωθεί ως εξής: Η κατάσταση μοτίβου μοντελοποιεί συμπεριφορά εξαρτώμενη από την κατάσταση και η μέθοδος πίνακα εστιάζει στον ορισμό μεταβάσεων μεταξύ καταστάσεων. Πηγή original.ru

    source.ru πρωτότυπο
  3. Δημιουργία και καταστροφή κρατικών αντικειμένων.
    Κατά τη διαδικασία ανάπτυξης συνήθως πρέπει να επιλέξετε μεταξύ:
    - δημιουργία αντικειμένων κατάστασης όταν χρειάζονται και καταστροφή τους αμέσως μετά τη χρήση,
    - δημιουργώντας τα εκ των προτέρων και για πάντα.

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

    Πηγή ιστότοπου πρωτότυπος ιστότοπος
  4. Χρήση δυναμικής αλλαγής.
    Είναι δυνατό να διαφοροποιηθεί η συμπεριφορά κατ' απαίτηση αλλάζοντας την κλάση του αντικειμένου κατά το χρόνο εκτέλεσης, αλλά οι περισσότερες αντικειμενοστρεφείς γλώσσες δεν το υποστηρίζουν. Η εξαίρεση είναι η Perl, η JavaScript και άλλες γλώσσες που βασίζονται σε μηχανές δέσμης ενεργειών που παρέχουν έναν τέτοιο μηχανισμό και επομένως υποστηρίζουν άμεσα το Pattern State. Αυτό επιτρέπει στα αντικείμενα να αλλάζουν τη συμπεριφορά τους αλλάζοντας τον κωδικό κλάσης τους. source.ru πρωτότυπο

    αρχική πηγή.ru

Αποτελέσματα

Αποτελέσματα της χρήσης κατάσταση προτύπου: Πηγή original.ru
  1. Εντοπίζει τη συμπεριφορά που εξαρτάται από το κράτος.
    Και το χωρίζει σε μέρη που αντιστοιχούν σε καταστάσεις. Το πρότυπο κατάστασης τοποθετεί όλη τη συμπεριφορά που σχετίζεται με μια συγκεκριμένη κατάσταση σε ένα ξεχωριστό αντικείμενο. Επειδή ο κώδικας που εξαρτάται από την κατάσταση περιέχεται εξ ολοκλήρου σε μία από τις υποκλάσεις της κλάσης κατάσταση, τότε μπορείτε να προσθέσετε νέες καταστάσεις και μεταβάσεις απλά δημιουργώντας νέες υποκλάσεις.
    Αντίθετα, θα μπορούσε κανείς να χρησιμοποιήσει μέλη δεδομένων για να ορίσει εσωτερικές καταστάσεις και στη συνέχεια τις λειτουργίες του αντικειμένου Συμφραζόμεναθα έλεγχε αυτά τα δεδομένα. Αλλά σε αυτήν την περίπτωση, παρόμοιες εντολές υπό όρους ή εντολές διακλάδωσης θα είναι διάσπαρτες σε όλο τον κώδικα κλάσης Συμφραζόμενα. Ωστόσο, η προσθήκη μιας νέας κατάστασης θα απαιτούσε αλλαγή πολλών λειτουργιών, γεγονός που θα καθιστούσε δύσκολη τη συντήρηση. Το πρότυπο κατάστασης λύνει αυτό το πρόβλημα, αλλά δημιουργεί επίσης ένα άλλο, καθώς η συμπεριφορά για διαφορετικές καταστάσεις καταλήγει να κατανέμεται σε πολλές υποκατηγορίες κατάσταση. Αυτό αυξάνει τον αριθμό των τάξεων. Φυσικά, μια κατηγορία είναι πιο συμπαγής, αλλά αν υπάρχουν πολλές καταστάσεις, τότε μια τέτοια κατανομή είναι πιο αποτελεσματική, αφού διαφορετικά θα έπρεπε να αντιμετωπίσει δυσκίνητες προτάσεις υπό όρους.
    Το να έχετε δυσκίνητες δηλώσεις υπό όρους είναι ανεπιθύμητο, όπως και οι μακρές διαδικασίες. Είναι πολύ μονολιθικοί, γι' αυτό η τροποποίηση και η επέκταση του κώδικα γίνεται πρόβλημα. Το πρότυπο κατάστασης προσφέρει έναν καλύτερο τρόπο δομής κώδικα που εξαρτάται από την κατάσταση. Η λογική που περιγράφει τις μεταβάσεις καταστάσεων δεν είναι πλέον τυλιγμένη σε μονολιθικές δηλώσεις ανή διακόπτης, αλλά κατανέμεται μεταξύ υποκατηγοριών κατάσταση. Με την ενθυλάκωση κάθε μετάβασης και δράσης σε μια κλάση, η κατάσταση γίνεται ένα πλήρες αντικείμενο. Αυτό βελτιώνει τη δομή του κώδικα και καθιστά σαφέστερο τον σκοπό του. πηγή original.ru
  2. Καθιστά σαφείς τις μεταβάσεις μεταξύ των καταστάσεων.
    Εάν ένα αντικείμενο ορίζει την τρέχουσα κατάστασή του αποκλειστικά με βάση τα εσωτερικά δεδομένα, τότε οι μεταβάσεις μεταξύ καταστάσεων δεν έχουν ρητή αναπαράσταση. εμφανίζονται μόνο ως εκχωρήσεις σε ορισμένες μεταβλητές. Η εισαγωγή ξεχωριστών αντικειμένων για διαφορετικές καταστάσεις κάνει τις μεταβάσεις πιο σαφείς. Επιπλέον, αντικείμενα κατάστασημπορεί να προστατεύσει το πλαίσιο Συμφραζόμενααπό αναντιστοιχία εσωτερικών μεταβλητών, αφού οι μεταβάσεις από την άποψη του πλαισίου είναι ατομικές ενέργειες. Για να κάνετε τη μετάβαση, πρέπει να αλλάξετε την τιμή μόνο μιας μεταβλητής (μεταβλητή αντικειμένου κατάστασηστην τάξη Συμφραζόμενα), και όχι πολλά. Πηγή original.ru
  3. Τα αντικείμενα κατάστασης μπορούν να κοινοποιηθούν.
    Αν βρίσκεται σε κατάσταση αντικείμενο κατάστασηδεν υπάρχουν μεταβλητές παρουσίας, που σημαίνει ότι η κατάσταση που αντιπροσωπεύει κωδικοποιείται αποκλειστικά από τον ίδιο τον τύπο, τότε διαφορετικά περιβάλλοντα μπορούν να μοιράζονται το ίδιο αντικείμενο κατάσταση. Όταν τα κράτη διαχωρίζονται με αυτόν τον τρόπο, είναι ουσιαστικά καιροσκόποι (βλ. οπορτουνιστικό μοτίβο) που δεν έχουν εσωτερική κατάσταση, παρά μόνο συμπεριφορά. πηγή τοποθεσίας αρχικός ιστότοπος

Παράδειγμα

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

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

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

Πηγή original.ru

TCPConnectionαναθέτει όλα τα αιτήματα που εξαρτώνται από την κατάσταση στην παρουσία που είναι αποθηκευμένη στην κατάσταση TCPSstate. Επίσης στην τάξη TCPConnectionυπάρχει επέμβαση Αλλαγή Κατάστασης, με το οποίο μπορείτε να γράψετε έναν δείκτη σε άλλο αντικείμενο σε αυτή τη μεταβλητή TCPSstate. Κατασκευαστής τάξης TCPConnectionαρχικοποιεί κατάστασηδείκτη σε κλειστή κατάσταση TCPΚλειστό(θα το ορίσουμε παρακάτω). source.ru

πηγή τοποθεσίας αρχικός ιστότοπος

Κάθε επέμβαση TCPSstateδέχεται ένα παράδειγμα TCPConnectionως παράμετρος, επιτρέποντας έτσι το αντικείμενο TCPSstateπρόσβαση σε δεδομένα αντικειμένου TCPConnectionκαι αλλάξτε την κατάσταση σύνδεσης. .ru

Στην τάξη TCPSstateεφαρμόστηκε προεπιλεγμένη συμπεριφορά για όλα τα αιτήματα που του ανατέθηκαν. Μπορεί επίσης να αλλάξει την κατάσταση ενός αντικειμένου TCPConnectionμέσω μιας επέμβασης Αλλαγή Κατάστασης. TCPSstateβρίσκεται στην ίδια συσκευασία με TCPConnection, έτσι έχει επίσης πρόσβαση σε αυτήν τη λειτουργία: TCPState . αρχική πηγή ιστοσελίδας

source.ru

Σε υποκατηγορίες TCPSstateεξαρτώμενη από το κράτος συμπεριφορά. Μια σύνδεση TCP μπορεί να είναι σε πολλές καταστάσεις: Καθιερωμένος(εγκατεστημένο), Ακούγοντας(ακούγοντας), Κλειστό(κλειστό) κ.λπ., και το καθένα από αυτά έχει τη δική του υποκατηγορία TCPSstate. Για απλότητα, θα εξετάσουμε λεπτομερώς μόνο 3 υποκατηγορίες - Το TCPE ιδρύθηκε, TCListenΚαι TCPΚλειστό. αρχική πηγή ιστότοπου

αρχική πηγή.ru

Σε υποκατηγορίες TCPSstateεφαρμόζει συμπεριφορά που εξαρτάται από την κατάσταση για εκείνα τα αιτήματα που είναι έγκυρα σε αυτήν την κατάσταση. Πηγή original.ru

αρχική πηγή ιστότοπου

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

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

Ru πρωτότυπο

Γνωστές Εφαρμογές του Κρατικού Μοτίβου

Οι Ralph Johnson και Jonathan Zweig χαρακτηρίζουν το πρότυπο κατάστασης και το περιγράφουν σε σχέση με το πρωτόκολλο TCP.
Τα πιο δημοφιλή προγράμματα διαδραστικής σχεδίασης παρέχουν "εργαλεία" για την εκτέλεση λειτουργιών άμεσου χειρισμού. Για παράδειγμα, ένα εργαλείο σχεδίασης γραμμής επιτρέπει στο χρήστη να κάνει κλικ σε ένα αυθαίρετο σημείο με το ποντίκι και στη συνέχεια να μετακινήσει το ποντίκι για να σχεδιάσει μια γραμμή από αυτό το σημείο. Το εργαλείο επιλογής σάς επιτρέπει να επιλέξετε ορισμένα σχήματα. Συνήθως, όλα τα διαθέσιμα εργαλεία τοποθετούνται στην παλέτα. Η δουλειά του χρήστη είναι να επιλέξει και να εφαρμόσει ένα εργαλείο, αλλά στην πραγματικότητα η συμπεριφορά του επεξεργαστή ποικίλλει καθώς αλλάζει το εργαλείο: με το εργαλείο σχεδίασης δημιουργούμε σχήματα, με το εργαλείο επιλογής τα επιλέγουμε κ.λπ. Πηγή original.ru

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

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

Αυτή η τεχνική χρησιμοποιείται στα πλαίσια των προγραμμάτων επεξεργασίας γραφικών HotDraw και Unidraw. Επιτρέπει στους πελάτες να ορίζουν εύκολα νέους τύπους εργαλείων. ΣΕ HotDrawΤάξη DrawingControllerπροωθεί αιτήματα στο τρέχον αντικείμενο Εργαλείο. ΣΕ Unidrawκαλούνται οι αντίστοιχες κλάσεις ΘεατήςΚαι Εργαλείο. Το παρακάτω διάγραμμα κλάσεων παρέχει μια σχηματική αναπαράσταση των διεπαφών κλάσεων Εργαλείο

Πηγή ιστότοπου πρωτότυπος ιστότοπος

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

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

εισαγωγή

Πρόθεση: Επιτρέπει σε ένα αντικείμενο να αλλάξει τη συμπεριφορά του όταν αλλάζει η εσωτερική κατάσταση και, στη συνέχεια, το αντικείμενο φαίνεται να αλλάζει την κλάση του.

Κυρίως επίλυση: η συμπεριφορά ενός αντικειμένου εξαρτάται από την κατάστασή του (χαρακτηριστικά) και μπορείτε να το αλλάξετε ανάλογα με την κατάστασή του που σχετίζεται με την αλλαγή συμπεριφοράς.

Πότε να χρησιμοποιείται: Ο κώδικας περιέχει μεγάλο αριθμό αντικειμένων που σχετίζονται με την κατάσταση των εντολών υπό όρους.

Τρόπος διόρθωσης: η κατάσταση των συγκεκριμένων αφηρημένων τάξεων είναι εκτός.

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

Παραδείγματα εφαρμογής: 1, παίζοντας μπάσκετ, ο παίκτης μπορεί να έχει μια κανονική κατάσταση, όχι μια κανονική κατάσταση και μια ανώμαλη κατάσταση. 2, Marquise Yi Zeng κουδούνια, στη συνέχεια "ρολόι αφηρημένη διεπαφή", "ρολόι Α" και άλλες συγκεκριμένες καταστάσεις, συγκεκριμένο περιβάλλον "" κινέζικα κουδούνια (πλαίσιο).

Πλεονεκτήματα: 1, ενσωματώνει τους κανόνες μετασχηματισμού. 2, απαριθμήστε πιθανές καταστάσεις πριν απαριθμήσετε το κράτος πρέπει να καθορίσει την κατάσταση του είδους. 3, τα πάντα με συμπεριφορά κατάστασης συνδέονται σε μια κλάση, και μπορείτε εύκολα να προσθέσετε μια νέα κατάσταση, χρειάζεται μόνο να αλλάξετε την κατάσταση ενός αντικειμένου μπορεί να αλλάξει τη συμπεριφορά των αντικειμένων. 4, το οποίο καθιστά δυνατή την πραγματοποίηση μιας μετάβασης κατάστασης - τη λογική κατάσταση ενός αντικειμένου σε ένα, αντί για ένα τεράστιο μπλοκ δηλώσεων υπό όρους. 5, επιτρέπει σε πολλά αντικείμενα να μοιράζονται το περιβάλλον κατάστασης ενός αντικειμένου, μειώνοντας έτσι τον αριθμό των αντικειμένων στο σύστημα.

Μειονεκτήματα: 1, Το μοτίβο κατάστασης χρήσης σχετίζεται με αύξηση του αριθμού των κλάσεων συστήματος και των αντικειμένων. 2, η δομή και η υλοποίηση της φόρμας κατάστασης είναι πιο περίπλοκη, εάν χρησιμοποιηθεί εσφαλμένα, μπορεί να προκαλέσει σύγχυση στη δομή και τον κώδικα του προγράμματος. 3, η υποστήριξη για το μοντέλο κατάστασης "Open Closed Principle" δεν είναι πολύ καλή, μπορείτε να αλλάξετε την κατάσταση του μοντέλου κατάστασης προσθέτοντας νέες κλάσεις, πρέπει να αλλάξετε την κατάσταση εκείνων που είναι υπεύθυνοι για τις μεταβάσεις κατάστασης πηγαίου κώδικα ή δεν μπορείτε να μεταβείτε σε μια νέα κατάσταση, και να αλλάξετε την κατάσταση της κλάσης για να ενεργήσει επίσης, είναι απαραίτητο να τροποποιήσετε τον πηγαίο κώδικα της αντίστοιχης κλάσης.

Περιπτώσεις χρήσης: 1, με αλλαγή κατάστασης και συμπεριφορά αλλαγής σκηνής. 2, βεβαίωση μετάβασης υπό όρους με αντικατάσταση.

Σημείωση: Όταν χρησιμοποιείτε συμπεριφορά περιορισμένης κατάστασης ανά κατάσταση κατάστασης και η κατάσταση δεν είναι μεγαλύτερη από πέντε.

εκτέλεση

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

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

Βήμα 1

Δημιουργήστε μια διεπαφή.

Πολιτεία.java

Κατάσταση δημόσιας διεπαφής ( public void doAction (Context context); )

Βήμα 2

Δημιουργήστε μια κλάση οντότητας που υλοποιεί τη διεπαφή.

StartState.java

Δημόσια κλάση StartState υλοποιεί κατάσταση ( public void DoAction(context Context) ( System.out.println("Το πρόγραμμα αναπαραγωγής βρίσκεται σε κατάσταση εκκίνησης"); context.setState(this); ) public String ToString() (επιστρέφει "αρχική κατάσταση"; ) )

StopState.java

Δημόσια κλάση StopState υλοποιεί State ( public void doAction(Context context) ( System.out.println("Player is in stop state"); context.setState(this); ) public String toString())( return "Stop State"); ) )

Βήμα 3

Δημιουργία τάξης συμφραζόμενα.

Context.java

Δημόσια κλάση (Context private State State; δημόσιο πλαίσιο () (state = NULL; ) public void SetState (State State) ( this.state = state; ) public State GetState () (return state; ) )

Βήμα 4

Χρήση συμφραζόμεναγια να δείτε τη συμπεριφορά όταν αλλάζει η κατάσταση αλλαγής κατάσταση.

StatePatternDemo.java

Δημόσια κλάση StatePatternDemo(state static force main(String)(agdz Context Context = new context(); StartState startState = new StartState(); startState.doAction(context); System.out.println(context.getState()) ToString( ) . StopState stopState = new StopState

Βήμα 5

Ελέγξτε την έξοδο.

Η συσκευή αναπαραγωγής βρίσκεται στην αρχική κατάσταση Κατάσταση έναρξης Η συσκευή αναπαραγωγής βρίσκεται στην κατάσταση διακοπής σταμάτημα

Τελευταία ενημέρωση: 31/10/2015

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

Πότε χρησιμοποιείται αυτό το μοτίβο;

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

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

Το διάγραμμα UML αυτού του μοτίβου σχεδίασης προτείνει το ακόλουθο σύστημα:

Επίσημος ορισμός ενός μοτίβου στη C#:

Πρόγραμμα τάξης ( static void Main() ( Context context = new Context(new StateA()); context.Request(); // Go to StateB context.Request(); // Go to StateA ) ) abstract class State ( public abstract void Handle(Context Context) class StateA: State ( δημόσια παράκαμψη κενό Handle(Context context) (context.State = new StateB(); ) class StateB: State ( public override void Handle(context context) State = new StateA( ) class Context ( public State State ( get; set; ) public Context(State state) ( this.State = state; ) public void Request() ( this.State.Handle(this);) )

Οι συμμετέχοντες του μοτίβου

    Κατάσταση: ορίζει τη διεπαφή κατάστασης

    Οι κλάσεις StateA και StateB είναι συγκεκριμένες υλοποιήσεις καταστάσεων

    Context: Αντιπροσωπεύει ένα αντικείμενο του οποίου η συμπεριφορά πρέπει να αλλάζει δυναμικά ανάλογα με την κατάσταση. Η εκτέλεση συγκεκριμένων ενεργειών ανατίθεται στο κρατικό αντικείμενο

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

Πρόγραμμα τάξης ( static void Main (string args) ( Water water = new Water(WaterState.LIQUID); water.Heat(); water.Frost(); water.Frost(); Console.Read(); ) enum WaterState ( ΣΤΕΡΕΑ, ΥΓΡΟ, ΑΕΡΙΟ ) κατηγορία Νερό ( δημόσια Κατάσταση Κατάστασης Νερού ( λήψη; Ορισμός ("Μετατρέψτε τον πάγο σε υγρό"); (Κατάσταση == WaterState.GAS) ( Console.WriteLine ("Αύξηση της θερμοκρασίας των υδρατμών"); ) ) δημόσιο κενό Frost() ( if (State == WaterState.LIQUID) ( Console.WriteLine ("Μετατροπή υγρού σε πάγο "); Κατάσταση = WaterState.SOLID; ) αλλιώς εάν (Κατάσταση == WaterState.GAS) ( Console.WriteLine("Μετατροπή υδρατμών σε υγρό"); Κατάσταση = WaterState.LIQUID; ) ) )

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

Πρόγραμμα τάξης ( static void Main(string args) ( Water water = new Water(new LiquidWaterState()); water.Heat(); water.Frost(); water.Frost(); Console.Read(); ) ) class Νερό ( δημόσια κατάσταση IWaterState ( get; set; ) public Water(IWaterState ws) ( State = ws; ) public void Heat() ( State.Heat(this); ) public void Frost() ( State.Frost(this); ) ) διεπαφή IWaterState ( void Heat(Water water); void Frost(Water water); ) class SolidWaterState: IWaterState ( public void Heat(Water water) ( Console.WriteLine("Turn ice in liquid"); water.State = new LiquidWaterState(); ) ; water.State = new GasWaterState( ) public void Frost(Water water) ( Console.WriteLine("Μετατροπή υγρού σε πάγο"); water.State = new SolidWaterState(); ) ) class GasWaterState: IWaterSt Θερμότητα (Νερό νερό) ( Console.WriteLine("Αύξηση της θερμοκρασίας των υδρατμών"); ) δημόσιο κενό Frost (Νερό νερό) ( Console.WriteLine ("Μετατροπή υδρατμών σε υγρό"); νερό. Κατάσταση = νέο LiquidWaterState(); ) )

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

Σκοπός του κρατικού προτύπου

  • Το πρότυπο κατάστασης επιτρέπει σε ένα αντικείμενο να αλλάξει τη συμπεριφορά του ανάλογα με την εσωτερική του κατάσταση. Φαίνεται ότι το αντικείμενο έχει αλλάξει κλάση.
  • Το μοτίβο κατάστασης είναι μια αντικειμενοστραφής υλοποίηση μιας μηχανής κατάστασης.

Πρόβλημα προς επίλυση

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

Συζήτηση για το πρότυπο του κράτους

Το πρότυπο κατάστασης λύνει αυτό το πρόβλημα ως εξής:

  • Εισάγει μια κλάση Context που ορίζει μια διεπαφή με τον έξω κόσμο.
  • Εισάγει την κατηγορία αφηρημένη κατάσταση.
  • Αντιπροσωπεύει τις διάφορες «καταστάσεις» μιας κρατικής μηχανής ως κρατικές υποκατηγορίες.
  • Η κλάση Context έχει έναν δείκτη στην τρέχουσα κατάσταση που αλλάζει όταν αλλάζει η κατάσταση της μηχανής κατάστασης.

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

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

Δομή προτύπων κατάστασης

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

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

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

Χρησιμοποιώντας το μοτίβο κατάστασης

  • Καθορίστε μια υπάρχουσα ή δημιουργήστε μια νέα κλάση περιτυλίγματος περιβάλλοντος που θα χρησιμοποιηθεί από τον πελάτη ως "μηχανή κατάστασης".
  • Δημιουργήστε μια βασική κλάση κατάστασης που αναπαράγει τη διεπαφή της κλάσης Context. Κάθε μέθοδος παίρνει μια πρόσθετη παράμετρο: μια παρουσία της κλάσης Context. Η κλάση State μπορεί να ορίσει οποιαδήποτε χρήσιμη συμπεριφορά "προεπιλογής".
  • Δημιουργήστε κλάσεις που προέρχονται από κατάσταση για όλες τις πιθανές καταστάσεις.
  • Η κλάση περιτυλίγματος περιβάλλοντος έχει μια αναφορά στο αντικείμενο τρέχουσας κατάστασης.
  • Η κλάση Context απλώς αναθέτει όλα τα αιτήματα που λαμβάνονται από τον πελάτη στο αντικείμενο "τρέχουσα κατάσταση", με τη διεύθυνση του αντικειμένου Context να μεταβιβάζεται ως πρόσθετη παράμετρος.
  • Χρησιμοποιώντας αυτήν τη διεύθυνση, οι μέθοδοι της κλάσης State μπορούν να αλλάξουν την "τρέχουσα κατάσταση" της κλάσης Context εάν είναι απαραίτητο.

Χαρακτηριστικά του κρατικού προτύπου

  • Τα αντικείμενα κατάστασης είναι συχνά μονότονα.
  • Το Flyweight δείχνει πώς και πότε μπορούν να διαχωριστούν τα αντικείμενα State.
  • Το μοτίβο διερμηνέα μπορεί να χρησιμοποιήσει την κατάσταση για να ορίσει τα περιβάλλοντα ανάλυσης.
  • Τα μοτίβα State και Bridge έχουν παρόμοιες δομές, εκτός από το ότι το Bridge επιτρέπει μια ιεραρχία κλάσεων φακέλου (αναλόγων κλάσεων "wrapper"), ενώ το State όχι. Αυτά τα μοτίβα έχουν παρόμοιες δομές, αλλά επιλύουν διαφορετικά προβλήματα: Η κατάσταση επιτρέπει σε ένα αντικείμενο να αλλάξει τη συμπεριφορά του ανάλογα με την εσωτερική του κατάσταση, ενώ το Bridge διαχωρίζει την αφαίρεση από την εφαρμογή της, ώστε να μπορούν να αλλάξουν ανεξάρτητα το ένα από το άλλο.
  • Η εφαρμογή του κρατικού προτύπου βασίζεται στο πρότυπο της στρατηγικής. Οι διαφορές βρίσκονται στον σκοπό τους.

Εφαρμογή του κρατικού προτύπου

Εξετάστε ένα παράδειγμα μηχανής πεπερασμένης κατάστασης με δύο πιθανές καταστάσεις και δύο γεγονότα.

#περιλαμβάνω χρησιμοποιώντας namespace std? class Machine ( class State *current; public: Machine(); void setCurrent(State *s) (current = s; ) void on(); void off(); class State ( public: virtual void on (Machine *m) ( cout<< " already ON\n"; } virtual void off(Machine *m) { cout << " already OFF\n"; } }; void Machine::on() { current->για το θέμα αυτό); ) void Machine::off() (current->off(this); ) class ON: public State ( public: ON() ( cout<< " ON-ctor "; }; ~ON() { cout << " dtor-ON\n"; }; void off(Machine *m); }; class OFF: public State { public: OFF() { cout << " OFF-ctor "; }; ~OFF() { cout << " dtor-OFF\n"; }; void on(Machine *m) { cout << " going from OFF to ON"; m->setCurrent(new ON()); διαγράψτε αυτό? ) ); void ON::off(Machine *m) (cout<< " going from ON to OFF"; m->setCurrent(new OFF()); διαγράψτε αυτό? ) Machine::Machine() ( τρέχον = νέο OFF(); cout<< "\n"; } int main() { void(Machine:: *ptrs)() = { Machine::off, Machine::on }; Machine fsm; int num; while (1) { cout << "Enter 0/1: "; cin >>αριθμός; (fsm. *ptrs)(); ) )