Skip to content

Instantly share code, notes, and snippets.

@aynik
Last active February 27, 2018 09:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aynik/27a48644b813e8aa15be27d77644964d to your computer and use it in GitHub Desktop.
Save aynik/27a48644b813e8aa15be27d77644964d to your computer and use it in GitHub Desktop.
A prototype switching state machine
import StateMachine from './StateMachine'
class Account extends StateMachine {
constructor (initialState, initialBalance = 0) {
super(initialState)
this.balance = initialBalance
}
static get openStateMethods () {
return {
deposit (amount) {
return this.balance += amount
},
withdraw (amount) {
return this.balance -= amount
},
placeHold () {
return this.to('held')
},
close () {
if (this.balance > 0) {
// transfer balance to suspension account
}
return this.to('closed')
}
}
}
static get heldStateMethods () {
return {
removeHold () {
return this.to('open')
},
deposit (amount) {
return this.balance += amount
},
close () {
if (this.balance > 0) {
// transfer balance to suspension account
}
return this.to('closed')
}
}
}
static get closedStateMethods () {
return {
reopen () {
// restore balance if applicable
return this.to('open')
}
}
}
}
export default class StateMachine {
constructor (initialState) {
this.to(initialState)
}
static setStateMethods (self) {
self.__proto__ = Object.assign({
constructor: self.constructor, to: self.to
}, self.constructor[self.state + 'StateMethods'])
}
static unsetStateMethods (self) {
self.__proto__ = Object.assign({
constructor: self.constructor, to: self.to
}, self.constructor.prototype)
}
to (state, value) {
this.constructor.unsetStateMethods(this)
this.state = state
this.constructor.setStateMethods(this)
return value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment