Ένα σχέδιο σχεδίασης είναι ένα πρότυπο που λύνει ένα συχνά επαναλαμβανόμενο πρόβλημα στο σχεδιασμό λογισμικού.
Το πρότυπο κατάστασης είναι ένα μοτίβο συμπεριφοράς που επιτρέπει σε ένα αντικείμενο να αλλάξει τη συμπεριφορά του όταν αλλάζει η εσωτερική του κατάσταση.
Εδώ θα μάθετε πώς να χρησιμοποιείτε το μοτίβο κατάστασης στο TypeScript.
Ποιο είναι το μοτίβο του κράτους;
Το σχέδιο σχεδίασης κατάστασης σχετίζεται στενά με μια μηχανή πεπερασμένης κατάστασης, η οποία περιγράφει ένα πρόγραμμα που υπάρχει σε ένα πεπερασμένος αριθμός καταστάσεων σε κάθε δεδομένη στιγμή και συμπεριφέρεται διαφορετικά σε κάθε πολιτεία.
Υπάρχουν περιορισμένοι, προκαθορισμένοι κανόνες - μεταβάσεις - που διέπουν τις άλλες καταστάσεις στις οποίες μπορεί να μεταβεί κάθε κατάσταση.
Για το πλαίσιο, σε ένα ηλεκτρονικό κατάστημα, εάν η παραγγελία αγορών ενός πελάτη έχει "παραδοθεί", δεν μπορεί να "ακυρωθεί" επειδή έχει ήδη "παραδοθεί". Τα "Παράδοση" και "Ακυρώθηκε" είναι πεπερασμένες καταστάσεις της παραγγελίας και η παραγγελία θα συμπεριφέρεται διαφορετικά ανάλογα με την κατάστασή της.
Το πρότυπο του κράτους δημιουργεί μια τάξη για κάθε δυνατή κατάσταση, με συγκεκριμένη συμπεριφορά που περιέχεται σε κάθε κλάση.
Ένα παράδειγμα εφαρμογής που βασίζεται σε κατάσταση
Για παράδειγμα, ας υποθέσουμε ότι δημιουργείτε μια εφαρμογή που παρακολουθεί τις καταστάσεις ενός άρθρου για μια εκδοτική εταιρεία. Ένα άρθρο μπορεί είτε να εκκρεμεί έγκριση, είτε να έχει συνταχθεί από συγγραφέα, είτε να έχει επιμεληθεί από έναν εκδότη ή να δημοσιευτεί. Αυτές είναι οι πεπερασμένες καταστάσεις ενός άρθρου που πρόκειται να δημοσιευθεί. σε κάθε μοναδική κατάσταση, το άρθρο συμπεριφέρεται διαφορετικά.
Μπορείτε να απεικονίσετε τις διαφορετικές καταστάσεις και τις μεταβάσεις της εφαρμογής άρθρου με το διάγραμμα καταστάσεων παρακάτω:
Εφαρμόζοντας αυτό το σενάριο σε κώδικα, θα πρέπει πρώτα να δηλώσετε μια διεπαφή για το άρθρο:
διεπαφήΔιασύνδεση άρθρου{
πίσσα(): κενός;
προσχέδιο(): κενός;
επεξεργασία(): κενός;
δημοσιεύω(): κενός;
}
Αυτή η διεπαφή θα έχει όλες τις πιθανές καταστάσεις της εφαρμογής.
Στη συνέχεια, δημιουργήστε μια εφαρμογή που υλοποιεί όλες τις μεθόδους διεπαφής:
// Εφαρμογή
τάξηΑρθρουλοποιείΔιασύνδεση άρθρου{
κατασκευαστής() {
Αυτό.showCurrentState();
}ιδιωτικόςεμφάνιση Τρέχουσα κατάσταση(): κενός{
//...
}δημόσιοπίσσα(): κενός{
//...
}δημόσιοπροσχέδιο(): κενός{
//...
}δημόσιοεπεξεργασία(): κενός{
//...
}
δημόσιοδημοσιεύω(): κενός{
//...
}
}
Το ιδιωτικό εμφάνιση Τρέχουσα κατάσταση η μέθοδος είναι μια χρηστική μέθοδος. Αυτό το σεμινάριο το χρησιμοποιεί για να δείξει τι συμβαίνει σε κάθε κατάσταση. Δεν είναι απαραίτητο μέρος του προτύπου κατάστασης.
Χειρισμός μεταβάσεων κατάστασης
Στη συνέχεια, θα χρειαστεί να χειριστείτε τις μεταβάσεις κατάστασης. Ο χειρισμός της μετάβασης κατάστασης στην τάξη εφαρμογών σας θα απαιτούσε πολλά δηλώσεις υπό όρους. Αυτό θα οδηγήσει σε επαναλαμβανόμενο κώδικα που είναι πιο δύσκολο να διαβαστεί και να διατηρηθεί. Για να λύσετε αυτό το πρόβλημα, μπορείτε να αναθέσετε τη λογική μετάβασης για κάθε κατάσταση στη δική της κλάση.
Πριν γράψετε κάθε κλάση κατάστασης, θα πρέπει να δημιουργήσετε μια αφηρημένη βασική κλάση για να διασφαλίσετε ότι οποιαδήποτε μέθοδος που καλείται σε μη έγκυρη κατάσταση παρουσιάζει σφάλμα.
Για παράδειγμα:
αφηρημένητάξηΆρθροΚράτοςυλοποιείΔιασύνδεση άρθρου{
pitch(): ArticleState {
βολήνέοςΛάθος("Μη έγκυρη λειτουργία: Δεν είναι δυνατή η εκτέλεση εργασίας σε τωρινή κατάσταση");
}draft(): ArticleState {
βολήνέοςΛάθος("Μη έγκυρη λειτουργία: Δεν είναι δυνατή η εκτέλεση εργασίας σε τωρινή κατάσταση");
}edit(): ArticleState {
βολήνέοςΛάθος("Μη έγκυρη λειτουργία: Δεν είναι δυνατή η εκτέλεση εργασίας σε τωρινή κατάσταση");
}
Δημοσίευση(): ArticleState {
βολήνέοςΛάθος("Μη έγκυρη λειτουργία: Δεν είναι δυνατή η εκτέλεση εργασίας σε τωρινή κατάσταση");
}
}
Στη βασική κλάση παραπάνω, κάθε μέθοδος παρουσιάζει ένα σφάλμα. Τώρα, πρέπει να παρακάμψετε κάθε μέθοδο δημιουργώντας συγκεκριμένες κλάσεις που εκτείνεται η βασική κλάση για κάθε κατάσταση. Κάθε συγκεκριμένη κλάση θα περιέχει λογική συγκεκριμένης κατάστασης.
Κάθε εφαρμογή έχει μια κατάσταση αδράνειας, η οποία αρχικοποιεί την εφαρμογή. Η κατάσταση αδράνειας για αυτήν την εφαρμογή θα ορίσει την εφαρμογή στο προσχέδιο κατάσταση.
Για παράδειγμα:
τάξηΣε εκκρεμότητα DraftStateεκτείνεταιΆρθροΚράτος{
pitch(): ArticleState {
ΕΠΙΣΤΡΟΦΗνέος DraftState();
}
}
ο πίσσα μέθοδος στην παραπάνω κλάση αρχικοποιεί την εφαρμογή ορίζοντας την τρέχουσα κατάσταση σε Σχέδιο Κράτους.
Στη συνέχεια, παρακάμψτε τις υπόλοιπες μεθόδους όπως:
τάξηΣχέδιο ΚράτουςεκτείνεταιΆρθροΚράτος{
draft(): ArticleState {
ΕΠΙΣΤΡΟΦΗνέος EditingState();
}
}
Αυτός ο κώδικας υπερισχύει του προσχέδιο μέθοδο και επιστρέφει ένα στιγμιότυπο του EditingState.
τάξηEditingStateεκτείνεταιΆρθροΚράτος{
edit(): ArticleState {
ΕΠΙΣΤΡΟΦΗνέος PublishedState();
}
}
Το μπλοκ κώδικα παραπάνω αντικαθιστά το επεξεργασία μέθοδο και επιστρέφει μια παρουσία του Δημοσιευμένο Κράτος.
τάξηΔημοσιευμένο ΚράτοςεκτείνεταιΆρθροΚράτος{
Δημοσίευση(): ArticleState {
ΕΠΙΣΤΡΟΦΗνέος PendingDraftState();
}
}
Το μπλοκ κώδικα παραπάνω αντικαθιστά το δημοσιεύω μέθοδο και επαναφέρει την εφαρμογή στην κατάσταση αδράνειας, Σε εκκρεμότητα DraftState.
Στη συνέχεια, πρέπει να επιτρέψετε στην εφαρμογή να αλλάξει την κατάστασή της εσωτερικά, αναφέροντας την τρέχουσα κατάσταση μέσω μιας ιδιωτικής μεταβλητής. Μπορείτε να το κάνετε αυτό αρχικοποιώντας την κατάσταση αδράνειας μέσα στην κλάση εφαρμογής σας και αποθηκεύοντας την τιμή σε μια ιδιωτική μεταβλητή:
ιδιωτικός κατάσταση: ArticleState = νέος PendingDraftState();
Στη συνέχεια, ενημερώστε το εμφάνιση Τρέχουσα κατάσταση μέθοδος εκτύπωσης της τρέχουσας τιμής κατάστασης:
ιδιωτικόςεμφάνιση Τρέχουσα κατάσταση(): κενός{
κονσόλα.κούτσουρο(Αυτό.κατάσταση);
}
ο εμφάνιση Τρέχουσα κατάσταση μέθοδος καταγράφει την τρέχουσα κατάσταση της εφαρμογής στην κονσόλα.
Τέλος, αντιστοιχίστε εκ νέου την ιδιωτική μεταβλητή στην τρέχουσα κατάσταση κατάστασης σε καθεμία από τις μεθόδους της εφαρμογής σας.
Για παράδειγμα, ενημερώστε τις εφαρμογές σας πίσσα μέθοδος στο μπλοκ κώδικα παρακάτω:
δημόσιοπίσσα(): κενός{
Αυτό.κράτος = Αυτό.state.pitch();
Αυτό.showCurrentState();
}
Στο μπλοκ κώδικα παραπάνω, το πίσσα Η μέθοδος αλλάζει την κατάσταση από την τρέχουσα κατάσταση στην κατάσταση τόνου.
Ομοίως, όλες οι άλλες μέθοδοι θα αλλάξουν την κατάσταση από την τρέχουσα κατάσταση εφαρμογής στις αντίστοιχες καταστάσεις τους.
Ενημερώστε τις μεθόδους εφαρμογής σας στα μπλοκ κώδικα παρακάτω:
ο προσχέδιο μέθοδος:
δημόσιοπροσχέδιο(): κενός{
Αυτό.κράτος = Αυτό.state.draft();
Αυτό.showCurrentState();
}
ο επεξεργασία μέθοδος:
δημόσιοεπεξεργασία(): κενός{
Αυτό.κράτος = Αυτό.state.edit();
Αυτό.showCurrentState();
}
Και το δημοσιεύω μέθοδος:
δημόσιοδημοσιεύω(): κενός{
Αυτό.κράτος = Αυτό.state.publish();
Αυτό.showCurrentState();
}
Χρήση της Ολοκληρωμένης Εφαρμογής
Η ολοκληρωμένη τάξη της εφαρμογής σας θα πρέπει να είναι παρόμοια με το μπλοκ κώδικα παρακάτω:
// Εφαρμογή
τάξηΑρθρουλοποιείΔιασύνδεση άρθρου{
ιδιωτικός κατάσταση: ArticleState = νέος PendingDraftState();κατασκευαστής() {
Αυτό.showCurrentState();
}ιδιωτικόςεμφάνιση Τρέχουσα κατάσταση(): κενός{
κονσόλα.κούτσουρο(Αυτό.κατάσταση);
}δημόσιοπίσσα(): κενός{
Αυτό.κράτος = Αυτό.state.pitch();
Αυτό.showCurrentState();
}δημόσιοπροσχέδιο(): κενός{
Αυτό.κράτος = Αυτό.state.draft();
Αυτό.showCurrentState();
}δημόσιοεπεξεργασία(): κενός{
Αυτό.κράτος = Αυτό.state.edit();
Αυτό.showCurrentState();
}
δημόσιοδημοσιεύω(): κενός{
Αυτό.κράτος = Αυτό.state.publish();
Αυτό.showCurrentState();
}
}
Μπορείτε να ελέγξετε τις μεταβάσεις κατάστασης καλώντας τις μεθόδους με τη σωστή σειρά. Για παράδειγμα:
συνθ έγγραφα = νέος Αρθρο(); // PendingDraftState: {}
docs.pitch(); // Πρόχειρη κατάσταση: {}
docs.draft(); // EditingState: {}
docs.edit(); // Δημοσιευμένη κατάσταση: {}
docs.publish(); // PendingDraftState: {}
Το παραπάνω μπλοκ κώδικα λειτουργεί επειδή οι καταστάσεις της εφαρμογής έγιναν κατάλληλα.
Εάν προσπαθήσετε να αλλάξετε την κατάσταση με τρόπο που δεν επιτρέπεται, για παράδειγμα, από την κατάσταση προώθησης στην κατάσταση επεξεργασίας, η εφαρμογή θα εμφανίσει ένα σφάλμα:
συνθ έγγραφα = νέος Αρθρο(); // PendingDraftState: {}
docs.pitch() // Πρόχειρη κατάσταση: {}
docs.edit() // Μη έγκυρη λειτουργία: Δεν είναι δυνατή η εκτέλεση εργασίας στην τρέχουσα κατάσταση
Θα πρέπει να χρησιμοποιείτε αυτό το μοτίβο μόνο όταν:
- Δημιουργείτε ένα αντικείμενο που συμπεριφέρεται διαφορετικά ανάλογα με την τρέχουσα κατάστασή του.
- Το αντικείμενο έχει πολλές καταστάσεις.
- Η συμπεριφορά της συγκεκριμένης κατάστασης αλλάζει συχνά.
Πλεονεκτήματα και ανταλλαγές του κρατικού προτύπου
Αυτό το μοτίβο εξαλείφει τις ογκώδεις δηλώσεις υπό όρους και διατηρεί την ενιαία ευθύνη και τις αρχές ανοιχτού/κλειστού. Αλλά μπορεί να είναι υπερβολικό εάν η εφαρμογή έχει λίγες καταστάσεις ή οι καταστάσεις της δεν είναι ιδιαίτερα δυναμικές.