Last active
February 27, 2018 09:45
-
-
Save aynik/27a48644b813e8aa15be27d77644964d to your computer and use it in GitHub Desktop.
A prototype switching state machine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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') | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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