Реализовать конечный автомат в ЕС6


Я построил простой конечный автомат, который моделирует еще проще фиктивной системой банковского счета.

Любой счет может быть в одном из трех состояний в любое время: открытые, закрытые, или провел.

У меня есть несколько разных методов, что переход из одного состояния в другое:

  • бередить: закрыта -> открыта
  • рядом : открыть / проведен -> закрыл
  • place_hold : открыть -> провел
  • remove_hold : пройдет -> открыть

Я использовал ЕС6 класс и прототипы для реализации этого. три разные объекты, каждый со своими методами, намерены быть __proto__ в любой момент BankAccount объект.

Проблема в том, что изменение __proto__ объекта удаляет его способность называть своего класса методов, что является проблемой.

Вот урезанная версия мой код:

const open ={stateName:"Open",
  close: function(){
    this.changeState(closed);
  },
  reopen: function(){
    return;
  },
  place_hold: function(){
    this.changeState(held);
  },
  remove_hold: function(){
    return;
  }
}

const held ={stateName:"Held",
  close: function(){
    this.changeState(closed);
  },
  reopen: function(){
    return;
  },
  place_hold: function(){
    return;
  },
  remove_hold: function(){
    this.changeState(open);
  }
}

const closed ={stateName:"Closed",
  close: function(){
    return;
  },
  reopen: function(){
    this.changeState(open);
  },
  place_hold: function(){
    return;
  },
  remove_hold: function(){
    return;
  }
}

class BankAccount {
  constructor() {
    this.balance = 0;
    this.__proto__ = open;
    this.changeState = state=>this.__proto__ = state;
  }
  otherStuff(){
    // this cannot be called...
  }
}

Что бы быть более правильный способ сделать это, сохраняя наши аккаунты в состоянии получить доступ к методам класса, а также синтаксис, используемый, чтобы получить доступ к методам осуществляется через государственную машину?



Комментарии
1 ответ

Свойства объекта.

При перезаписи прототипа вы потеряете существующих свойств.

Есть и другие решения, используя синтаксис класса, но важно отметить следующее.


JavaScript-классы, ввел в ECMAScript 2015, в первую очередь
синтаксический сахар поверх существующих прототипов в JavaScript
наследство. Синтаксис класса не вводит новой объектно-ориентированной
модель наследования в JavaScript.

от МДН классов

Используя class есть какие-то существенные проблемы, и на мой взгляд, следует избегать, так-же и лучше можно сделать, используя стандартный синтаксис для объектов.

Слово на код.


  • Вы не должны добавить возвращение к функции. Его автомат.

  • Используйте функцию стенографии при добавлении функций к объектам.

  • Не смешивайте стили именования. У вас есть snake_case и верблюжьего.

Применить это к


const held ={stateName:"Held",
close: function(){
this.changeState(closed);
},
reopen: function(){
return;
},
place_hold: function(){
return;
},
remove_hold: function(){
this.changeState(open);
}
}

Становится

const held = {
stateName: "Held",
close() { // function shorthand
this.changeState(closed);
},
reopen() {}, // return implied Same as return undefined;
placeHold() {}, // camelCase
removeHold() {
this.changeState(open);
}
}; // objects have semicolons..

Свойства объекта.

При создании объектов с динамическими свойствами можно назначать свойства напрямую к объекту, используя Object.assign(obj, properties) Это имеет некоторые эксплуатационные преимущества, а также.

Ниже приводится пример счета instanceable государственная машина, используя объект назначения назначение государства.

const Account = (() => {
const actions = {
close() { this.transition(states.closed) },
hold() { this.transition(states.held) },
open() { this.transition(states.open) },
};
const nulls = {close(){ }, hold(){ }, open(){ }};
const states = {
open : {
state: "Open",
close: actions.close,
hold: actions.hold,
},
held : {
state: "Held",
close: actions.close,
open: actions.open,
},
closed : {
state: "Closed",
open: actions.open,
}
};
return function(){
const account = {
...states.closed, // default State
balance : 0,
transition(state) { Object.assign(account, nulls, state) },
statement() { console.log(account) },
};
return account;
};
})();

Использовать

const foo = Account(); 
// or
const foo = new Account();

foo.close();
foo.open();
foo.hold();
foo.statement();

2
ответ дан 28 февраля 2018 в 10:02 Источник Поделиться