12
votes

Comment voudriez-vous coder une machine à laver?

Imaginez que j'ai une classe qui représente une simple machine à laver. Il peut effectuer des opérations suivantes dans l'ordre suivant: Activer -> Lavage -> Centrifuge -> Éteindre . Je vois deux alternatives de base:

  1. Je peux avoir une classe de lavage de la classe avec des méthodes Turnon (), lavage (minutes int), centrifugeuse (INT REVS), désinscription (). Le problème avec ceci est que l'interface dit rien sur le bon ordre des opérations. Je peux au mieux lancer InvalidoPratationException si le client essaie de centrifuger avant que la machine soit allumée. Je peux également utiliser une classe de programme séparée qui passera à la centrifugeuse et laver les minutes à la machine à laver et simplifiera ces méthodes.

  2. Je peux laisser la classe elle-même s'occuper des transitions correctes et avoir la méthode unique suivante () . Le problème avec cela, d'autre part, est que la sémantique est médiocre. Le client ne saura pas ce qui va se passer quand il appelle la suivante (). Imaginez que vous implémentiez l'événement de clic du bouton de centrifuge afin qu'il appelle la suivante (). L'utilisateur appuie sur le bouton centrifuge après que la machine a été allumée et ups! la machine commence à se laver. J'aurai probablement besoin de quelques propriétés sur ma classe pour paramétrer les opérations, ou peut-être une classe de programme distincte avec des champs de longueur de la longueur de la longueur et de centrifuge, mais ce n'est pas vraiment le problème.

    Quelle alternative est meilleure? Ou peut-être qu'il y a d'autres alternatives, de meilleures alternatives que j'ai manquées de décrire?


3 commentaires

"Imaginez que vous mettez en œuvre l'événement de clic du bouton de centrifuge." Pourquoi l'utilisateur déciderait-il jamais ce qui se passe avec la centrifugeuse? Je ne dis certainement jamais à ma machine à laver comment faire ses affaires ...


@ harschaware Imagine que ce capteur de niveau d'eau envoie un signal "chargé" ou cet utilisateur appuie sur le bouton "Ouvrir la porte" à tout moment de fonctionnement.


Oui, mais un utilisateur ne ferait pas tourner la centrifugeuse. L'utilisateur peut se tourner vers le cycle d'essorage et exécuter, à quel point la machine d'état déciderait s'il s'agit d'une demande valide pour l'état donné. La centrifugeuse est une opération mécanique utilisée par le FSM et le cycle de rotation serait une entrée de l'utilisateur.


10 Réponses :


0
votes

Le premier est exactement ce que je ferais. laver et Centrifuge vérifierait le drapeau qui suit si la machine est allumée et lancez une exception si ce n'est pas le cas, mais il n'y a pas d'ordre d'exploitation obligatoire; Vous pouvez appeler Centrifuge avant WASH si vous avez vraiment senti le besoin


0 commentaires

0
votes

erm, un peu bizarre mais voilà;

Je regarderais même des délégués. Donc, pour un type de cycle de lavage particulier, un soulèvement, une lumière, des Studdsy, économique, etc. J'aurais une interface pour chacun.

Puis, avec l'utilisation de génériques, je créerais le type de lavage approprié que je veux.

Le type de lavage aurait alors un événement de lavage qui déléguette, dans l'ordre, les cycles à exécuter.


0 commentaires

5
votes

Je pense que Turnon () , Wash () , centerfuge () etc. devrait être des méthodes privées / protégées. L'interface publique doit être Dothewash (mode WASHMODE) . La machine à laver elle-même connaît les modes qu'il prend en charge et comment les faire fonctionner, l'utilisateur de la machine à laver ne doit pas nécessairement s'impliquer dans la commande ou la durée des opérations. Il est raisonnable de s'attendre à ce que l'auteur de la classe de machine à laver appelle les méthodes privées dans un ordre sensible.


0 commentaires

0
votes

La machine à laver doit savoir comment exécuter correctement une charge. Peut-être avant de laver une charge, certains éléments de configuration devraient être définis (avec des valeurs par défaut, si non défini), comme quel type de charge (lumières vs sombre) ou taille (petit, moyen, grand). L'utilisateur (une autre classe) doit savoir comment configurer correctement une charge à exécuter, mais pour laver une charge, le lave-linge doit seulement expirer une méthode, quelque chose comme washload . En interne, il gérerait ce qui doit être appelé quand laver une charge de blanchisserie.

