DEV Community

artydev
artydev

Posted on

Decisional tree with State Machine

Dealing with decisional tree using FSM is a breeze.
Here is a simple Loan Checker.

Here are the rules for according a Loan to a person P:

  P.age >= 18
  P.CC  == true  (Credit Card)
Enter fullscreen mode Exit fullscreen mode

The benefits come when you have numerous conditions to test.
You simply have to add new rules, and add the corresponding transitions within the fsm and you are done.

The rules are tested in sequential order.

Again, no view library, you can test it here : LoanRunner

import javascriptStateMachine from "https://cdn.skypack.dev/javascript-state-machine";
const StateMachine = javascriptStateMachine;

let displayPerson = (p) =>
  document.write(`
  <h2>Loan checking for ${p.name}</h2>
  <h3>Age : ${p.age}</h3>
  <h3>CC : ${p.ownCC}</h3>
`);

function Person({ name, age, ownCC }) {
  this.name = name;
  this.age = age;
  this.ownCC = ownCC;
}

let paul = new Person({
  name: "Paul",
  age: 49,
  ownCC: true,
});

// rule 1 : age >= 18
function checkAge(p) {
  if (p.age >= 18) {
    return "ageOK";
  } else {
    return "abort";
  }
}

// rule 2 : ownCC === true
function checkCC(p) {
  if (p.ownCC == true) {
    return "ccOK";
  } else {
    return "abort";
  }
}

const LoanMachine = function (person) {
  let p = person;
  const fsm = new StateMachine({
    transitions: [
      { name: "checkAge", from: "none", to: checkAge(p) },
      { name: "checkCC", from: "ageOK", to: checkCC(p) },
      { name: "okLoan", from: "ccOK", to: "success" },
      { name: "koLoan", from: "abort", to: "rejected" },
    ],
  });
  return fsm;
};

const loanPaul = LoanMachine(paul);
loanPaul.observe({
  onSuccess: () => document.write("<h3 class='resultOk'>Loan accepted</h3>"),
  onRejected: () => document.write("<h3 class='resultKo'>Loan rejected</h3>"),
});

function loanCheck(loanMachine) {
  const allTransitions = loanMachine.allTransitions();
  // transitions run in sequential order 
  // we first check if the transition is possible
  for (let transition of allTransitions) {
    if (loanMachine.can(transition, true)){
      loanMachine[transition]()
    }
  }
}

function loanRunner() {
  displayPerson(paul);
  loanCheck(loanPaul);
}

loanRunner();

Enter fullscreen mode Exit fullscreen mode

Top comments (0)