Σε αυτό το άρθρο, δείχνω πώς η υιοθέτηση τεχνικών προγραμματισμού τύπου δηλωτικού μπορεί να επιτρέψει στις ομάδες να δημιουργήσουν εφαρμογές ιστού που είναι ευκολότερες να επεκταθούν και να συντηρηθούν.
'... ο δηλωτικός προγραμματισμός είναι ένα πρότυπο προγραμματισμού που εκφράζει τη λογική ενός υπολογισμού χωρίς να περιγράφει τη ροή ελέγχου του.' —Remo H. Jansen, Πραγματικός λειτουργικός προγραμματισμός με TypeScript
Όπως τα περισσότερα προβλήματα στο λογισμικό, το να αποφασίζετε να χρησιμοποιήσετε τεχνικές δηλωτικού προγραμματισμού στις εφαρμογές σας απαιτεί προσεκτική αξιολόγηση των αντισταθμίσεων. Δείτε ένα από τα δικά μας προηγούμενα άρθρα για μια εις βάθος συζήτηση αυτών.
Εδώ, εστιάζεται στο πώς μπορούν να υιοθετηθούν σταδιακά πρότυπα δηλωτικού προγραμματισμού τόσο για τις νέες όσο και για τις υπάρχουσες εφαρμογές JavaScript , μια γλώσσα που υποστηρίζει πολλαπλά παραδείγματα.
Πρώτον, συζητάμε πώς να χρησιμοποιήσετε το TypeScript τόσο στο πίσω όσο και στο μπροστινό μέρος για να κάνουμε τον κώδικά σας πιο εκφραστικό και ανθεκτικό στην αλλαγή. Στη συνέχεια, διερευνούμε μηχανές πεπερασμένης κατάστασης (FSM) για τον εξορθολογισμό της ανάπτυξης front-end και την αύξηση της συμμετοχής των ενδιαφερομένων στη διαδικασία ανάπτυξης.
Τα FSM δεν είναι μια νέα τεχνολογία. Ανακαλύφθηκαν πριν από σχεδόν 50 χρόνια και είναι δημοφιλείς σε κλάδους όπως η επεξεργασία σήματος, η αεροναυτική και η χρηματοδότηση, όπου η ορθότητα του λογισμικού μπορεί να είναι κρίσιμη. Είναι επίσης πολύ κατάλληλα για μοντελοποίηση προβλημάτων που προκύπτουν συχνά στη σύγχρονη ανάπτυξη ιστού, όπως ο συντονισμός σύνθετων ασύγχρονων ενημερώσεων κατάστασης και κινούμενων εικόνων.
Αυτό το όφελος προκύπτει λόγω περιορισμών στον τρόπο διαχείρισης της κατάστασης. Μια μηχανή κατάστασης μπορεί να βρίσκεται σε μία μόνο κατάσταση ταυτόχρονα και έχει περιορισμένες γειτονικές καταστάσεις στις οποίες μπορεί να μεταβεί σε απόκριση σε εξωτερικά συμβάντα (όπως κλικ ποντικιού ή λήψη αποκρίσεων). Το αποτέλεσμα είναι συνήθως ένα σημαντικά μειωμένο ποσοστό ελαττωμάτων. Ωστόσο, οι προσεγγίσεις FSM μπορεί να είναι δύσκολο να κλιμακωθούν ώστε να λειτουργούν καλά σε μεγάλες εφαρμογές. Οι πρόσφατες επεκτάσεις σε FSM που ονομάζονται πολιτικά διαγράμματα επιτρέπουν την οπτικοποίηση σύνθετων FSM και την κλιμάκωση σε πολύ μεγαλύτερες εφαρμογές, που είναι η γεύση των μηχανών πεπερασμένης κατάστασης στην οποία επικεντρώνεται αυτό το άρθρο. Για την επίδειξή μας, θα χρησιμοποιήσουμε τη βιβλιοθήκη XState, η οποία είναι μια από τις καλύτερες λύσεις για FSM και διαγράμματα κατάστασης σε JavaScript.
κόστος μεταγωγής στις πέντε δυνάμεις του porter
Ο προγραμματισμός ενός διακομιστή ιστού με χρήση δηλωτικών προσεγγίσεων είναι ένα μεγάλο θέμα και μπορεί συνήθως να ξεκινήσει με την αξιολόγηση μιας κατάλληλης γλώσσας λειτουργικού προγραμματισμού από τον διακομιστή. Αντ 'αυτού, ας υποθέσουμε ότι το διαβάζετε σε μια στιγμή που έχετε ήδη επιλέξει (ή σκέφτεστε) Node.js για το πίσω μέρος σας .
Αυτή η ενότητα περιγράφει μια προσέγγιση για οντότητες μοντελοποίησης στο πίσω μέρος που έχει τα ακόλουθα οφέλη:
Εξετάστε το καθήκον να αναζητήσετε έναν συγκεκριμένο χρήστη μέσω της διεύθυνσης email του σε JavaScript:
function validateEmail(email) { if (typeof email !== 'string') return false; return isWellFormedEmailAddress(email); } function lookupUser(validatedEmail) { // Assume a valid email is passed in. // Safe to pass this down to the database for a user lookup.. }
Αυτή η λειτουργία δέχεται μια διεύθυνση email ως συμβολοσειρά και επιστρέφει τον αντίστοιχο χρήστη από τη βάση δεδομένων όταν υπάρχει αντιστοιχία.
Η υπόθεση είναι ότι lookupUser()
θα κληθεί μόνο μετά την πραγματοποίηση της βασικής επικύρωσης. Αυτή είναι μια βασική υπόθεση. Τι γίνεται αν αρκετές εβδομάδες αργότερα, πραγματοποιείται κάποια αναδιαμόρφωση και αυτή η υπόθεση δεν ισχύει πλέον; Τα δάχτυλα διέσχισαν ότι οι δοκιμές της μονάδας πιάσουν το σφάλμα, ή ενδέχεται να στέλνουμε μη φιλτραρισμένο κείμενο στη βάση δεδομένων!
Ας εξετάσουμε ένα ισοδύναμο TypeScript της συνάρτησης επικύρωσης:
function validateEmail(email: string) { // No longer needed the type check (typeof email === 'string'). return isWellFormedEmailAddress(email); }
Αυτή είναι μια ελαφριά βελτίωση, με τον μεταγλωττιστή TypeScript να μας σώζει από την προσθήκη ενός επιπλέον βήματος επικύρωσης χρόνου εκτέλεσης.
Η ασφάλεια εγγυάται ότι η ισχυρή πληκτρολόγηση δεν μπορεί να έχει αξιοποιηθεί ακόμη. Ας δούμε αυτό.
Ας βελτιώσουμε την ασφάλεια του τύπου και να μην επιτρέψουμε να περάσουμε μη επεξεργασμένες χορδές ως είσοδο στο looukupUser
:
type ValidEmail = { value: string }; function validateEmail(input: string): Email | null { if (!isWellFormedEmailAddress(input)) return null; return { value: email }; } function lookupUser(email: ValidEmail): User { // No need to perform validation. Compiler has already ensured only valid emails have been passed in. return lookupUserInDatabase(email.value); }
Αυτό είναι καλύτερο, αλλά είναι δυσκίνητο. Όλες οι χρήσεις του ValidEmail
πρόσβαση στην πραγματική διεύθυνση μέσω email.value
. Το TypeScript χρησιμοποιεί κατασκευαστικός πληκτρολογώντας παρά το ονομαστικός πληκτρολόγηση που χρησιμοποιείται από γλώσσες όπως Java και C #.
Αν και ισχυρό, αυτό σημαίνει ότι οποιοσδήποτε άλλος τύπος που τηρεί αυτήν την υπογραφή θεωρείται ισοδύναμος. Για παράδειγμα, ο ακόλουθος τύπος κωδικού πρόσβασης θα μπορούσε να περάσει στο lookupUser()
χωρίς παράπονο από τον μεταγλωττιστή:
type ValidPassword = { value: string }; const password = { value: 'password' }; lookupUser(password); // No error.
Μπορούμε να επιτύχουμε ονομαστική πληκτρολόγηση σε TypeScript χρησιμοποιώντας τομή:
type ValidEmail = string & { _: 'ValidEmail' }; function validateEmail(input: string): ValidEmail { // Perform email validation checks.. return input as ValidEmail; } type ValidPassword = string & { _: 'ValidPassword' }; function validatePassword(input: string): ValidPassword { ... } lookupUser(' [email protected] '); // Error: expected type ValidEmail. lookupUser(validatePassword('MyPassword'); // Error: expected type ValidEmail. lookupUser(validateEmail(' [email protected] ')); // Ok.
Έχουμε πλέον επιτύχει το στόχο ότι μόνο επικυρωμένες συμβολοσειρές email μπορούν να μεταφερθούν σε lookupUser()
.
Επαγγελματική συμβουλή: Εφαρμόστε εύκολα αυτό το μοτίβο χρησιμοποιώντας τον ακόλουθο τύπο βοηθού:
type Opaque = T & { __TYPE__: K }; type Email = Opaque; type Password = Opaque; type UserId = Opaque;
Πληκτρολογώντας έντονα οντότητες στον τομέα σας, μπορούμε:
Ο τύπος μοντελοποίησης συνοδεύεται από ορισμένες ανταλλαγές που πρέπει να ληφθούν υπόψη:
Έχουμε δείξει πώς ο υπάρχων κώδικας JavaScript στο διακομιστή ή το κοινόχρηστο επίπεδο επικύρωσης back-end / front-end μπορεί να επεκταθεί με τύπους για τη βελτίωση της αναγνωσιμότητας του κώδικα και επιτρέποντας ασφαλέστερη αναδιαμόρφωση - σημαντικές απαιτήσεις για ομάδες.
Οι διεπαφές χρήστη που αναπτύχθηκαν χρησιμοποιώντας τεχνικές δηλωτικού προγραμματισμού εστιάζουν την προσπάθεια στην περιγραφή του «τι» έναντι του «πώς». Δύο από τα τρία βασικά συστατικά του ιστού, CSS και HTML, είναι δηλωτικές γλώσσες προγραμματισμού που έχουν αντέξει στη δοκιμασία του χρόνου και περισσότερο από 1 δισεκατομμύριο ιστότοποι .
Το React προήλθε από το Facebook το 2013 και άλλαξε σημαντικά την πορεία της ανάπτυξης front-end. Όταν το χρησιμοποίησα για πρώτη φορά, μου άρεσε πώς μπορούσα δηλώνω το GUI ως συνάρτηση της κατάστασης της εφαρμογής. Είχα πλέον τη δυνατότητα να συνθέσω μεγάλα και περίπλοκα περιβάλλοντα χρήστη από μικρότερα δομικά στοιχεία χωρίς να ασχοληθώ με τις ακατάστατες λεπτομέρειες χειρισμού του DOM και να παρακολουθώ ποια τμήματα της εφαρμογής χρειάζονται ενημέρωση ως απάντηση στις ενέργειες των χρηστών. Θα μπορούσα σε μεγάλο βαθμό να αγνοήσω το χρόνος πτυχή κατά τον καθορισμό της διεπαφής χρήστη και εστίαση στη διασφάλιση της σωστής μετάβασης της εφαρμογής μου από τη μία κατάσταση στην άλλη.
Για να επιτευχθεί ένας απλούστερος τρόπος ανάπτυξης UI, η React εισήγαγε ένα επίπεδο αφαίρεσης μεταξύ του προγραμματιστή και του μηχανήματος / προγράμματος περιήγησης: το εικονικό DOM .
Άλλα σύγχρονα πλαίσια διεπαφής χρήστη ιστού έχουν γεφυρώσει επίσης αυτό το κενό, αν και με διαφορετικούς τρόπους. Για παράδειγμα, η Vue χρησιμοποιεί λειτουργική αντιδραστικότητα είτε μέσω JavaScript / ρυθμιστών (Vue 2) είτε μέσω διακομιστών μεσολάβησης (Vue 3). Το Svelte προσφέρει αντιδραστικότητα μέσω ενός επιπλέον βήματος σύνταξης πηγαίου κώδικα (Svelte).
Αυτά τα παραδείγματα φαίνεται να δείχνουν μεγάλη επιθυμία στον κλάδο μας να παρέχει καλύτερα, απλούστερα εργαλεία στους προγραμματιστές για να εκφράσουν τη συμπεριφορά των εφαρμογών μέσω δηλωτικών προσεγγίσεων.
Ενώ το επίπεδο παρουσίασης συνεχίζει να περιστρέφεται γύρω από κάποια μορφή HTML (π.χ. JSX στο React, πρότυπα που βασίζονται σε HTML που βρέθηκαν στο Vue, Angular και Svelte), υποστηρίζω ότι το πρόβλημα του τρόπου μοντελοποίησης της κατάστασης μιας εφαρμογής με τρόπο που είναι εύκολα κατανοητό από άλλους προγραμματιστές και διατηρήσιμο καθώς η εφαρμογή μεγαλώνει δεν έχει επιλυθεί. Βλέπουμε αποδείξεις για αυτό μέσω του πολλαπλασιασμού των βιβλιοθηκών και των προσεγγίσεων διαχείρισης του κράτους που συνεχίζεται μέχρι σήμερα.
Η κατάσταση περιπλέκεται από τις αυξανόμενες προσδοκίες των σύγχρονων εφαρμογών ιστού. Ορισμένες αναδυόμενες προκλήσεις που πρέπει να υποστηρίξουν οι σύγχρονες κρατικές προσεγγίσεις:
Οι μηχανές πεπερασμένης κατάστασης έχουν χρησιμοποιηθεί εκτενώς για την ανάπτυξη λογισμικού σε ορισμένες βιομηχανίες όπου η ευρωστία της εφαρμογής είναι κρίσιμη, όπως η αεροπορία και η χρηματοδότηση. Επίσης, κερδίζει σταθερά δημοτικότητα για την ανάπτυξη εφαρμογών ιστού από την αρχή μέσω, για παράδειγμα, της εξαιρετικής Βιβλιοθήκη XState .
Η Wikipedia ορίζει ένα μηχανή πεπερασμένης κατάστασης όπως και:
Ένα αφηρημένο μηχάνημα που μπορεί να είναι ακριβώς σε ένα από έναν πεπερασμένο αριθμό καταστάσεων ανά πάσα στιγμή. Το FSM μπορεί να αλλάξει από τη μία κατάσταση στην άλλη ως απόκριση σε ορισμένες εξωτερικές εισόδους. η αλλαγή από μια κατάσταση σε άλλη ονομάζεται μετάβαση. Ένα FSM ορίζεται από μια λίστα με τις καταστάσεις του, την αρχική του κατάσταση και τις συνθήκες για κάθε μετάβαση.
Και επιπλέον:
Μια κατάσταση είναι μια περιγραφή της κατάστασης ενός συστήματος που περιμένει να εκτελέσει μια μετάβαση.
Τα FSM στη βασική τους μορφή δεν κλιμακώνονται καλά σε μεγάλα συστήματα λόγω του πρόβλημα κατάστασης έκρηξης . Πρόσφατα, τα διαγράμματα κατάστασης UML δημιουργήθηκαν για να επεκτείνουν τα FSM με ιεραρχία και συνάφεια, τα οποία επιτρέπουν την ευρεία χρήση των FSM σε εμπορικές εφαρμογές.
Πρώτον, πώς μοιάζει ένα FSM ως κωδικός; Υπάρχουν πολλοί τρόποι για να εφαρμόσετε μια μηχανή πεπερασμένης κατάστασης σε JavaScript.
Ακολουθεί ένα μηχάνημα που περιγράφει τις πιθανές καταστάσεις στις οποίες μπορεί να βρίσκεται ένα JavaScript, το οποίο εφαρμόζεται χρησιμοποιώντας μια δήλωση εναλλαγής:
const initialState = { type: 'idle', error: undefined, result: undefined }; function transition(state = initialState, action) { switch (action) { case 'invoke': return { type: 'pending' }; case 'resolve': return { type: 'completed', result: action.value }; case 'error': return { type: 'completed', error: action.error ; default: return state; } }
Αυτό το στυλ κώδικα θα είναι γνωστό στους προγραμματιστές που έχουν χρησιμοποιήσει τη δημοφιλή βιβλιοθήκη διαχείρισης κατάστασης Redux.
Εδώ είναι το ίδιο μηχάνημα που εφαρμόζεται ως αντικείμενο JavaScript χρησιμοποιώντας τη βιβλιοθήκη JavaScript XState:
const promiseMachine = Machine({ id: 'promise', initial: 'idle', context: { result: undefined, error: undefined, }, states: { idle: { on: { INVOKE: 'pending', }, }, pending: { on: { RESOLVE: 'success', REJECT: 'failure', }, }, success: { type: 'final', actions: assign({ result: (context, event) => event.data, }), }, failure: { type: 'final', actions: assign({ error: (context, event) => event.data, }), }, }, });
Ενώ η έκδοση XState είναι λιγότερο συμπαγής, η αναπαράσταση αντικειμένων έχει πολλά πλεονεκτήματα:
Το XState υποστηρίζει διαγράμματα κατάστασης και εφαρμόζει το SCXML προδιαγραφή, που το καθιστά κατάλληλο για χρήση σε πολύ μεγάλες εφαρμογές.
Οπτικοποίηση κρατικών γραφημάτων μιας υπόσχεσης:
Τα παρακάτω είναι μερικές βέλτιστες πρακτικές που πρέπει να εφαρμόσετε όταν χρησιμοποιείτε το XState για να διατηρήσετε τα έργα διατηρήσιμα.
Το XState επιτρέπει ανεπιθύμητες ενέργειες (που περιλαμβάνουν δραστηριότητες όπως καταγραφή ή αιτήσεις API) να προσδιορίζονται ανεξάρτητα από τη λογική του μηχανήματος κατάστασης.
Αυτό έχει τα ακόλουθα οφέλη:
const fetchUsersMachine = Machine({ id: 'fetchUsers', initial: 'idle', context: { users: undefined, error: undefined, nextPage: 0, }, states: { idle: { on: { FETCH: 'fetching', }, }, fetching: { invoke: { src: (context) => fetch(`url/to/users?page=${context.nextPage}`).then((response) => response.json() ), onDone: { target: 'success', actions: assign({ users: (context, event) => [...context.users, ...event.data], // Data holds the newly fetched users nextPage: (context) => context.nextPage + 1, }), }, onError: { target: 'failure', error: (_, event) => event.data, // Data holds the error }, }, }, // success state.. // failure state.. }, });
Ενώ είναι δελεαστικό να γράφετε μηχανές κατάστασης με αυτόν τον τρόπο ενώ συνεχίζετε να δουλεύετε, ένας καλύτερος διαχωρισμός των ανησυχιών επιτυγχάνεται μεταβιβάζοντας παρενέργειες ως επιλογές:
const services = { getUsers: (context) => fetch( `url/to/users?page=${context.nextPage}` ).then((response) => response.json()) } const fetchUsersMachine = Machine({ ... states: { ... fetching: { invoke: { // Invoke the side effect at key: 'getUsers' in the supplied services object. src: 'getUsers', } on: { RESOLVE: 'success', REJECT: 'failure', }, }, ... }, // Supply the side effects to be executed on state transitions. { services } });
Αυτό επιτρέπει επίσης την εύκολη δοκιμή μονάδας του μηχανήματος κατάστασης, επιτρέποντας ρητή κοροϊδία των λήψεων χρήστη:
async function testFetchUsers() { return [{ name: 'Peter', location: 'New Zealand' }]; } const machine = fetchUsersMachine.withConfig({ services: { getUsers: (context) => testFetchUsers(), }, });
Δεν είναι πάντα άμεσα προφανές πώς είναι καλύτερο να δομήσετε έναν προβληματικό τομέα σε μια καλή ιεραρχία πεπερασμένων καταστάσεων όταν ξεκινάτε.
Υπόδειξη: Χρησιμοποιήστε την ιεραρχία των στοιχείων διεπαφής χρήστη για να βοηθήσετε στην καθοδήγηση αυτής της διαδικασίας. Δείτε την επόμενη ενότητα σχετικά με τον τρόπο χαρτογράφησης μηχανών κατάστασης σε στοιχεία διεπαφής χρήστη.
Ένα σημαντικό πλεονέκτημα της χρήσης μηχανών κατάστασης είναι η μοντελοποίηση ρητώς όλων των καταστάσεων και των μεταβάσεων μεταξύ καταστάσεων στις εφαρμογές σας, έτσι ώστε η συμπεριφορά που προκύπτει να είναι σαφώς κατανοητή, καθιστώντας τα λογικά λάθη ή κενά εύκολα εντοπισμένα.
Για να λειτουργήσει καλά, τα μηχανήματα πρέπει να διατηρούνται μικρά και συνοπτικά. Ευτυχώς, η σύνθεση ιεραρχικών μηχανών κατάστασης είναι εύκολη. Στο παράδειγμα κανονικών διαγραμμάτων κατάστασης ενός συστήματος φωτεινού σηματοδότη, η ίδια η «κόκκινη» κατάσταση γίνεται μια μηχανή θυγατρικής κατάστασης. Το μητρικό μηχάνημα 'φως' δεν γνωρίζει τις εσωτερικές καταστάσεις του 'κόκκινου' αλλά αποφασίζει πότε θα εισαγάγει το 'κόκκινο' και ποια είναι η επιδιωκόμενη συμπεριφορά κατά την έξοδο:
Πάρτε, για παράδειγμα, έναν πολύ απλοποιημένο, φανταστικό ιστότοπο ηλεκτρονικού εμπορίου που έχει τις ακόλουθες προβολές React:
setState() / useState()
Η διαδικασία δημιουργίας μηχανών κατάστασης που αντιστοιχεί στις παραπάνω προβολές μπορεί να είναι οικεία για όσους έχουν χρησιμοποιήσει τη βιβλιοθήκη διαχείρισης κατάστασης Redux:
|_+_|) για την αντιμετώπιση του προβλήματος; Η παρακολούθηση του κατά πόσο το αναδυόμενο καρότσι είναι ανοιχτό αυτήν τη στιγμή δεν απαιτεί τη χρήση ενός μηχανήματος πεπερασμένης κατάστασης.
Ενώ τα διαγράμματα κατάστασης και τα FSM μπορούν να λύσουν κομψά ορισμένα δύσκολα προβλήματα, η απόφαση για τα καλύτερα εργαλεία και προσεγγίσεις για χρήση για μια συγκεκριμένη εφαρμογή συνήθως εξαρτάται από διάφορους παράγοντες.
Μερικές καταστάσεις όπου η χρήση μηχανών πεπερασμένης κατάστασης λάμπει:
συνεχής παράδοση με χρήση packer και terraform
Η δημοτικότητα και η υιοθέτηση του δηλωτικού προγραμματισμού στην κοινότητα ανάπτυξης ιστού συνεχίζουν να αυξάνονται.
Ενώ η σύγχρονη ανάπτυξη ιστού συνεχίζει να γίνεται πιο περίπλοκη, οι βιβλιοθήκες και τα πλαίσια που υιοθετούν τον δηλωτικό προγραμματισμό προσεγγίζουν την επιφάνεια με αυξανόμενη συχνότητα. Ο λόγος φαίνεται σαφής - πρέπει να δημιουργηθούν απλούστερες, πιο περιγραφικές προσεγγίσεις στο λογισμικό γραφής.
Χρησιμοποιώντας έντονα δακτυλογραφημένες γλώσσες όπως το TypeScript επιτρέπει στις οντότητες στον τομέα της εφαρμογής να μοντελοποιηθούν συνοπτικά και ρητά, γεγονός που μειώνει την πιθανότητα σφαλμάτων και τον αριθμό του κώδικα ελέγχου που είναι επιρρεπές σε σφάλματα που πρέπει να χειριστεί. Η υιοθέτηση μηχανών πεπερασμένης κατάστασης και διαγραμμάτων κατάστασης στο μπροστινό μέρος επιτρέπει στους προγραμματιστές να δηλώσουν την επιχειρησιακή λογική μιας εφαρμογής μέσω μεταβάσεων κατάστασης, επιτρέποντας την ανάπτυξη εργαλείων πλούσιων οπτικοποιήσεων και αυξάνοντας την ευκαιρία για στενή συνεργασία με μη προγραμματιστές.
Όταν το κάνουμε αυτό, αλλάζουμε την εστίασή μας από τα παξιμάδια του τρόπου λειτουργίας της εφαρμογής σε προβολή υψηλότερου επιπέδου που μας επιτρέπει να επικεντρωθούμε ακόμη περισσότερο στις ανάγκες του πελάτη και να δημιουργήσουμε διαρκή αξία.
Ο εντυπωσιακός προγραμματισμός λέει στον υπολογιστή πώς να επιτύχει ένα αποτέλεσμα μέσω μιας σειράς εντολών όπως σε μια συνταγή, ενώ ο δηλωτικός προγραμματισμός περιγράφει το επιθυμητό τελικό αποτέλεσμα που πρέπει να επιτευχθεί.
Ένα μηχάνημα πεπερασμένης κατάστασης ξεκινά στην αρχική του κατάσταση και μεταβαίνει σε μια άλλη γνωστή κατάσταση ως απόκριση σε μια ενέργεια όπως το πάτημα ενός κουμπιού ή η απόκριση από τον διακομιστή.
Οι μηχανές πεπερασμένης κατάστασης επιβάλλουν περιορισμούς στον τρόπο με τον οποίο μπορεί να γραφτεί ένα πρόγραμμα, γεγονός που μειώνει τα πιθανά σφάλματα, επειδή μπορούν να βρίσκονται σε μία μόνο κατάσταση ανά πάσα στιγμή και να έχουν έναν πεπερασμένο αριθμό καταστάσεων στις οποίες μπορούν να κινηθούν.
Οι τύποι επιτρέπουν στους προγραμματιστές να περιγράψουν τις οντότητες της εφαρμογής, οι οποίες αποφεύγουν τη σύνταξη επιπλέον κώδικα για να επαληθεύσουν ότι χρησιμοποιούνται σωστά σε όλη την εφαρμογή.
Το statechart είναι μια πρόσφατη επέκταση της μηχανής πεπερασμένων καταστάσεων που επιλύει ορισμένα από τα προβλήματά της, όπως η κατάσταση έκρηξης με την εισαγωγή ιεραρχικών μηχανών και επιτρέπει την οπτικοποίηση της συμπεριφοράς του συστήματος.