Last active
August 29, 2015 14:19
-
-
Save haru01/06c6b53a279f0d6ce9ed to your computer and use it in GitHub Desktop.
Event 中心に
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
// 学習用 | |
// * See Also http://ookami86.github.io/event-sourcing-in-practice/#how-eventsourcing-works/04-restoring-objects-5.md | |
// * http://martinfowler.com/eaaDev/EventSourcing.html | |
// | |
function BanckingAccount(id, owner, balance, version) { | |
this.id = id || 0; | |
this.owner = owner || ""; | |
this.balance = balance || 0; | |
this.version = version || 0; | |
} | |
BanckingAccount.prototype.applyAll = function(evnts) { | |
var result = this; | |
for (var i = 0; i < events.length; i++) { | |
result = result.applyTo(events[i]); | |
//console.log(result); | |
} | |
return result; | |
} | |
BanckingAccount.prototype.applyTo = function(evnt) { | |
return evnt.process(this); | |
} | |
function BanckingAccountCreated(accountId, owner, version) { | |
this.accountId = accountId; | |
this.owner = owner; | |
this.version = version; | |
} | |
// id を持っているけど、 Immutable & Side effect free スタイルで書いてみたが。。。 | |
BanckingAccountCreated.prototype.process = function(account) { | |
if (this.version <= account.version ) { | |
return account; | |
} | |
// 初回であること | |
return new BanckingAccount(this.accountId, this.owner, account.balance, this.version); | |
} | |
function DepositPerformed(accountId, amount, version) { | |
this.accountId = accountId; | |
this.amount = amount; | |
this.version = version; | |
} | |
DepositPerformed.prototype.process = function(account) { | |
if (this.version <= account.version ) { | |
return account; | |
} | |
// idが一致すること | |
// create後であること | |
return new BanckingAccount(this.accountId, account.owner, account.balance + this.amount, this.version); | |
} | |
function WithdrawalPerformed(accountId, amount, version) { | |
this.accountId = accountId; | |
this.amount = amount; | |
this.version = version; | |
} | |
WithdrawalPerformed.prototype.process = function(account) { | |
if (this.version <= account.version ) { | |
return account; | |
} | |
// create後であること | |
// id が一致すること | |
return new BanckingAccount(this.accountId, account.owner, account.balance - this.amount, this.version); | |
} | |
function OwnerChanged(accountId, newOwner, version) { | |
this.accountId = accountId; | |
this.newOwner = newOwner; | |
this.version = version; | |
} | |
OwnerChanged.prototype.process = function(account) { | |
if (this.version <= account.version ) { | |
return account; | |
} | |
// create後であること | |
// id が一致すること | |
return new BanckingAccount(this.accountId, this.newOwner, account.balance, this.version); | |
} | |
// eventsのリスト、replay可能ってことは Rxの可能性?? | |
var events = [new BanckingAccountCreated(1, "eiji", 1), | |
new DepositPerformed(1, 200, 2), | |
new DepositPerformed(1, 50, 3), | |
new WithdrawalPerformed(1, 10, 4), | |
new WithdrawalPerformed(1, 100, 5), | |
new OwnerChanged(1, 'yoshi', 6)]; | |
//----- | |
var account = new BanckingAccount(); | |
account = account.applyAll(events); | |
console.log(account); | |
// => BanckingAccount {id: 1, owner: "yoshi", balance: 140, version: 6, applyAll: function…} | |
console.log("-- start snap---"); | |
var snap = new BanckingAccount().applyTo(events[0]) | |
.applyTo(events[1]) | |
.applyTo(events[2]); // snap; | |
snap = snap.applyAll(events); | |
console.log(snap); | |
// => BanckingAccount {id: 1, owner: "yoshi", balance: 140, version: 6, applyAll: function…} | |
// TODO | |
// ステートフルなBankingAccountにdepositメソッドを用意してイベント発行する版を書く。 | |
// Eventの永続化の機構 | |
// EventSourcingに移行 | |
// Rxで書きなおす。 | |
// CQRS | |
// idの振りかた。たぶんUUIDのほうが扱いやすい | |
// 疑問 | |
// * 通常だと ステートフルなbankingAccountを中心にそえて、 create, depositPerformed, withdrawalPerformed, ownerChangeの | |
// メソッドがあって,ステータス変更後にイベントを発行するだろうけど、 | |
// まずさきにイベントがあって、イベントからステートフルなBankingAccountを復元でも十分オブジェクトモデルが作れるはず。 | |
// * eventsが永続化できれば、必ずしもはbankingAccountは永続化する必要なし?? | |
// * events中心であれば、DBへのアクセスは、INSERTとSELECT中心で、UPDATE, DELETEの出番が殆ど無い?? | |
// * DDD読んでると、events にマーキングしてチェリーピックやrebase -i みたいなことをしたくなるニーズ があるみたいだが?? | |
// * id発行はuuidか? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment