「注文」から「出荷」への業務プロセス連鎖部位をDDD的に解釈したい!

「注文」から「出荷」への業務プロセス連鎖部位って、注文領域に属するべき?出荷領域に属するべき?それとも第三の業務領域?
6
たなかこういち @Tanaka9230

ご意見いただけますかっ?(いまさら?) 注文集約と出荷集約があります。 注文を元に出荷を作り出す、 def newShippingFromOrder(order: Order): Shipping こいう趣旨の処理が必要です。 この処理はどこに装備する?(※コメの補足みてください。)

2020-03-10 13:35:44
たなかこういち @Tanaka9230

(回答1) Order集約ルートに、 def createShipping(): Shipping (回答2) Shipping集約ルートに、 def fromOrder(order: Order): Shippingというクラスメソッド (回答3) OrderServiceに、 def createShipping(): Unit (回答4) ShippingServiceに、 def createFromOrder(): Unit

2020-03-10 13:40:10
なんとかなんとかさん @selvaggio

DDD素人だけど… Order理由でShippingを決める場合(こちらが通常)と、Shipping都合でOrderを変更する場合(災害時とか?)の両方がありそう。相互更新を行うのは危険に思うので、サービス層が必要…だと思う。 どちらのSvcに持たせるかは"出荷しないOrder"があるかもだからOrder側…かなあ twitter.com/Tanaka9230/sta…

2020-03-10 14:01:28
なんとかなんとかさん @selvaggio

集約がトランザクション境界を指す、っていうのはググって出てきたけど、サービス層って何をやる層なのかはよくわかってないで答えてる

2020-03-10 14:02:47
たなかこういち @Tanaka9230

本件、最初の考慮点は、 注文と出荷、どちらかがどらかを"知っている"必要がある。つまり、どちらかがどちらかに依存しなければならない点。 注文が出荷の作り方を知っているべきか?出荷が、注文からの作り方を知っているべきか? 注文が出荷に依存するのか?出荷が注文に依存するのか? twitter.com/Tanaka9230/sta…

2020-03-11 00:46:07
かにかま🦀 @ka2_kamaboko

注文は出荷に依存しないが、出荷は注文に依存するはず。 しかし出荷自体は単なる成果物であって、注文から出荷への流れは別枠に担当させるべき。 と思ったけど選択肢のサービスはUnitを返すのか……参ったな。 絶対選ばないといけないなら、泣く泣く4番かなぁ。 twitter.com/Tanaka9230/sta…

2020-03-11 01:00:30
働くお馬さん@まだ寝られない @Tadahiro_Yamamu

@Tanaka9230 Shippingの生成処理になるから回答2か4だけど、回答4かなー。 多分DB登録とかの処理が必要だと思うんですよね。

2020-03-11 01:37:27
すえなみ @a_suenami

@Tanaka9230 1に入れましたが、選択肢がそもそも択一じゃないと感じました。3,4がアプリケーションサービスを意味するなら「{1,2のいずれか}を{3,4のいずれか}から利用する」っていうのが回答になり、僕は「4から1を利用する」ですね。3,4がドメインサービスを意味するならこれらは真っ先に候補から外れます。

2020-03-11 11:14:19
すえなみ @a_suenami

@Tanaka9230 3,4がアプリケーション層なのかドメインサービスなのかわからなかったので、より確実な1に入れましたが、戻り値の型がUnitであることを考えるとこれはアプリケーションサービスですね。そうなると4も妥当かなと思います。

2020-03-11 11:29:53
加藤潤一(かとじゅん) @j5ik2o

@Tanaka9230 Order::createShippingにしたけど、Order集約とShipping集約と循環参照になって密結合してしまうようならShipping::fromOrderにすることがあります。JIGを使うと循環は一発で検出できますよ。

2020-03-11 11:34:30
加藤潤一(かとじゅん) @j5ik2o

@Tanaka9230 モジュールの結合度のコントロールを忘れて、ドメイン的な意味論だけでメソッド生やしていくと、いつの間にか循環参照で密結合になり、コードを読む人にとっては過酷な状況になりやすいと思っています。