Alternativement, vous pouvez toujours exposer les fonctions publiques pour transformer la laveuse sur et éteindre, puis si washload a été appelé lorsque la rondelle était éteinte, il serait approprié de jeter une exception. En outre, dans ce scénario, je ferais probablement les paramètres de la laveuse définie via une méthode unique setOchartOPtions qui prendrait une autre classe, ce serait quelque chose comme loadoptions et défini toutes les caractéristiques vous vouliez configurable. Je voudrais également jeter une exception si la laveuse n'était pas allumée.


0 commentaires

15
votes

J'aurais un "Code" de haut niveau ' Machine d'état qui contrôle l'entrée / la sortie / sortie de chaque état (où les états pourraient être des choses comme "remplissage", "lavage", "Rinçage", " ',' Vider ',' Spin Sèche ', etc.)

établir un diagramme de transition d'état de tous les états dont vous avez besoin, y compris (pour chaque état )

  1. Quelles exigences il y a avant de saisir l'état (Conditions d'entrée)
  2. Ce qui doit arriver lorsque vous entrez dans l'état (Actions d'entrée)
  3. Que se passe-t-il pendant l'état (la tâche elle-même)
  4. Quelles exigences il y a avant de pouvoir quitter l'état (conditions de sortie)
  5. Que se passe-t-il lorsque vous quittez l'état (EXIT ACTIONS)

    Vous pouvez ou non besoin de conditions d'entrée / de sortie (par exemple, vous pouvez forcer les conditions avec une action d'entrée / sortie dans certains cas). Pour des raisons de sécurité, certaines conditions peuvent être bonnes (par exemple sortant d'un état de «veille» ou d'une entrée dans un état «dangereux» comme Spin Sèche)

    Vous créez également transitions , qui définissent les liens entre les états. Une transition a

    1. A 'de l'état'
    2. a 'to' State
    3. Conditions de transition (la transition peut-elle se produire?
    4. Actions de transition (ce qui doit se produire lorsque vous transition)

      Encore une fois, vous n'avez peut-être pas besoin de tous, et de nombreuses transitions n'auront que les états «de» et «à» spécifiés.

      Dans les deux cas, essayez de conserver chaque état et transition aussi simple que celui que a besoin être (essayer de mettre les conditions / actions Là où ils ont le plus de sens, il y a évidemment un double potentiel de ceux-ci à définir dans un état et a transition en raison de la conception générique )

      Il devrait être assez évident à ce stade que vous pouvez créer une classe d'état assez générique qui inclut des fonctions abstraites / surchargées pour toutes ces choses, et également pour la transition classe. La classe d'état peut appeler chacune de ces fonctions de membre selon les besoins, en fonction des transitions demandées.

      Si vous le faites particulièrement génériques, les états et transitions peuvent être enregistrés avec la machine d'état au temps de construction, ou vous pourriez Il suffit de coder la machine d'état pour les contenir tous.

      Vous pouvez ensuite demander des transitions, soit à partir de dans les états (c'est-à-dire qu'un état particulier peut savoir quand il est terminé, et sachez quel état passer à la suivante) ou vous pourriez avoir une classe externe qui contrôle Les transitions de l'état (chaque état est alors très simple, de manière purement prise en charge de ses propres actions, et la classe externe décide de la commande et du calendrier des transitions).

      Dans mon expérience avec ces choses, il est judicieux de séparer la logique de haut niveau d'ordre / chronométrage délibéré de chaque action et de la logique de réaction de faible niveau à certains événements matériels (par exemple, la transition de l'état "remplissage" lorsque Le niveau d'eau est atteint).

      C'est un design vraiment générique cependant, et vous pouvez obtenir exactement la même fonctionnalité un tas de différentes manières - il y a rarement un simple droite moyen de faire les choses .. .


2 commentaires

Je pense que c'est une bonne réponse! J'ajouterais que je trouve utile de penser à l'interface utilisateur courante dans un fil et la machine à laver états / transitions / travaux fonctionnant dans un autre. En outre, on pourrait utiliser vos états comme des nœuds et transitions comme des bords (plutôt que d'avoir la transition de la transition «de» et de «à» état) dans une structure graphique. Cela permettrait aux choses comme énumérer les états «à» pour un nœud donné. J'aime utiliser Jung pour les structures graphiques.


Oui, les nœuds / bords sont fondamentalement la même idée, comme je l'ai dit que la conception est assez générique, de sorte que les transitions ont «de» et «à» états, ou si des États ont une liste de transitions disponibles n'est pas trop importante, il y a un beaucoup de moyens ceux-ci peuvent être mis en œuvre



