web-dev-qa-db-fra.com

Quelle est la différence entre une machine à états et la mise en oeuvre du modèle d'état?

Je me demande si un machine à états est simplement le motif state au travail ou s’il existe une différence entre ces deux?

J'ai trouvé cet article avec le titre audacieux "le modèle de conception d'état vs machine à états" mais à la fin de la journée, il dit seulement que le modèle modèle d'état fait machines à états obsolète mais ne décrit pas ce qu'est exactement un machine à états par rapport à la mise en oeuvre du modèle state .

25
Christoph

Je décris cette différence auprès de mes collègues, à savoir que les modèles d'état constituent une implémentation plus décentralisée de nombreux états encapsulés autonomes, alors que les machines à états sont plus monolithiques. La nature monolithique des machines à états signifie qu’un seul état sera plus difficile à réutiliser dans une machine différente et qu’il est plus difficile de scinder une machine à états en plusieurs unités de compilation. D'autre part, cette conception monolithique permet une bien meilleure optimisation des machines à états et permet à de nombreuses implémentations de représenter toutes les informations de transition à un seul endroit dans une table. Ceci est particulièrement adapté aux situations dans lesquelles le responsable de l'architecture ou de la fonction d'une machine à états n'est pas familiarisé avec le langage de programmation dans lequel il est implémenté. domaine de programmation. Il est beaucoup plus facile de présenter à ces types de personnes un tableau des transitions, des actions et des gardes que des pages et des pages de modèles d'état. 

Bien que l'article ait été réellement lu, je suis en désaccord avec l'auteur sur plusieurs points:

  • "Il n’ya plus de raison d’utiliser des machines d’état lorsque vous utilisez un langage de programmation orienté objet". Cela n’est catégoriquement pas vrai si vous avez des exigences en matière de vitesse d’exécution. 
  • L’idée que l’implémentation des auteurs est particulièrement courte ou simple, ou qu’elle nécessite moins de maintenance que l’appareil photo numérique boost Statecharts dépend de votre cas d’utilisation et de vos goûts personnels, mais ne peut pas être dite de manière catégorique. http://www.boost.org/doc/libs/1_55_0/libs/statechart/doc/tutorial.html#IntermediateTopicsADigitalCamera

Notez que le changement d'état nécessite une attribution! cela va tuer la vitesse. On pourrait remédier à cela en plaçant tous les états dans un tampon juxtaposé afin de sauvegarder un ou plusieurs cache. Cependant, cela nécessiterait des changements majeurs dans l'exemple des auteurs. 

Notez également que les événements qui ne sont pas gérés ne peuvent pas être alignés et optimisés, comme dans les machines à états statiques, car avec le modèle d'état, ils se trouvent derrière une couche d'indirection dynamique. C’est aussi une efficacité potentielle qui tue en fonction de vos besoins.

Du point de vue de la maintenance, il convient de noter que la journalisation des événements non gérés ne peut pas être effectuée à partir d'un super-État central avec le modèle d'état. De plus, l'ajout d'une nouvelle fonction type/gestionnaire d'événement nécessite l'ajout d'une fonction à tous les états! Je ne considère pas cela comme une maintenance facile. 

Je préfère également voir toutes les transitions dans une table plutôt que de regarder à travers les rouages ​​internes de chaque état. L’auteur a raison de dire que l’ajout d’un état est plus facile, mais très minime, avec des statistiques superposées, par exemple, je n’ai qu’à ajouter l’état à la liste de ses états parents, c’est la seule différence réelle. 

J'utilise le modèle d'état dans les cas où la vitesse n'est pas un problème et où la hiérarchie de la machine à états restera probablement inchangée. L’auteur a raison de dire que la mise en oeuvre initiale est généralement plus facile avec le modèle d’état par rapport à une machine à états et que, généralement, davantage de programmeurs devraient utiliser plus de machines à états. 

Un argument pour le modèle d'état est qu'il permet l'implémentation de machines d'état "Open Closed" où une machine d'état peut être définie dans une bibliothèque puis développée par l'utilisateur, ceci n'est pas possible pour autant que je sache avec la machine d'état traditionnelle cadres. 

17
odinthenerd

Une machine à états peut être conçue et implémentée de plusieurs manières. Une solution consiste à utiliser le modèle d'état décrit dans le livre du Gang of Four. Mais il existe d'autres modèles pour implémenter une machine à états. 

