jeudi 3 septembre 2020

State machine design pattern

TLDR: Are there any known design pattern to represent a state machine configuration as code without the usage of goto statements?

What are the possible issues with refactoring:

{
   a: {
      title: 'Step A',
      onActionXGoTo: 'b',
      onActionYGoTo: 'c',
   },
   b: {
      title: 'Step B',
      onAnyActionGoTo: 'c',
   }
   c: {
      title: 'Step C',
      onActionXGoTo: 'a',
      onActionYGoTo: 'b',
   }
}

as something like the example below. Where buildGraph will return the object above

buildGraph((builder) => {
     builder.while(() => {
        if (builder.initial() {
            builder.setStep({ title: 'Step A'});
        } else {
           if (builder.isActionX()) {
              builder.setStep({ title: 'Step A'});
           }
           if (builder.isActionY()) {
              builder.setStep({ title: 'Step B'});
           }
        }
        
        if (builder.isActionX()) {
           builder.setStep({ title: 'Step B'});
           builder.setStep({ title: 'Step C'});
        }
        if (builder.isActionY()) {
           builder.setStep({ title: 'Step C'});
        }
    });
});

This use case might not make sense as it's harder to follow. However, we've got a state machine with hundreds of connections which is challenging to maintain.

  1. Are there any design patterns that can help with that?
  2. The spec for the state machine is given by UX/Product as goto statements. Converting goto statements to sequential code might now worth the effort because of increased complexity when implementing a new state machine. Am I missing something?
  3. Are there any caveats with that type of sequential code to state machine conversion? On the surface it might appear as compiling code to custom machine code but I think the difference here is that it is a finite state machine not code.

Aucun commentaire:

Enregistrer un commentaire