2020-03-11 11:35:29
杉本啓 @sugimoto_kei

@j5ik2o @Tanaka9230 同意。出荷は受注に依存するけれど、受注は出荷に依存しないのが、業務における普通の線引きのように思います。なんとかサービスの要否はよくわかりませんが。

2020-03-11 11:37:17
すえなみ @a_suenami

@Tanaka9230 たなかさん自身もおっしゃっている通り、これはOrderがShippingに依存する(1)か、その逆(2)かって話だと思いますが、Shippingのほうがより早期に安定しやすくOrderのほうが競争優位になる部分だから依存関係の上位に置きたいかなぁと思って1にしました。(EC脳)

2020-03-11 11:41:13
すえなみ @a_suenami

@Tanaka9230 Shippingのほうが早期に安定するとか言っちゃうと物流関係者に怒られそうですが……

2020-03-11 11:42:06
杉本啓 @sugimoto_kei

@a_suenami @Tanaka9230 その意味では、Sales Order と Shipping の間に、Shipping Order /出荷指図みたいな媒介概念を置くのが、わりとよくある分担の枠組みかと思います。

2020-03-11 11:46:33
加藤潤一(かとじゅん) @j5ik2o

@Tanaka9230 あと、OrderにもShippingにもメソッドがおけない場合があって、特定の場面でしか現れない操作、CLOSのマルチメソッドみたいな局面です。それはDCIのロールオブジェクトみたいなものにメソッドを従属させていますね。

2020-03-11 11:47:11
すえなみ @a_suenami

@Tanaka9230 今の僕だったら class CreateShippingFromOrderFunction implements BiConsumer<Order, Shipping> とかっていう関数を作るかもしれません。これだとこの関数が両者に依存する形になってOrderとShippingの間の依存関係はなくせるので。

2020-03-11 11:50:22
すえなみ @a_suenami

@sugimoto_kei @Tanaka9230 おー、なるほどー!それは確かに綺麗(?)ですね。

2020-03-11 11:52:32
杉本啓 @sugimoto_kei

@a_suenami @Tanaka9230 在庫管理の担当からすれば、受注以外にも出荷の理由はあるので、受注とは切り離した「出荷指示」というものがあった方がいいのですね。業務は意外と疎結合に出来ているものだと思います。長年、淘汰されていますから。

2020-03-11 11:55:13
HARADA Kiro @haradakiro

@Tanaka9230 注文と出荷が多対多になるなら、座席予約クラス作ってそちらにしますね。

2020-03-11 11:55:43
たなかこういち @Tanaka9230

@sugimoto_kei @a_suenami 当初設問がゆるかった感じはしますね(=_=; ちな、その通り、 注文によらない、拠点(店舗)間移動指示による出荷や、仕入先返品による出荷もあります。 業務フロー的に、出荷が受注に依存し、逆ではないと思ってました。そうすると、 出荷に次々と様々な依存先が出現してしまいます。

2020-03-11 12:28:26
たなかこういち @Tanaka9230

@sugimoto_kei @a_suenami それでむしろ、受注や返品側にそれぞれ「次は出荷」を担わせるのか?という気もしました。 しかし、業務的に上流側が下流をいちいち知れっていうのもツラい。 結局(一晩寝ながら)、杉本さんにも指摘いただいた通り、 注文から出荷を作り出す采配そのものが、独立業務と捉えた方がいいと思いました。

2020-03-11 12:32:04
たなかこういち @Tanaka9230

@a_suenami 実際のところ、受注側と物流側、それぞれ異なる要因で異なるライフサイクルで、要求発生変更しますね、まさに。 サブシステム分割的に、業界ではOMS-WMSといってます。 Order Mgmt. SystemとWarehouse Mgmt. Systemです。

2020-03-11 12:36:00
かにかま🦀 @ka2_kamaboko

これ、業務ならちゃんと要件詰めてそれに合わせた設計するけど、Twitterであんまり「ケースバイケース」とか言いたくないからある程度前提を決めうちしてる、みたいなとこある。

2020-03-11 12:36:24