Last active
March 7, 2019 13:17
-
-
Save mbrowne/52ae253fdee9a300d6273da071f94202 to your computer and use it in GitHub Desktop.
DCI in native Javascript using symbols
This file contains hidden or 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
const addEntry = Symbol('addEntry'), | |
getBalance = Symbol('getBalance'); | |
export default class Account { | |
constructor(ledgers) { | |
const roles = { | |
ledgers: { | |
[addEntry](message, amount) { | |
ledgers.push(new LedgerEntry(message, amount)); | |
}, | |
[getBalance]() { | |
return ledgers.reduce((sum, ledger) => ( | |
sum + ledger.amount | |
), 0); | |
} | |
} | |
}; | |
if (!ledgers) ledgers = []; | |
this.ledgers = ledgers; | |
//role binding | |
Object.assign(ledgers, roles.ledgers); | |
} | |
increaseBalance(amount) { | |
this.ledgers[addEntry]('depositing', amount); | |
} | |
decreaseBalance(amount) { | |
this.ledgers[addEntry]('withdrawing', 0 - amount); | |
} | |
get balance() { | |
return this.ledgers[getBalance](); | |
} | |
} | |
class LedgerEntry { | |
constructor(message, amount) { | |
this.message = message; | |
this.amount = amount; | |
//ledger entries are immutable | |
Object.freeze(this); | |
} | |
} |
This file contains hidden or 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 Account from './Account'; | |
import TransferMoney from './TransferMoney'; | |
const source = new Account(); | |
source.increaseBalance(30); | |
const dest = new Account(); | |
dest.increaseBalance(30); | |
TransferMoney(source, dest, 10); | |
console.log('source balance', source.balance); | |
console.log('destination balance', dest.balance); |
This file contains hidden or 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
const transfer = Symbol('transfer'), | |
withdraw = Symbol('withdraw'), | |
deposit = Symbol('deposit'); | |
export default function TransferMoney(sourceAccount, destinationAccount, amount) { | |
const roles = { | |
banker: { | |
[transfer]() { | |
sourceAccount[withdraw](); | |
destinationAccount[deposit](); | |
} | |
}, | |
sourceAccount: { | |
[withdraw]() { | |
if (this.balance < amount) { | |
throw Error('Insufficient funds'); | |
} | |
this.decreaseBalance(amount); | |
} | |
}, | |
destinationAccount: { | |
[deposit]() { | |
this.increaseBalance(amount); | |
} | |
} | |
}; | |
// Role binding | |
const banker = {}; | |
Object.assign(banker, roles.banker); | |
Object.assign(sourceAccount, roles.sourceAccount); | |
Object.assign(destinationAccount, roles.destinationAccount); | |
// Run the use case | |
banker[transfer](); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment