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

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

@a_suenami 注文側、出荷側は、(捉え方にもよりますが、)概ね異なる境界付けられたコンテキストと思った方がいい。

2020-03-11 12:38:36
たなかこういち @Tanaka9230

@a_suenami 「出荷指示」は、それらを繋ぐ機能or役割で、「出荷指示」自体は、注文集約の振る舞いでも、出荷集約の振る舞いでもない。

2020-03-11 12:38:47
たなかこういち @Tanaka9230

@a_suenami さらに、ちなみに、「出荷指示」は、(Amazonみたいなところは別として(^^;、)日に1回〜2回のスケジュールでバッチ処理をトリガーします。〆時間がきた注文に対して、「出荷指示」します。

2020-03-11 12:44:08
saka @gaplant_tr5

「手配」って言う概念見たことあるなぁ。 引数に受注データ(住所含む)や返品データを受け取って、住所からリードタイム計算して出荷データを作るやつ。 twitter.com/tanaka9230/sta…

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

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

2020-03-11 12:32:04
杉本啓 @sugimoto_kei

受注や出荷はオペレーションレベルの業務ですが、出荷指示は意思決定レベルの業務で、レイヤが違う。こういう意味論的なレイヤ分けの話は、確かDDD本にもあったと思います(今てもとにない)。 twitter.com/Tanaka9230/sta…

2020-03-11 12:48:46
たなかこういち @Tanaka9230

DDDや集約とかの用語や概念を用いない場合、"サブシステム"としては、シンプルに三つあります。 - orderテーブルにinsertするようなECフロント - shippingテーブルをselectしてピッキングリスト出力するWMS - ordersテーブルを所定の条件でselectして、shippingを作ってinsertするバッチプログラム

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

As-Isシステムは、"古典的に素直に"そのように作ってあっる。 これを意味的に再整理しようとして、、注文集約と出荷集約、それぞれを"戦術DDD"というか"ボトムアップDDD"というかで、それぞれの状態遷移(ワークフロー)再定義し作るこむことには何も問題ない。

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

バッチプログラムになっている処理を、「注文」または「出荷」に寄せるべきと思って、、どっちだろう?と無駄に悩んだ。 結局、はじめから「どちらでもなかった」のだ。 なぜか? さすが杉本さんですね、オペレーションのレイヤーと意思決定のレイヤーなのでしょう。 twitter.com/sugimoto_kei/s…

2020-03-11 12:59:00
杉本啓 @sugimoto_kei

@Tanaka9230 本件、興味深いですね。オブジェクト設計の問題でもあり、業務構造の設計の問題でもある。両者が表裏一体になっていますね。

2020-03-11 13:16:27
mitsutaka.takeda @MitsutakaTakeda

集約と集約が依存するのに違和感があるから、注文集約側では、OrderReceivedみたいなイベント(DTO)だけ記録して、Shipping側でイベントから出荷集約を生成するみたいにするかな twitter.com/Tanaka9230/sta…

2020-03-11 13:19:20
たなかこういち @Tanaka9230

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

2020-03-10 13:35:44
Siena. @n_siena

@Tanaka9230 2. か 4. ですが、要件不明なので 4. にしておきました。 複数の注文をまとめて発送したり、一つの注文を分割発送したりという要求が想定されるのと、具体的な注文・発注のバリエーションがどれくらい発生しうるのか未知数なのでそれらを密結合にしたくない、というのが理由です。

2020-03-11 13:32:07
Atsuhiro Kubo @iteman

@sugimoto_kei 「責務のレイヤ」ですね。PHPメンターズの過去の関連記事もあります。 phpmentors.jp/post/820419520…

2020-03-11 13:54:11
杉本啓 @sugimoto_kei

実際、業務システムの核って、入出庫みたいなオペレーションじゃなくて(それも大事だけど)、その上のレイヤである手配や指図だと思うんですよね。 SoR(記録のシステム)って呼び方を僕は好きじゃないんだけど、その理由は、手配や指図という概念が欠落しているように見えるから。 twitter.com/gaplant_tr5/st…

2020-03-11 15:54:14
saka @gaplant_tr5

@sugimoto_kei データを記録すること自体(SoRの概念的な話)はシステムとしては必要だと思いますが、 そのデータと業務システムやフローの表現が1:1である必要はないように思います。 ちなみに「手配」っていうのは業務フローの名称をそのまま取ってたと記憶しています。(もう7~8年前の話なのでうろ覚えですが)

2020-03-11 16:07:14
wint🛰 @wint7

手配や指図などのコマンドはイベント扱いで良いのか気になる twitter.com/sugimoto_kei/s…

2020-03-11 23:37:47
杉本啓 @sugimoto_kei

@wint7 イベントかリソースかって便宜的な区分ですよね。資材所要量計画(MRP)では、予定オーダーなんてどんどん更新されていきます。

2020-03-11 23:40:55
wint🛰 @wint7

@sugimoto_kei なるほど、その通りですね。イベントやレコードやらだけ見てると、結局その手前で調整され続けてる手配などの概念を捉えきれてないのは変わらないということなんでしょうね

2020-03-11 23:48:47

まとめ後の追記

たなかこういち @Tanaka9230

注文集約の状態遷移は、粗くは、 受付-決済済-出荷中-出荷完了-キャンセル-強制キャンセル こんな感じ。 出荷集約の状態遷移は、 受付済-出荷作業中-出荷完了-出荷不可-取消 こんな感じ。

2020-03-12 00:35:52
たなかこういち @Tanaka9230

各集約の状態遷移は、DDDのAggregate/Repositoryのパターンで普通に実装できる。 各集約の状態遷移は、確かに単純CRUDではないが(削除なんてないし!)、とは言え、 - 一種類の作成処理 - 複数種類の更新処理 - "削除"風の処理 から構成されてて、まあー"拡張CRUD"の範囲っちゃ範囲なんですよ。

2020-03-12 00:35:53
たなかこういち @Tanaka9230

これは僕の個人的な定義ですが、 「業務フロー」と「業務プロセス」を次のように使い分けます。 業務フロー = 一つの集約に閉じてる、業務状態遷移 業務プロセス = 集約をまたいで連鎖する状態遷移

2020-03-12 00:38:56
たなかこういち @Tanaka9230

基本的に、業務フロー/プロセスとも「業務状態遷移」でとらえます。 ある状態から次の状態への遷移をひきおこすアクションは、アトミックトランザクションを構成する前提です。 一つのアトミックトランザクション内での中間状態は、業務状態として定義しません。

2020-03-12 00:48:17
たなかこういち @Tanaka9230

で、戻りますが、 一つの業務フローは、一つの「プライマリー集約」によって担われるとします。 一つの業務フローは、この僕の話における用語として、一つの「コンテキスト」といってよいと思います。(ただ、これを「境界付けられたコンテキスト」と言ってしまうのは早いと思います。)

2020-03-12 00:51:57
たなかこういち @Tanaka9230

「業務フロー」と「集約」の定義が双方向依存っぽくなってるかもしれませんが、そこは上手にそうなるように設計します。

2020-03-12 00:57:55