0
votes

sur ma machine à laver, vous avez accès à deux boutons. Je suis un peu confus quant à ce que les limitations sont dans votre cas.

  1. Taille de la charge (petite, moyenne, grande)
  2. Bouton de cycle (presse, presse, tricots et délicates, régulier)
    • Chaque cycle contient différentes "phases" aueses qui peuvent être activées à

      lorsque vous "activez" un cycle (en tournant le bouton), la machine commencera à fonctionner si vous le tournez au milieu ou au début d'un cycle.

      Voici un vraiment , Exemple vraiment de base de la façon dont je vais traduire cela en une classe: xxx


0 commentaires

0
votes

Dernièrement, je vais fonctionnel et en utilisant des objets immuables avec Martin Fowler / JQuery enchaînant fluent style .

  • J'utilise le système de type autant que possible car il fait refactoring.
  • Avec ma méthode, le compilateur vous obligera à le faire correctement.
  • Parce que les objets sont quelque peu immuables, il est plus facile de prouver que cette machine d'état est déterministe.

    code: xxx


3 commentaires

Bien que ce soit bien, cela ne modifie pas vraiment le comportement réel d'une machine à laver. L'utilisateur (sur la plupart des modèles) ne peut généralement pas choisir la commande et la longueur des états, bien qu'ils puissent généralement choisir entre plusieurs modèles de cycle. Bien que je suppose que votre Examplerun pourrait être un modèle de cycle choisi.


@MYSTERE Man Le point est que les états sont des objets immuables et seuls les états savent quel est l'état suivant. Je suis à peu près sûr pour une rondelle que vous pourriez obtenir cela pour travailler.


rien contre le motif et le code, ça a vraiment l'air bien! Et l'OP a demandé une solution pour une simple machine à états. Juste pour le monde réel - Les machines modernes varient du programme, par exemple sur la base de la mesure de la qualité de l'eau usée - comme: si elle est sale, lavez à nouveau. Cela introduirait des conditions et des succursales.



1
votes

La plupart des machines à laver les plus occidentales utilisent une minuterie pour passer du cycle au cycle. Cette minuterie peut être considérée comme une machine d'état. Cependant, il est important de réaliser qu'une machine d'incendie se déroule, pas l'utilisateur. L'utilisateur définit le mode initial, puis sur son entreprise.

Si de manière interne, vous pouvez avoir des fonctions de lavage, de rinçage, de spin, l'interface réelle serait la création () et le début () et l'arrêt (). Vous pouvez également avoir des propriétés supplémentaires, telles que le niveau d'eau, la vitesse d'agitation, la température de l'eau, etc.

Démarrage provoque le temps d'avancer, lequel après une période de temps entre dans l'état suivant, jusqu'à ce qu'il soit finalement complet.


0 commentaires

0
votes

L'option A est comme une laveuse manuelle tandis que l'option B est comme une laveuse automatique. Les deux options sont utiles à leurs utilisateurs ciblant:

Un utilisateur d'option A peut profiter de la programmation manuelle de l'ensemble du processus (comme doubler le cercle de lavage ou enseigner le petit que si vous éteignez la machine pendant que c'est dans le cercle de centrifugation).

Un utilisateur d'option B peut profiter de la simplicité et écrire une série de séries factices - apprendre à votre auto lavage en 21 secondes: -)


0 commentaires

1
votes

Chaque machine à laver a un contrôleur et un programme . Pour les machines plus anciennes et simples, le programme et le contrôleur sont intégrés à un bouton plutôt compliqué, des machines modernes et plus chères ont un ordinateur.

Dans les deux cas, la machine a des sous-systèmes supplémentaires et le contrôleur notifie les sous-systèmes pour effectuer une action, comme verrouiller la porte , Eau thermique jusqu'à 40 ° C ou tourner le tambour .

Le contrôleur lui-même connaît la séquence, qui est jolie linéaire et la minuterie basée sur des machines anciennes ou complexes pour les systèmes modernes qui varient en fonction de la séquence des données du capteur. Mais dans les deux cas, il exécute une série de commandes pouvant notifier des capteurs et des acteurs.

Si vous regardez le système de lavage de ce point de vue, vous pouvez utiliser la commande commande à l'intérieur du contrôleur pour modéliser le programme de lavage et de l'observateur Motif de notification des sous-systèmes (comme: le commutateur de porte écoute le contrôleur pour un signal pour verrouiller la porte ).


0 commentaires