Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DDD by Functional programming with TypeScript

DDD by Functional programming with TypeScript

Gunma.web#30のLTスライドです。
勘違いがあればどうかご指摘ください。

参考
https://qiita.com/nunulk/items/7447e6dadae29a41af3d

Childhooooo

January 20, 2018
Tweet

More Decks by Childhooooo

Other Decks in Programming

Transcript

  1. ࠶୅ೖʹΑΔࢀরಁաੑͷഁյ > var x = 1 undefined > x =

    2 2 > x 2 > const y = 1 undefined > y = 2 TypeError Broken!
  2. ؔ਺ͷ෭࡞༻ʹΑΔࢀরಁաੑͷഁյ > var counter = 0 undefined > const count

    = (x) => counter += x undefined > count(3) 3 > count(3) 6
  3. ؔ਺ͷ෭࡞༻ʹΑΔࢀরಁաੑͷഁյ > var counter = 0 undefined > const count

    = (x) => counter += x undefined > count(3) 3 > count(3) 6 Broken!
  4. ΤϯςΟςΟʢؔ਺ܕϓϩάϥϛϯάʣ class Account { constructor(public id: UserID, public balance: Balance)

    { Object.freeze(this); } debit(amount: number):Balance { if(this.balance.amount < amount) { return [“error”, “This is an error message.”]; } else { return [“success”, ɹnew Account(this.id, new Balance(this.balance.amount - amount))]; } } credit(amount: number):Balance { return [“success”, new Account(this.id, new Balance(this.balance.amount + amount))]; } }
  5. ஋ΦϒδΣΫτ class Balance { constructor(public amount: number = 0) {

    Object.freeze(this); } } const balance = new Balance(100); balance.amount = 50 //error
  6. ΤϯςΟςΟʢҰൠతͳΦϒδΣΫτࢦ޲ʣ class Account { constructor(public id: UserID, public balance: Balance)

    {} debit(amount: number):string { if(this.balance.amount < amount) {
 return “error”; } else { this.balance = new Balance(this.balance.amount - amount); return “success”; } } credit(amount: number):string { this.balance = new Balance(this.balance.amount + amount); return “success”; } }
  7. ΤϯςΟςΟΛ࢖͏ʢҰൠతͳΦϒδΣΫτࢦ޲ʣ let account = new Account(“A”, new Balance(200)); console.log(account.balance.amount); //200

    result = account.debit(100); console.log(result, account.balance.amount); //“success” 100 Broken!
  8. ΤϯςΟςΟʢؔ਺ܕϓϩάϥϛϯάʣ class Account { constructor(public id: UserID, public balance: Balance)

    { Object.freeze(this); } debit(amount: number):Account { if(this.balance.amount < amount) { return [“error”, “This is an error message.”]; } else { return [“success”, ɹnew Account(this.id, new Balance(this.balance.amount - amount))]; } } credit(amount: number):Account { return [“success”, new Account(this.id, new Balance(this.balance.amount + amount))]; } }
  9. ΤϯςΟςΟΛ࢖͏ʢؔ਺ܕϓϩάϥϛϯάʣ const pattern = require(“matches”).pattern; //matches.js const account = new

    Account(new UserID(1), new Balance(200)); const operated = account.debit(100); pattern({ ‘[“success”, a@Account ]’: (a) => console.log(a.balance.amount), ‘[“error”, message ]’: (message) => console.log(message) })(operated); //100
  10. αʔϏε const transfer = (from: Account, to: Account, amount: number)

    => { const [res, debited] = from.debit(amount); return if_success([res, debited, …to.credit(amount)], ([a, credited]) => [“success”, a, credited[1]]); }
  11. αʔϏεΛ࢖͏ const pattern = require(“matches”).pattern; //matches.js const from = new

    Account(new UserID(1), new Balance(500)); const to = new Account(new UserID(2), new Balance(300)); const transferred = transfer(from, to, 300); pattern({ ‘[“success”, f, _]’: (f) => console.log(f.balance.amount), ‘[“error”, message]’: (message) => console.log(message) })(transferred); //200
  12. ҰൠతͳΦϒδΣΫτࢦ޲ͷ৔߹ > const account = new Account(new UserID(5)) undefined //ҎԼɺ࢒ߴΛฦؔ͢਺showBalance(account)͕ఆٛͯ͋͠Δͱ͢Δɻ

    > showBalance(account) 0 > account.credit(200) undefined > account.debit(100) undefined > account.debit(50) undefined > showBalance(account) 50
  13. ҰൠతͳΦϒδΣΫτࢦ޲ͷ৔߹ > const account = new Account(new UserID(5)) undefined //ҎԼɺ࢒ߴΛฦؔ͢਺showBalance(account)͕ఆٛͯ͋͠Δͱ͢Δɻ

    > showBalance(account) 0 > account.credit(200) undefined > account.debit(100) undefined > account.debit(50) undefined > showBalance(account) 50 Broken!
  14. ؔ਺ܕͰී௨ʹ΍ͬͯΈΔ > const a0 = new Account(new UserID(5)) undefined >

    showBalance(a0) 0 > const a1 = a0.credit(200) undefined > const a2 = a1.debit(100) undefined > const a3 = a2.debit(50) undefined > showBalance(a3) 50
  15. ؔ਺ܕͰී௨ʹ΍ͬͯΈΔ > const a0 = new Account(new UserID(5)) undefined >

    showBalance(a0) 0 > const a1 = a0.credit(200) undefined > const a2 = a1.debit(100) undefined > const a3 = a2.debit(50) undefined > showBalance(a3) 50 ຊ౰ʹ͜ΕͰ͍͍ͷʁ
  16. ؔ਺ܕͰී௨ʹ΍ͬͯΈΔ > const a0 = new Account(new UserID(5)) undefined >

    showBalance(a0) 0 > const a1 = a0.credit(200) undefined > const a2 = a1.debit(100) undefined > const a3 = a2.debit(50) undefined > showBalance(a3) 50 ݁ہɺBɾBͱ͍ͬͨঢ়ଶΛ͍࣋ͬͯΔ
  17. ͦΕͳΒͬͪ͜ͷ΄͏͕Θ͔Γ΍͍͢ > const account = new Account(new UserID(5)) undefined >

    showBalance(account) 0 > account.credit(200) undefined > account.debit(100) undefined > account.debit(50) undefined > showBalance(account) 50
  18. ͦΕͳΒͬͪ͜ͷ΄͏͕Θ͔Γ΍͍͢ > const account = new Account(new UserID(5)) undefined >

    showBalance(account) 0 > account.credit(200) undefined > account.debit(100) undefined > account.debit(50) undefined > showBalance(account)() 50 Ͱ΋ɺͲ͏΍ͬͯࢀর౳ՁੑΛอͭͷ͔
  19. ͜Μͳͷ͸Ͳ͏͔ > const account = new Account(new UserID(5)) undefined >

    showBalance(account, “Կ΋͍ͯ͠ͳ͍”) 0 > showBalance(account, “200आΓͯɺ100ିͯ͠ɺ50ିͨ͠”) 50
  20. ͜Μͳͷ͸Ͳ͏͔ > const account = new Account(new UserID(5)) undefined >

    showBalance(account, “Կ΋͍ͯ͠ͳ͍”) 0 > showBalance(account, “200आΓͯɺ100ିͯ͠ɺ50ିͨ͠”) 50 ঢ়ଶΛ໌ࣔతʹ౉͢
  21. ͜Μͳͷ͸Ͳ͏͔ > const account = new Account(new UserID(5)) undefined >

    showBalance(account, “Կ΋͍ͯ͠ͳ͍”) 0 > showBalance(account, “200आΓͯɺ100ିͯ͠ɺ50ିͨ͠”) 50 Ҿ਺͕ҧ͏ͷͰɺࢀর౳Ձੑ͕อͨΕͨʂ ঢ়ଶΛ໌ࣔతʹ౉͢
  22. 4UBUFϞφυ > const account = new Account(new UserID(5)) undefined >

    const state = new State(“200आΓͯɺ100ିͯ͠ɺ50ିͨ͠”) undefined > showBalance(state.runState(account)) 50 ʂ ͜Ε͸งғؾΛઆ໌͢Δ΋ͷͳͷͰɺ·ͬͨ͘΋ͬͯ ਖ਼֬ͳίʔυͰ͸͋Γ·ͤΜ