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

集約の設計と実装

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

 集約の設計と実装

Avatar for かとじゅん

かとじゅん

April 16, 2018
Tweet

More Decks by かとじゅん

Other Decks in Programming

Transcript

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

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

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

    ͨͱ͑͹ɺಉ͡෦ॺʹผͷैۀһ͕ॴଐ͍ͯ͠ Δ͔΋͠Εͳ͍ɻͦͷ෦ॺΛ࡟আ͢Δͱผͷै ۀһΦϒδΣΫτ͸࡟আ͞ΕͨࢀরΛ࣋ͭ͜ͱ ʹͳΔɻٯʹ์ஔ͢Ε͹ɺDBʹෆཁͳ෦ॺΛ ͨΊࠐΉ͜ͱʹͳΔ ू໿
  4. ڥքະఆٛʹΑΔ໰୊ • ଘࡏ͢Δෳ਺ͷΦϒδΣΫτ͕ɺ͍ͭ ࡞ΒΕɺ͍ͭͳ͘ͳΔͷ͔ʁ • σʔλΛมߋ͢Δൣғ(τϥϯβΫ γϣϯείʔϓͳͲ)΍σʔλͷҰ؏ੑ Λҡ࣋͢Δϧʔϧ͕ͳ͚Ε͹ͳΒͳ͍ • ڥքະఆٛͷ··ɺ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) } }
  5. ࣗಈंमཧళ޲͚γεςϜͷྫ • λΠϠͷϩʔςʔγϣϯͷه࿥ ͱɺ֤λΠϠͷ૸ߦڑ཭ͱ઀஍ ໘ͷຎ໣౓߹͍Λ௥੻͢Δ • ࣗಈं͸άϩʔόϧͳಉҰੑΛ ࣋ͭϧʔτΤϯςΟςΟɻࣝผ ࢠʹ͸ं྆൪߸Λར༻͢Δ •

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

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

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

    ͳ͍(λΠϠϩʔςʔγϣϯϧʔϧ Λڧ੍ͤ͞ΔͳͲͷෆม৚݅Λҡ ࣋͢ΔͨΊʹ) ڥք ࣗಈं λΠϠ λΠϠͷަ׵ λΠϠ λΠϠ λΠϠ ं྆൪߸ λΠϠ ू໿
  9. ઌ಄ͷࡾจࣈΛฦ͢ϝιου1 package example object Example1 extends App { def getThree(s:

    String): String = s.substring(0, 3) println(getThree("12345")) } • Ҿ਺ͷจࣈྻ͔Βઌ಄ࡾจࣈΛൈ͖ग़͠ฦ͢ϝιου • ਖ਼͘͠ಈ࡞ͦ͠͏Ͱ͢… 123 %C$
  10. ઌ಄ͷࡾจࣈΛฦ͢ϝιου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$
  11. ίʔυ͔Β࢓༷͕Θ͔Βͳ͍ྫ 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͕Ұͭ ͷ౴͑
  12. ܖ໿ʹΑΔઃܭ(Design by Contract) • όά(ʹ࢓༷ͱ࣮૷ͷໃ६)ͱ൑அ͢Δਖ਼͠͞ͱ͸͍͍ͬͨԿ͔ʁ • ”ਖ਼͠͞ͱ͸૬ରతͳ֓೦Ͱ͋Δ” • ΦϒδΣΫτࢦ޲ೖ໳ ୈ2൛

    ݪଇɾίϯηϓτ ୈ11ষ ܖ໿ʹΑΔઃܭ:৴པੑͷߴ͍ιϑτ΢ΣΞΛߏங͢Δ • ιϑτ΢ΣΞཁૉͦͷ΋ͷ͕ਖ਼͍͔͠Ͳ͏͔Ͱ͸ͳ͘ɺରԠ͢Δ࢓༷ͱҰக͢ Δ͔Λ࿦ͣΔ΂͖(ιϑτ΢ΣΞཁૉͱ࢓༷ͷϖΞͰߟ͑Δ) • ਖ਼͠͞ΛධՁ͢Δʹ͸ɺ”ද໌”Λ࢖ͬͨ࢓༷ͷهड़ํ๏Λར༻͢Δͷ͕Ұൠత • ਖ਼͠͞ͷެࣜ(ϗΞͷτϦϓϧ) = {P} A {Q} • ʮ೚ҙͷAͷ࣮ߦ͸ɺPͷঢ়ଶʹͳͬͨͱ͖ʹ࢝·ΓɺQͷঢ়ଶʹͳͬͨͱ͖ʹ ऴྃ͢Δʯ • P = ࣄલ৚݅(A͕ݺ͹ΕΔલʹຬͨ͢΂͖৚݅)ɻΫϥΠΞϯτΛଋറ͢Δ৚݅ • A = ιϑτ΢ΣΞཁૉ(ॲཧຊମ) • Q = ࣄޙ৚݅(A͕ݺ͹Εͨޙʹຬͨ͢΂͖৚݅)ɻαʔϏεΛଋറ͢Δ৚݅ %C$
  13. ྫ: ࣄલɾࣄޙ৚݅Λද໌͢Δϝιου 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$
  14. ͦΕͧΕͷܖ໿Λද໌͢Δ 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$
  15. ίϯετϥΫλͰͷද໌ 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$
  16. 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$
  17. ࠶ܝ: Evansϧʔϧ1 • ϧʔτΤϯςΟςΟ͸ɺάϩʔό ϧͳಉҰੑΛ࣋ͪɺෆม৚݅(ͦ ͷϞσϧ͕࣋ͭੑ࣭)ΛνΣοΫ͢ Δ੹຿Λෛ͏ • λΠϠͷަ׵͸ϝιουͳͲΛհ ͯ͠ߦΘΕΔɻܾͯ͠಺෦ͷΦϒ

    δΣΫτΛ௚઀ૢ࡞ͤͯ͞͸ͳΒ ͳ͍(λΠϠϩʔςʔγϣϯϧʔϧ Λڧ੍ͤ͞ΔͳͲͷෆม৚݅Λҡ ࣋͢ΔͨΊʹ) ڥք ࣗಈं λΠϠ λΠϠͷަ׵ λΠϠ λΠϠ λΠϠ ं྆൪߸ λΠϠ ू໿
  18. 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Ͱ΋ՄมΫϥεͷ ৔߹΋஫ҙ͕ඞཁ ू໿ͷ༬͔Γ஌Βͳ͍ॲཧͰෆม৚݅ΛഁյͰ͖Δ
  19. Evansϧʔϧ2 • ू໿֎ͷΦϒδΣΫτ͸ɺϧʔτΤϯςΟςΟΛআ ͖ɺڥք಺෦΁ͷࢀরΛอ࣋͢Δ͜ͱ͕Ͱ͖ͳ ͍ɻ಺෦ΦϒδΣΫτ΁ͷࢀরΛଞͷΦϒδΣΫτ ʹ౉͠Ұ࣌తʹར༻͢Δ͜ͱ͕Ͱ͖Δ͕ɺϑΟʔϧ υͱͯ͠ར༻Ͱ͖ͳ͍(ॴ༗ݖͷ໌֬Խ) • DB͔ΒΫΤϦΛ࢖ͬͯऔಘͰ͖Δͷ͸ɺϧʔτΤ ϯςΟςΟͷΈ

    • ࡟আͷࡍ͸ɺू໿ʹ಺ࡏ͢Δ͋ΒΏΔΦϒδΣΫ τΛҰ౓ʹ࡟আ͢Δ(ϧʔτҎ֎͸֎෦͔Βࢀর͞ Ε͍ͯͳ͍ͷͰϧʔτΛ࡟আ͢Ε͹GC΋ޮ཰͕Α ͍) • ू໿಺෦ͷΦϒδΣΫτʹର͢Δมߋ͕ίϛοτ ͞ΕΔͱ͖͸ɺू໿શମͷෆม৚͕݅͢΂ͯຬͨ͞ Ε͍ͯΔ͜ͱ ू໿ Order OrderItems Purchase OrderItems ௚઀ͷࢀরΛอ࣋ NG Order OrderItems Purchase Order ௚઀ͷࢀরΛอ࣋ OK *%%%Ͱ͸0SEFS*E Λਪ঑
  20. ϧʔϧ2: খ͞ͳू໿Λઃܭ͢Δ • ڊେͳू໿Ͱ͸ɺجຊૢ࡞ͷଟ͘Ͱɺෳ਺ͷେ ن໛ͳίϨΫγϣϯͷಡΈࠐΈ͕ൃੜ͢Δɻύ ϑΥʔϚϯεʹѱӨڹ͕͋Δ • ”ଞͷཁૉͱͷ੔߹ੑΛอͭඞཁ͕͋Δ΋ͷ”͕ ൑அج४ɻͨͩ͠ϢʔεέʔεΛҰํతʹແࢹ Ͱ͖ͳ͍(Evans)

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

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

    • ಉҰτϥϯβΫγϣϯͰ͸ɺ݁ہ ڊେͳू ໿ʹͳΔ • ଞͷू໿΁ͷࢀরΛอ࣋͠ͳ͚Ε͹ɺͦͷू ໿Λมߋ͢Δ͜ͱ͕Ͱ͖ͳ͍ • ֎෦ͷू໿΁ͷࢀর͸ID͚ͩΛར༻͠ϙΠ ϯλ͸อ࣋͠ͳ͍Α͏ʹ͢Δ • ϝϞϦফඅྔ΋཈͑ΒΕΔɻׂΓ౰͚ͯͩ Ͱͳ͘ɺGC໘Ͱ΋޷Өڹ͕ٴͿ Order OrderItems Purchase Order ௚઀ͷࢀরΛอ࣋ NG Order OrderItems Purchase OrderId ؒ઀ͷࢀরΛอ࣋ OK 0SEFS3FQPTJUPSZ ू໿ 7FSOPO