Par exemple, vous voudrez peut-être jeter un coup d’œil sur les recherches de Miro Samek en lisant le livre Statecharts UML pratiques en C/C++, 2e éd. (Programmation événementielle pour les systèmes embarqués)

Vous pouvez également trouver intéressant cette question .

9
Claudio

une machine à états est simplement le modèle d'état au travail ou s'il y a une différence entre ces deux

TL; DR: Imaginez que vous deviez remplacer un état par un autre. Ensuite, imaginez que vous deviez ajouter un nouvel état.

Réponse complète. Il y a une grosse différence. 

Le modèle d'état abstrait les états et les dissocie les uns des autres. Ainsi, par exemple, vous pouvez facilement remplacer un état particulier par un autre. Pourtant, vous ne serez pas heureux de réécrire tous les états quand il sera temps d’en ajouter un nouveau et/ou une nouvelle transition.

La machine à états extrait le diagramme d'états lui-même et le dissocie des données utiles de la transition. Pour changer un état particulier, vous devez corriger tout le diagramme. Mais pour ajouter un état ou une transition, il vous suffit de corriger le diagramme. 

1

Au cas où quelqu'un serait toujours intéressé, voici mon avis:

Dans la machine à états, l'objet peut se trouver dans différents états, mais nous ne nous soucions pas vraiment comment ils se comportent dans ces états. En fait, nous ne nous soucions que de l'action à appliquer lorsque l'objet passe à l'état suivant. Si vous implémentez une machine à états en Java, un état sera simplement une énumération ou une chaîne et il y aura une classe de transition avec la méthode doAction ().

D'autre part, dans le modèle d'état, vous ne vous souciez pas vraiment de la transition, mais du comportement de l'objet dans ces états. La transition est juste un détail d'implémentation pour rendre vos comportements d'état découplés les uns des autres. Chaque état sera une classe séparée, ayant sa propre méthode doAction ().

Dire que le modèle d'état rend la machine d'état obsolète est incorrect. Le modèle d'état sera utile si le comportement de chaque état est important, par exemple dans la programmation de jeux, où un objet peut avoir des états tels que "inactif", "attaque", "courir" et dans chaque état, vous souhaitez implémenter le comportement de l'objet. .

Mais pour les cas d'utilisation comme la commande de produits en ligne, où vous ne vous souciez pas du comportement de l'objet de la commande. Vous ne vous souciez que si la commande est dans l'état "added_to_cart", lorsqu'un événement "payment_finished" est publié, puis modifiez-le en état "processing". Dans ce cas, state est une simple propriété enum de la classe Order. Il est donc préférable d'utiliser machine à états.

1
Bùi Anh Dũng

Je remarque une différence avec le motif d'état. c'est plus pratique lorsque vous l'utilisez pour l'interface utilisateur. Disons que je voulais verrouiller l'état. Dans le contexte de motif d'état, je pourrais créer un booléen et empêcher les états de changer davantage. 

voici un exemple Kotlin:

     inner class StateContext : State {

       private var stateContext: State? = null
       private var lockState: Boolean = false

       fun isLockState(): Boolean {
           return lockState
       }

       fun setLockState(lockState: Boolean): StateContext {
           this.lockState = lockState//no further actions allowed. useful if you need to permenatley lock out the user from changing state.
           return this
       }

       fun getState(): State? {
           return this.stateContext
       }

       fun setState(state: State): StateContext {
           if (!lockState) this.stateContext = state
           return this
       }

       override fun doAction() {
           this.stateContext?.doAction()
       }
   }

avec la machine d'état, je ne sais pas comment cela se ferait facilement. 

j'aime beaucoup la machine d'état lorsque je m'inquiète uniquement pour l'état (sauvegarde de l'état actuel, par exemple), et non pour le détail de la mise en œuvre (modification de la couleur des boutons de l'interface utilisateur, par exemple). Ce qui est bien avec la machine à états, c’est que vous pouvez avoir un emplacement central pour enregistrer les changements d’état. J'ai vu cette bibliothèque pour Kotlin par Tinder qui a l'air intéressant. mais personnellement, je pense que vous pourriez tous les changer pour faire ce que vous voulez, juste plus propre d'une manière ou d'une autre. 

0
j2emanue