集約の設計と実装

 集約の設計と実装

933291444e456bfb511a66a2fa9c6929?s=128

かとじゅん

April 16, 2018
Tweet

Transcript

  1. ू໿ͷઃܭͱ࣮૷ ͔ͱ͡ΎΜ(@j5ik2o)

  2. ΞδΣϯμ • ໨త • DDDͷઓज़తύλʔϯͷதͰൺֱతʹॏཁͰ೉ղͰ͋Δɺू໿ ΛͲͷΑ͏ʹઃܭɾ࣮૷͢ΔͱΑ͍͔ɺ஫ҙ఺ͳͲ΋౿·͑ͳ ͕Βղઆ • ΞδΣϯμ •

    ू໿ͱ͸ • ू໿ͷڥք • ࣗಈंमཧళͰͷࣄྫ • ܖ໿ʹΑΔઃܭ(DbC) • ू໿Λ࣮૷͢ΔͨΊͷϧʔϧ(Evans and Vernon) • ·ͱΊ
  3. ू໿ͱ͸ • ϥΠϑαΠΫϧΛڞʹ͢Δɺؔ࿈͕ਂ ͍ෳ਺ͷΦϒδΣΫτΛɺͻͱ͔ͨ· Γͷ”ू໿”ͱͯ͠ѻ͏ • ू໿ΛมߋͷҰ؏ੑΛอূ͢ΔҰͭͷ ୯Ґͱͯ͠ɺଞͷΦϒδΣΫτͷʮڥ քʯΛ໌֬ʹ෼͚Δ •

    ΦϒδΣΫτ͸ଞͷΦϒδΣΫτͱؔ ࿈Λ࣋ͭՄೳੑ͕͋Δ͕ɺෆద੾ͳϩο Ϋ͸ϢʔβϏϦςΟΛ௿Լͤ͞Δɻಉ ͡ߦΛฤू͍ͯ͠ͳ͍ͷʹจॻશମΛ ϩοΫͳͲ͸ϩοΫڝ߹ͷԹচʹͳΔ ू໿
  4. ڥք͸Ͳ͜ʁ • DB͔ΒैۀһΦϒδΣΫτΛ࡟আ͢Δέʔε • ैۀһͱڞʹ໊લɾੜ೥݄೔ɾ৬຿۠෼͸ͳ͘ ͳΔ͕ɺ෦ॺ͸Ͳ͏ͩΖ͏͔ʁ • ෦ॺ͕ैۀһͷڥքʹؔ܎ͳ͍͜ͱ͸ࣗ໌͕ͩɺ ͦͷ൑அج४Λ࿦ཧతʹઆ໌Մೳ͔ʁ •

    ͨͱ͑͹ɺಉ͡෦ॺʹผͷैۀһ͕ॴଐ͍ͯ͠ Δ͔΋͠Εͳ͍ɻͦͷ෦ॺΛ࡟আ͢Δͱผͷै ۀһΦϒδΣΫτ͸࡟আ͞ΕͨࢀরΛ࣋ͭ͜ͱ ʹͳΔɻٯʹ์ஔ͢Ε͹ɺDBʹෆཁͳ෦ॺΛ ͨΊࠐΉ͜ͱʹͳΔ ू໿
  5. ڥքະఆٛʹΑΔ໰୊ • ଘࡏ͢Δෳ਺ͷΦϒδΣΫτ͕ɺ͍ͭ ࡞ΒΕɺ͍ͭͳ͘ͳΔͷ͔ʁ • σʔλΛมߋ͢Δൣғ(τϥϯβΫ γϣϯείʔϓͳͲ)΍σʔλͷҰ؏ੑ Λҡ࣋͢Δϧʔϧ͕ͳ͚Ε͹ͳΒͳ͍ • ڥքະఆٛͷ··ɺDBͷϩοΫػߏ

    Λར༻͢Δ͜ͱ͕Ͱ͖Δ͕ɺͦͷ৔͠ ͷ͗ͷղܾࡦͱݴΘ͟ΔΛಘͳ͍(ѻ ͍Λؒҧ͑Ε͹ϩοΫ͕ڝ߹͢ΔՄೳ ੑ͕͋Δ) • ຊ࣭͸Ϟσϧʹ͋Δɻ͜ΕΒͷ໰୊͸ ڥքΛఆٛ͢Δ͜ͱͰղܾͰ͖Δ ू໿ $BS 5JSFT &OHJOF 5JSFTͱ&OHJOF͸Ұॹʹ ࡞ΔʁͦΕͱ΋ผʑʁফ ͢ͱ͖͸ಉ͡ͳͷʁ λΠϠަ׵ޙʹλΠϠ͕ຊ͔͠ͳ͍ ঢ়ଶ͚ͩͲʜɻͦΕυϝΠϯΦϒδΣ Ϋτ͕յΕ͍ͯΔঢ়ଶͰ͸ʜɻ ंʹऔΓ෇͚ΒΕΔલͳΒ͍͍ͷ͔ʁ // ू໿Λލ͕ΔΑ͏ͳτϥϯβΫγϣϯʁͦΕͱ΋Ұͭͷू໿ͱ͠ ͯѻ͍ͬͯΔͷ͔ʁ def updateCar(car: Car) = { withTranscation { implicit con => updateRecord(car.id, car.tires) updateRecord(car.engine.id, car.engine.typeName) } } // ͋Εʁͬͪ͜͸୯ಠͰߋ৽͢ΔΑ͏ͩɻڥք͕໌ࣔ͞Ε͍ͯͳ͍… def updateEngine(engine: Engine) = { withTranscation { implicit con => updateRecord(engine.id, engine.typeName) } }
  6. ڥքΛͲͷΑ͏ʹఆٛ͢Δͷ͔ • Ϟσϧ಺ʹ͋ΔࢀরΛΧϓηϧԽ͢ΔͨΊͷந৅Խ͕ ඞཁɻؔ࿈͢ΔΦϒδΣΫτ܈Λͻͱ͔ͨ·Γͱ͠ɺ σʔλΛมߋ͢Δ୯Ґͱͯ͠ѻ͏ɻ͜Ε͕ू໿ͷ໾ׂ • ֤ू໿ʹ͸ڥքͱϧʔτ͕͋Δ • ڥք͸ू໿಺෦ʹԿ͕͋Δ͔Λఆٛ͢Δ •

    ϧʔτ͸ू໿ʹؚ·Ε͍ͯΔಛఆͷ1ΤϯςΟςΟ (ϧʔτΤϯςΟςΟ) ू໿ ϧʔτ " # % & $ ڥք
  7. ࣗಈंमཧళ޲͚γεςϜͷྫ • λΠϠͷϩʔςʔγϣϯͷه࿥ ͱɺ֤λΠϠͷ૸ߦڑ཭ͱ઀஍ ໘ͷຎ໣౓߹͍Λ௥੻͢Δ • ࣗಈं͸άϩʔόϧͳಉҰੑΛ ࣋ͭϧʔτΤϯςΟςΟɻࣝผ ࢠʹ͸ं྆൪߸Λར༻͢Δ •

    λΠϠ͸ࣗಈं͔Β཭ΕΔͱಉ ҰੑΛؾʹ͠ͳͯ͘Α͍ɻަ ׵͞Εͨݹ͍λΠϠ͸௥੻Λࢭ ΊΔ͔ɺͨͩͷ஋ΦϒδΣΫτ ͱͯ͠ࡏݿΛ؅ཧ͢Ε͹Α͍ ڥք ࣗಈं λΠϠ λΠϠ λΠϠ λΠϠ ू໿
  8. FYI: ΦϒδΣΫτΛḷΔೋͭͷํ๏ • ಛఆͷλΠϠΛ୳͢৔߹͸ɺ ·ͣࣗಈंΛಛఆ͔ͯ͠Βɻ ं྆൪߸Λ࢖ͬͯDBʹΫΤϦ Λ͔͚Δ • ͦͷͨΊɺλΠϠ͕ࣗಈंʹ ૷ண͞Ε͍ͯΔؒ΋άϩʔό

    ϧͳಉҰੑ͸ෆཁɻϧʔτΤ ϯςΟςΟ͔ΒࢀরΛḷΔ • ͢΂ͯͷΦϒδΣΫτ͕ू໿ ͩͱɺ੔߹ੑͷҡ࣋؅ཧ͕൥ ࡶԽ͢ΔՄೳੑ͕͋Δ ڥք ࣗಈं λΠϠ λΠϠ λΠϠ λΠϠ %# ΫΤϦ ࢀর ू໿
  9. Ϣʔεέʔε͔ΒڥքΛݟ͚ͭग़͢ • ҰํɺΤϯδϯ͸ಠཱͨ͠ू໿ or ू ໿಺෦ͷΦϒδΣΫτʁ • ࣗಈंͱಠཱͯ͠௥੻͢ΔϢʔεέʔ εͰ͋Ε͹ɺΤϯδϯ͸ಠཱͨ͠ू ໿ͱͳΔɻ

    • ं͕ΤϯδϯΛ಺แ͢Δͱ͍͏ࢥ͍ ࠐΈͱ͸૬൓͢Δ͔΋͠Εͳ͍͕ɺ ϢʔεέʔεΛແࢹͯ͠ϞσϧΛ࡞ Δͱ໾ʹཱͨͳ͍Ϟσϧʹͳͬͯ͠ ·͏ • Ϣʔεέʔε͔ΒϞσϧΛ૑଄͢Δ ͜ͱ͸ඞཁ͕ͩɺϞσϧͷ੔߹ੑ͕ ੒Γཱ͔ͭݕূ΋ඞཁɻ͜Ε͸྆ྠ ڥք ࣗಈं λΠϠ λΠϠ λΠϠ λΠϠ Τϯδϯ ڥք ू໿
  10. Evansϧʔϧ1 • ϧʔτΤϯςΟςΟ͸ɺάϩʔό ϧͳಉҰੑΛ࣋ͪɺෆม৚݅(ͦ ͷϞσϧ͕࣋ͭੑ࣭)ΛνΣοΫ͢ Δ੹຿Λෛ͏ • λΠϠͷަ׵͸ϝιουͳͲΛհ ͯ͠ߦΘΕΔɻܾͯ͠಺෦ͷΦϒ δΣΫτΛ௚઀ૢ࡞ͤͯ͞͸ͳΒ

    ͳ͍(λΠϠϩʔςʔγϣϯϧʔϧ Λڧ੍ͤ͞ΔͳͲͷෆม৚݅Λҡ ࣋͢ΔͨΊʹ) ڥք ࣗಈं λΠϠ λΠϠͷަ׵ λΠϠ λΠϠ λΠϠ ं྆൪߸ λΠϠ ू໿
  11. ෆม৚݅ is Կ?

  12. ԣಓʹҳΕͯ ܖ໿ʹΑΔઃܭ(DbC)

  13. ઌ಄ͷࡾจࣈΛฦ͢ϝιου1 package example object Example1 extends App { def getThree(s:

    String): String = s.substring(0, 3) println(getThree("12345")) } • Ҿ਺ͷจࣈྻ͔Βઌ಄ࡾจࣈΛൈ͖ग़͠ฦ͢ϝιου • ਖ਼͘͠ಈ࡞ͦ͠͏Ͱ͢… 123 %C$
  14. ઌ಄ͷࡾจࣈΛฦ͢ϝιου2 package example object Example1 extends App { def getThree(s:

    String): String = s.substring(0, 3) println(getThree("12")) } • ͜Ε͸αʔϏεଆͷόάͰ͠ΐ͏͔ʁ • ͦΕͱ΋ΫϥΠΞϯτଆͷόάͰ͠ΐ͏͔ʁ Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3 at java.lang.String.substring(String.java:1963) at example.Example1$.getThree(Example1.scala:5) … at scala.collection.immutable.List.foreach(List.scala:389) at scala.App.main(App.scala:76) at scala.App.main$(App.scala:74) at example.Example1$.main(Example1.scala:3) at example.Example1.main(Example1.scala) %C$
  15. ౴͑͸࢓༷ະఆٛ • ౴͑͸ɺ͍͍͑ • ϝιουͷڍಈ͕ਖ਼͍͔ؒ͠ҧ͍ͬͯΔ͔͸͖ͬΓͯ͠ ͍·ͤΜɻ͜ͷέʔεͰ͸࢓༷͕໌֬ʹఆٛ͞Ε͍ͯͳ ͍(࢓༷ະఆٛ) • ίʔυΛಡΊ͹࢓༷͸Θ͔ΔͷͰ͸ʁ %C$

  16. ίʔυ͔Β࢓༷͕Θ͔Βͳ͍ྫ package example case class User(id: Long, name: String, deptId:

    Long) trait UserRepository { def findByDeptId(depId: Long): Option[Seq[User]] } object UserRepository1 extends UserRepository { override def findByDeptId(depId: Long): Option[Seq[User]] = None } object UserRepository2 extends UserRepository { override def findByDeptId(depId: Long): Option[Seq[User]] = Some(Seq.empty) } object Example2 extends App { def printUser(userRepository: UserRepository, deptId: Long) = userRepository.findByDeptId(deptId) match { case None => println("users are empty") case Some(users) => println(s"users = $users") } printUser(UserRepository1, 1) // users are empty printUser(UserRepository2, 1) // users = List() } • ໭Γ஋ΛνΣοΫ͢Δ͚ͩͰ͸ɺਖ਼͠͞͸Θ͔Βͳ͍ ͲͪΒͷ໭Γ஋Λฦ͢ ͷ͕ਖ਼͍͠ʁ %C$ Ұൠతʹɺ࢓༷ΛࣗવݴޠͰࣔ ͞ͳ͍ݶΓɺΘ͔Βͳ͍ɻ Ͳ͏ද͢ͱ͍͍͔ → DbC͕Ұͭ ͷ౴͑
  17. ܖ໿ʹΑΔઃܭ(Design by Contract) • όά(ʹ࢓༷ͱ࣮૷ͷໃ६)ͱ൑அ͢Δਖ਼͠͞ͱ͸͍͍ͬͨԿ͔ʁ • ”ਖ਼͠͞ͱ͸૬ରతͳ֓೦Ͱ͋Δ” • ΦϒδΣΫτࢦ޲ೖ໳ ୈ2൛

    ݪଇɾίϯηϓτ ୈ11ষ ܖ໿ʹΑΔઃܭ:৴པੑͷߴ͍ιϑτ΢ΣΞΛߏங͢Δ • ιϑτ΢ΣΞཁૉͦͷ΋ͷ͕ਖ਼͍͔͠Ͳ͏͔Ͱ͸ͳ͘ɺରԠ͢Δ࢓༷ͱҰக͢ Δ͔Λ࿦ͣΔ΂͖(ιϑτ΢ΣΞཁૉͱ࢓༷ͷϖΞͰߟ͑Δ) • ਖ਼͠͞ΛධՁ͢Δʹ͸ɺ”ද໌”Λ࢖ͬͨ࢓༷ͷهड़ํ๏Λར༻͢Δͷ͕Ұൠత • ਖ਼͠͞ͷެࣜ(ϗΞͷτϦϓϧ) = {P} A {Q} • ʮ೚ҙͷAͷ࣮ߦ͸ɺPͷঢ়ଶʹͳͬͨͱ͖ʹ࢝·ΓɺQͷঢ়ଶʹͳͬͨͱ͖ʹ ऴྃ͢Δʯ • P = ࣄલ৚݅(A͕ݺ͹ΕΔલʹຬͨ͢΂͖৚݅)ɻΫϥΠΞϯτΛଋറ͢Δ৚݅ • A = ιϑτ΢ΣΞཁૉ(ॲཧຊମ) • Q = ࣄޙ৚݅(A͕ݺ͹Εͨޙʹຬͨ͢΂͖৚݅)ɻαʔϏεΛଋറ͢Δ৚݅ %C$
  18. αʔϏεͱΫϥΠΞϯτ͕ަΘ͢ܖ໿ • ސ٬(ΫϥΠΞϯτ)͕ఏڙऀ(αʔϏε)Λར༻͢Δલఏ ͷܖ໿ • ͋ΔΫϥεʹରԠ͢Δϧʔνϯr͕ɺrequire preͱ ensure postΛએݴ͍ͯ͠Δ৔߹ɺͦͷΫϥε͸ސ٬(Ϋ ϥΠΞϯτ)ʹҎԼͷ͜ͱΛݴ͍ͬͯΔʹ౳͍͠

    • ʮ΋ͦͪ͠Β͕ pre Λຬͨͨ͠ঢ়ଶͰr ΛݺͿͱ໿ଋ͠ ͯԼ͞ΔͳΒ͹ɺ͓ฦ͠ʹɺpost Λຬͨ͢ঢ়ଶΛ࠷ऴ తʹ࣮ݱ͢Δ͜ͱΛ͓໿ଋ͠·͢ʯ %C$
  19. ྫ: ࣄલɾࣄޙ৚݅Λද໌͢Δϝιου def getThree(s: String): String = { require(s.length >=

    3, "length of s is too long!") s.substring(0, 3) }.ensuring(_.length == 3, "length of s doesn't equals 3") • requireΛ࢖ͬͯࣄલ৚݅Λද໌͢Δɻensuring͸ࣄޙ৚݅ͷද໌ • ΫϥΠΞϯτଆ͕StringIndexOutOfBoundsExceptionʹґଘ͍ͯ͠ΔͳΒ͹ɺαʔϏε ଆͷ࣮૷ʹґଘ͍ͯ͠Δ͜ͱʹͳΔʂ Exception in thread "main" java.lang.IllegalArgumentException: requirement failed: length of s is too long! at scala.Predef$.require(Predef.scala:277) at example.Example1$.getThree(Example1.scala:6)
 … at scala.App.$anonfun$main$1$adapted(App.scala:76) at scala.collection.immutable.List.foreach(List.scala:389) at scala.App.main(App.scala:76) at scala.App.main$(App.scala:74) at example.Example1$.main(Example1.scala:3) at example.Example1.main(Example1.scala) %C$
  20. ྫ) PHPͷmt_rand()ؔ਺ • mt_rand()͸Ұ؏ͯ͠ յΕ͍ͯΔ͕ɺࠔͬͯ ͍Δͷ͸ɺܖ໿Ͱ͸ͳ ͘αʔϏεଆͷ࣮૷ʹ ґଘͯ͠͠·ͬͨਓͨ ͪ %C$

  21. • ࣮ߦ࣌ͷද໌ҧ൓͸ɺͦͷιϑτ΢ΣΞʹόά͕͋Δ ূڌ • ࣄલ৚݅ҧ൓͸ɺΫϥΠΞϯτʹόά͕͋Δূڌ • ࣄޙ৚݅ҧ൓͸ɺαʔϏεʹόά͕͋Δূڌ ද໌͸੍ޚߏ଄ʹ͋Βͣ %C$

  22. ෆม৚݅ͱ͸ • ϗΞͷτϦϓϧʹΑͬͯɺॲཧͷਖ਼͠͞Λ൑ఆ͢Δ͜ͱ ͕Ͱ͖Δ͕ɺΫϥεͷଐੑ(σʔλ)ʹ΋ຬͨ͢΂͖৚݅ ͕͋ΔɻͦΕΛෆม৚݅ͱݺͿ • ྫ͑͹ɺࣗવ਺ͷෆม৚݅͸ʮ0Ҏ্ʯͰ͢ɻ • { INV

    & P } A { INV & Q} ͕੒Γཱͭͱ͖ɺ͢΂͕ͯ੒ޭ ͢Δ %C$
  23. ͦΕͧΕͷܖ໿Λද໌͢Δ case class Order(items: Seq[OrderItem]) { require(items.nonEmpty) def addOrderItems(otherItems: Seq[OrderItem]):

    Order = { require(otherItems.nonEmpty) copy(items = this.items ++ otherItems) }.ensuring(items.nonEmpty) } • ஫จΦϒδΣΫτͷ஫จΞΠςϜ͸ۭͰ͋ͬͯ͸ͳΒͳ͍ɻ • addOrderItem࣌ʹࣄલ৚݅ͱࣄޙ৚݅Λ֬ೝ͢Δ • ΋ͬͱ؆ܿʹهड़Ͱ͖ͳ͍͔ %C$
  24. ίϯετϥΫλͰͷද໌ case class OrderItems(values: Seq[OrderItem]) { require(values.nonEmpty) } object OrderItems

    { implicit object SeqmigroupInstance extends Semigroup[OrderItems] { override def combine(x: OrderItems, y: OrderItems): OrderItems = OrderItems(x.values ++ y.values) } } case class Order(items: OrderItems) { def addOrderItems(otherItems: OrderItems): Order = copy(items = this.items.combine(otherItems)) } • ImmutableͰ͋Ε͹ίϯετϥΫλͰɺෆม৚݅Λද໌ ͢Ε͹ɺͦΕΛ࢖͏ϝιουͰͷද໌ΛলུͰ͖Δ %C$
  25. FYI: ܕϨϕϧͰͷද໌ object Order { type OrderItems = NonEmptyList[OrderItem] //

    NonEmptyList͸ɺઌ಄ཁૉͷheadΛඞͣඞཁͱ͢ΔͨΊɺܕͱۭͯ͠ʹ͸Ͱ͖ͳ͍ // final case class NonEmptyList[+A](head: A, tail: List[A]) { … } case class Order(items: OrderItems) { def addOrderItem(otherItems: OrderItems): Order = copy(items = this.items.combine(otherItems)) } • cats.data.NonEmptyListͰͷྫ • ܕϨϕϧͰෆม৚݅Λද໌Ͱ͖Δ • ͢΂ͯͷέʔεͰ͜ͷํ๏͕࢖͑ΔΘ͚Ͱ͸ͳ͍ %C$
  26. ࠶ܝ: Evansϧʔϧ1 • ϧʔτΤϯςΟςΟ͸ɺάϩʔό ϧͳಉҰੑΛ࣋ͪɺෆม৚݅(ͦ ͷϞσϧ͕࣋ͭੑ࣭)ΛνΣοΫ͢ Δ੹຿Λෛ͏ • λΠϠͷަ׵͸ϝιουͳͲΛհ ͯ͠ߦΘΕΔɻܾͯ͠಺෦ͷΦϒ

    δΣΫτΛ௚઀ૢ࡞ͤͯ͞͸ͳΒ ͳ͍(λΠϠϩʔςʔγϣϯϧʔϧ Λڧ੍ͤ͞ΔͳͲͷෆม৚݅Λҡ ࣋͢ΔͨΊʹ) ڥք ࣗಈं λΠϠ λΠϠͷަ׵ λΠϠ λΠϠ λΠϠ ं྆൪߸ λΠϠ ू໿
  27. FYI: ՄมϑΟʔϧυΛ๫࿐ͯ͠͸ͳΒͳ͍ case class Order(private val _items: Seq[OrderItem]) { require(_items.nonEmpty,

    "items are empty!") val items: ListBuffer[OrderItem] = ListBuffer.empty[OrderItem] addOrderItems(_items) def addOrderItems(otherOrderItems: Seq[OrderItem]): Unit = { require(otherOrderItems.nonEmpty, "otherOrderItems are empty!") items.appendAll(otherOrderItems) items.ensuring(_.nonEmpty, "items are empty!") } } object Main extends App { val order = Order(Seq(OrderItem(1L, ProductName("red-pen"), 100, 1))) order.addOrderItems( mutable.Seq(OrderItem(2L, ProductName("blue-pen"), 100, 2))) println(order.items) // ListBuffer(OrderItem(1,ProductName(red-pen),100,1), OrderItem(2,ProductName(blue- pen),100,2)) order.items.clear() println(order.items) // ListBuffer() } • ू໿ͷෆม৚݅ΛഁյͰ͖ͯ͠·͏ྫ ू໿ ঢ়ଶΛՄมͰ͖Δ ϑΟʔϧυ͸ू໿ͷ ڥք֎ʹ๫࿐ͯ͠͸ ͳΒͳ͍ WBSͰ΋ಉ༷͕ͩɺ WBMͰ΋ՄมΫϥεͷ ৔߹΋஫ҙ͕ඞཁ ू໿ͷ༬͔Γ஌Βͳ͍ॲཧͰෆม৚݅ΛഁյͰ͖Δ
  28. Evansϧʔϧ2 • ू໿֎ͷΦϒδΣΫτ͸ɺϧʔτΤϯςΟςΟΛআ ͖ɺڥք಺෦΁ͷࢀরΛอ࣋͢Δ͜ͱ͕Ͱ͖ͳ ͍ɻ಺෦ΦϒδΣΫτ΁ͷࢀরΛଞͷΦϒδΣΫτ ʹ౉͠Ұ࣌తʹར༻͢Δ͜ͱ͕Ͱ͖Δ͕ɺϑΟʔϧ υͱͯ͠ར༻Ͱ͖ͳ͍(ॴ༗ݖͷ໌֬Խ) • DB͔ΒΫΤϦΛ࢖ͬͯऔಘͰ͖Δͷ͸ɺϧʔτΤ ϯςΟςΟͷΈ

    • ࡟আͷࡍ͸ɺू໿ʹ಺ࡏ͢Δ͋ΒΏΔΦϒδΣΫ τΛҰ౓ʹ࡟আ͢Δ(ϧʔτҎ֎͸֎෦͔Βࢀর͞ Ε͍ͯͳ͍ͷͰϧʔτΛ࡟আ͢Ε͹GC΋ޮ཰͕Α ͍) • ू໿಺෦ͷΦϒδΣΫτʹର͢Δมߋ͕ίϛοτ ͞ΕΔͱ͖͸ɺू໿શମͷෆม৚͕݅͢΂ͯຬͨ͞ Ε͍ͯΔ͜ͱ ू໿ Order OrderItems Purchase OrderItems ௚઀ͷࢀরΛอ࣋ NG Order OrderItems Purchase Order ௚઀ͷࢀরΛอ࣋ OK *%%%Ͱ͸0SEFS*E Λਪ঑
  29. ڥքఆٛͷળ͠ѱ͠

  30. ྫ:ڊେͳू໿ • όοΫϩάɺϦϦʔεɺεϓϦϯτͷ͢΂ͯΛอ࣋͢Δϓϩ μΫτू໿ɻϓϩμΫτʹόʔδϣϯ͕͋Γָ؍ϩοΫ͞Ε Δ • AͱBͷϢʔβ͕ಉ͡όʔδϣϯͰ࢖͍࢝ΊΔˠA͕όοΫϩ άΛ௥Ճ͠ίϛοτ
 B͕ϦϦʔεΛมߋ͠
 ͯίϛοτ͢Δ͕ɺ


    ָ؍ϩοΫΤϥʔ • සൟʹෳ਺ͷϢʔβ͕ߋ৽͢ΔέʔεͰ͸ɺಉ࣌ʹมߋ͠Α ͏ͱͨ͠ͱ͖ɺ੒ޭ͢Δͷ͸1ਓ͚ͩ͸ड͚ೖΕΒΕͳ͍ ू໿ 7FSOPO
  31. ྫ:ෳ਺ͷू໿ • ڊେͳू໿Λ࢛෼ׂɻProductIdʹΑͬͯؔ࿈෇͚ΒΕΔɻ όοΫϩάͷ௥Ճ࣌͸ɺτϥϯβΫγϣϯڥք಺Ͱߦ͏ͨ Ίɺڝ߹͕ى͖ͣʹ҆શʹߋ৽Ͱ͖Δ • τϥϯβΫγϣϯ໘Ͱ͸༗རͰ΋ɺΫϥΠΞϯτଆ͔Β͢ Δͱෆศ͔΋͠Εͳ͍(Product͕͋Δ͜ͱΛ֬ೝͯ͠ BacklogItemΛ௥ՃͳͲ) •

    όοΫϩάͳͲͷN਺
 Λ੍ݶ͢Δෆม৚݅
 ͕कΕͳ͘ͳΔՄೳੑ͕͋Δ ू໿ 7FSOPO
  32. Vernonͷू໿ઃܭϧʔϧ

  33. ϧʔϧ1: ਅͷෆม৚݅Λɺ੔߹ੑͷڥք಺ʹϞσϦϯά͢Δ • ੔߹ੑʹ͸2छྨ͋Δ: τϥϯβΫγϣϯ੔߹ੑ(ڧ͍੔߹ ੑ)ͱ݁Ռ੔߹ੑ(ऑ͍੔߹ੑ)ɻෆม৚݅ʹඞཁͳ੔߹ੑ ͸ɺτϥϯβΫγϣϯ੔߹ੑ • ू໿͸τϥϯβΫγϣϯ੔߹ੑͷڥքͱಉٛɻυϝΠϯ Ͱඞཁͱ͢Δ͋ΒΏΔมߋʹରͯ͠ɺτϥϯβΫγϣϯ

    ಺Ͱͷෆม৚݅ͷ੔߹ੑΛ҆શʹҡ࣋͢Δ • τϥϯβΫγϣϯͷ෼ੳޙʹɺू໿ͷઃܭͷળ͠ѱ͠Λ ਖ਼͘͠൑அ͢Δ͜ͱ͕Ͱ͖Δ ू໿ 7FSOPO
  34. ϧʔϧ2: খ͞ͳू໿Λઃܭ͢Δ • ڊେͳू໿Ͱ͸ɺجຊૢ࡞ͷଟ͘Ͱɺෳ਺ͷେ ن໛ͳίϨΫγϣϯͷಡΈࠐΈ͕ൃੜ͢Δɻύ ϑΥʔϚϯεʹѱӨڹ͕͋Δ • ”ଞͷཁૉͱͷ੔߹ੑΛอͭඞཁ͕͋Δ΋ͷ”͕ ൑அج४ɻͨͩ͠ϢʔεέʔεΛҰํతʹແࢹ Ͱ͖ͳ͍(Evans)

    • ϞσϧͷҰ෦ΛΤϯςΟςΟԽ͢Δ৔߹ • ͦΕ͕ࠓޙ΋มΘΓଓ͚ΔͳΒˠू໿Խ • มߋ࣌ʹ·Δ͝ͱஔ͖׵͑Ε͹Α͍ˠ஋Φ ϒδΣΫτ • ϧʔτΤϯςΟςΟͱҰॹʹγϦΞϥΠ ζͰ͖ɺΫΤϦ΋୯७ԽͰ͖ΔɻΤϯςΟ ςΟͷํ͕Φʔόʔϔου͕͋Δ ࣗಈं λΠϠ λΠϠ λΠϠ λΠϠ ं྆൪߸ Τϯδϯ Τϯδϯ൪߸ Τϯδϯ൪߸ ܕࣜ ϨγϓϩϩʔλϦ ܕࣜ͸ৗʹࣗಈंͷଞͷଐੑͱ੔߹ੑΛ อͭඞཁ͕͋Δ৔߹͸ಉҰू໿ͱͳΔ ू໿ 7FSOPO
  35. FYI: ϢʔεέʔεΛӏವΈʹ͠ͳ͍ • Ϣʔεέʔε෼ੳʹ͸ɺϏδωεΞφϦετ͕ॏཁͳ໾ׂΛՌͨ͢ ͕ɺ։ൃऀͷࢹ఺Λ൓өͨ͠΋ͷͱ͸ݶΒͳ͍ • ݸʑͷϢʔεέʔεͱϞσϧͷઃܭͷ੔߹ੑΛ߹ΘͤΔඞཁ͕͋Δ • ෳ਺ͷτϥϯβΫγϣϯ(ex. Product,

    BacklogItem)Λ୯Ұͷτϥ ϯβΫγϣϯͱͯ͠ѻ͏Α͏ͳϢʔεέʔεͰ໰୊͕ੜ͡Δ • ͜ͷΑ͏ͳϢʔεέʔε͸ӏವ Έʹ͠ͳ͍͜ͱ • ৔߹ʹΑͬͯ͸ɺϞσϧ΋͠ ͘͸ϢʔεέʔεΛݟ௚͢ඞ ཁ͕͋Δ • Ͱ͖Ε͹ɺ࠷ॳ͔Βશһಉ੮ ͰϞσϦϯάͨ͠ํ͕Α͍ ू໿ 7FSOPO
  36. ϧʔϧ3: ଞͷू໿΁ͷࢀরʹ͸ɺͦͷࣝผࢠΛར༻͢Δ • ͋Δू໿͕ผͷू໿ͷϧʔτΤϯςΟςΟ΁ ͷࢀরΛอ࣋ͯ͠΋͔·Θͳ͍͕ɺࢀরઌͷ ू໿ͱࢀরݩͷू໿͕ಉ͡ڥքʹଐ͢ΔΘ͚ Ͱ͸ͳ͍ • ಉҰτϥϯβΫγϣϯ಺Ͱ྆ํΛมߋͯ͠͸ ͍͚ͳ͍ɻมߋͰ͖Δͷ͸ͲͪΒ͔Ұํ͚ͩ

    • ಉҰτϥϯβΫγϣϯͰ͸ɺ݁ہ ڊେͳू ໿ʹͳΔ • ଞͷू໿΁ͷࢀরΛอ࣋͠ͳ͚Ε͹ɺͦͷू ໿Λมߋ͢Δ͜ͱ͕Ͱ͖ͳ͍ • ֎෦ͷू໿΁ͷࢀর͸ID͚ͩΛར༻͠ϙΠ ϯλ͸อ࣋͠ͳ͍Α͏ʹ͢Δ • ϝϞϦফඅྔ΋཈͑ΒΕΔɻׂΓ౰͚ͯͩ Ͱͳ͘ɺGC໘Ͱ΋޷Өڹ͕ٴͿ Order OrderItems Purchase Order ௚઀ͷࢀরΛอ࣋ NG Order OrderItems Purchase OrderId ؒ઀ͷࢀরΛอ࣋ OK 0SEFS3FQPTJUPSZ ू໿ 7FSOPO
  37. ϧʔϧ4: ڥքͷ֎෦Ͱ͸݁Ռ੔߹ੑΛ༻͍Δ • ΫϥΠΞϯτ͔Βͷ୯ҰͷϦΫΤετͰɺෳ਺ͷू໿Λม ߋ͢Δ৔߹͸݁Ռ੔߹ੑΛ࢖͏͜ͱ • ͋Δू໿͕ࢀর͢Δ֎෦ͷू໿͸࡟আ͞Ε͍͔ͯ΋͠Ε ͳ͍͠ɺͦͷૢ࡞Ͱ૝ఆ͠ͳ͍ঢ়ଶʹભҠ͍ͯ͠Δ͔΋ ͠Εͳ͍ɻ(ϓϩμΫτ͕࣋ͭλάʹؔ࿈෇͘ɺόοΫϩ άͱεϓϦϯτΛফͦ͏ͨ͠Βɺ͢Ͱʹফ͍͑ͯΔ͜ͱ

    ͕͋Δ) • ͋Δू໿͕ঢ়ଶΛมߋ͢ΔࡍʹɺαϒεΫϥΠόʹυϝ ΠϯΠϕϯτΛ௨஌͠ɺ੔߹ੑΛҡ࣋͢ΔॲཧΛ࣮ߦ͢ Δ͜ͱ΋Մೳ ू໿ 7FSOPO
  38. ·ͱΊ • ϏδωεϧʔϧΛू໿ͷෆม৚݅ͱͯ͠࡞ΓࠐΉ͜ͱͰɺݎ࿚ͳγ εςϜͷ࣮ݱʹߩݙͰ͖Δ • ೉͍͜͠ͱ͕ͩɺϢʔεέʔεͱϞσϧͷ੔߹ੑͷ྆ํΛܰࢹ͠ͳ ͍͜ͱ • ू໿ͷΑΓৄࡉͳ৘ใΛಘΔ৔߹͸ɺEvansຊ ୈ2෦ୈ6ষ

    ू໿ɺ Vernonຊ ୈ10ষ ू໿ΛಡΉͱΑ͍