ドメイン駆動設計 Before/Afterを鑑賞して(途中)

# DDD実践によって事業成長スピードと保守性を両立する
一個目のセッションでは、LINEヤフーの方による登壇です。

## ビジネスの概要
対象のビジネスは、日本最大級ECプラットフォームであるヤフーショッピングです。

扱っている商品数：4億、年間取扱高：1兆円
サービス自体は25周年目という長めの運用期間です。

## DDDを採用する前状態
### ビジネスの複雑化
下図のユーザが商品購入時に、さまざまな種類の割引クーポンを使える使用になっている。
そのバリエーションは下図のように多岐にわたるそう。
家電にのみ使えるクーポンやら、初めて会員になった方向けのものやら、、、。

<img width=600 alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/efb39b3b-a594-8d4c-0292-1b984f0bbfc7.png">

:::note warn
まずこれを見た瞬間に思ったのは、仮にこれがif文とかで書かれていたら、
保守が絶望的に大変になるなと感じました。
:::

まあただ、ビジネスが成長し拡大するにしたがって、システムが複雑化してしまうのは避けられないのもまた事実。

### コミュニケーションコストの増大
IT部門と営業、企画、マーケティング、開発部門が密接に関わらないといけないが、
その際に、用語の違いによる認識のズレが関係者間の間で発生し、
コミュニケーションコストが増大したそう。

コミュニケーションコストのわかりやすい図としては、
以下のようなクモ状の糸とn*(n-1)/2という計算式が有名である。

<img width=500 alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/b7614ebb-e897-7767-1e92-339fb0dd7e04.jpeg">

あとは、部門の境界をまたぐと用語の変換がなされてしまい意図が変わってしまうなどによるコミュニケーションコストの増大現象もよく聞くものである。

### システム内部のメンテコスト増大
かなりレガシーな状態であったそうであり、以下のような特徴があったそう。

:::note alert
神クラス状態
:::

:::note alert
処理の流れが複雑で見通しが悪い
:::

:::note alert
仕様自体が複雑であるため、後続のシステムはそれ以上に複雑
:::

## As-Is → To-Beの移行計画表
このような状況から抜け出すために、以下のような大規模なリアーキ計画が立てられた。

![スクリーンショット 2025-02-06 004000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/2f4271fa-d6d4-abe9-7760-2e7718972ce0.png)

個人的にこれを見てふっと気になったのは、業務改善であるECRS原則と対応した、
戦術的フォークやらコンポーネントベース分割を行ったうえで、
それでもまだ業務範囲が大きいがゆえに、アジリティやスケーラビリティを維持しにくい
といった場合に、マイクロサービスを検討されたのかな？ってところです。

## DDDの実践前の活動内容
技術的な下ごしらえだけでなく、コードの方針決めやら体制づくりなどの解説があり、
ここが成功要因になったのではないかと感じました。

### DDDを実践する前準備

・既存コードのモデルによる可視化
ちなみにA4用紙10枚以上のシーケンス図ができあがったとのことで、
相当複雑化したビジネスプロセスだなー:sweat_smile:　と思いました。

・DDDの学習
・DDDに詳しい講師を招いての学習

### コード設計のコンセプト
:::note info
配属直後の新卒でも理解できるほどの容易性(理解容易性)の担保
:::

:::note info
シンプルなワークフローの設計←これはビジネスモデルにおいて非常に重要
:::

:::note info
モジュール名や処理名、変数名を業務用語に合わせる。
:::

【補足説明】
この３つ目はBizDevOps体制を引いている状態でないと実現が厳しい。

しかしながら、名前を業務用語と一致させていることによって、
ビジネスとアプリケーション層が相似形になりやすく(下図のEAモデルを参照)、
それによってビジネスの特定箇所を変更するとしたら、システム内のどこを変更すべきであり、それによってどこまで影響範囲があるのか？といった分析が非常に行いやすくなるという大きなリターンがある。


<img width=600 alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/2617730f-e94c-2e3f-16e3-8564b36cecb3.png">

### 開発体制

:::note info
ドメインエキスパートと若手エンジニアでペアプログラミング
:::

これは若手の育成にもつながるし、体感的にきれいなコードを描く習慣化にもつながるので、非常にいい体験を提供されていると感じた。

:::note info
書いては捨て、を繰り返す
:::
この活動はまさにアジャイルモデリングそのものである。(下記が参考書籍)

<img width=250 alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/16463788-4095-8727-18b1-ec18392030c9.jpeg">

## DDDの実践

### モデルの分析フェーズ
イベントストーミングなどの手法を用いて可視化し、
時にコンテキスト境界をまたいで他チームとコラボし、
別チームの人をドメインエキスパートとして質問したりして、モデルの理解を深めていったそうです。

その分析工程を経て、まだモデル図に出ていない概念の発見につながる。

この流れは基本的にDDDを実践する、どこの現場でも同じようなメカニズムですね。

ただし、工夫を感じたのは、代表的な異なるユースケースにおいて、
カゴや商品ラインの役割が異なるという発見から、
文脈の違いによってリポジトリーを分割して、それぞれのコンテキストごとにモデリングを行ったという点。

また業務知識を表現したモデル上の名前をユビキタス名として、
モジュール名に適用することによって、ソースコード自体が業務のマニュアルになっていることを目指した。

### レイヤードアーキテクチャでドメインロジックを分離
ドメインモデルの領域を技術的な他の層から関心分離するために、
レイヤードアーキテクチャスタイルをとられたそう。
これはDDDの文脈では、よく取る代表的なパターンですよね。

依存関係逆転原則を適用し、インフラ層の技術を変えたとしても
ドメインロジック部分は変更の影響を受けないように、関心が分離されています。

![スクリーンショット 2025-02-06 025322.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/57cbc0e0-b8aa-cdd2-bfe4-ea7d805c8811.png)

さらに腐敗防止層があることによって、ドメインロジックは他の層の関心事に依存しない
ものとして維持できます。

### ドメインサービスの利用法と注意点
ドメインサービスに関しても、ちょこっと話題に出ていたので触れておきます。

:::note info
その時点で、どこにも責務を割り当てられないロジックに関しては、
いったん仮置きのドメインサービスを用意して、そこに割り当てる
:::

というやり方は、過去にわたしもやっていた手法です。

ただし、これはどうしても割当先が見つからないといった時の応急処置です。
あまりにも乱用しすぎるとあっという間にドメイン貧血症を引き起こします。

:::note warn
極力、ドメインサービスの利用は控えておきましょう。
そして必ず次回以降のモデリングでモデルの理解が深まり、
割当先になる概念が発見されたら、すぐにそちらへロジックを移すリファクタリングを行いましょう。
:::

### DDDを行う上でのメリット
:::note info
単体テストが実装しやすくなる
:::

これはモデリングを通して、単一責務を意識していると、
自ずと１メソッド当たりの責務の範囲が最小限になるため、結果的にテスト対象も小さくなることが理由である。

:::note info
カプセル化によりロジックの凝集性が上がる
:::

:::note info
実装スピードが上がる
:::
モデリングによって、意味のある単位に小さく切り分けられたことで、
エンジニア１人当たりの認知負荷が減少し、スピードがアップする。

### 副作用のない関数にする
これは驚き最小原則のことをまさに指しています。
意図しない矛盾のある状態変化などのバグを発生させないようにするために大事です。
これは事前にRDRAなどを使って、状態モデルを可視化しておくことも抑止力になります。

これによってドメインモデルの普遍性を獲得できる。
状態を変えたい場合には、新しいオブジェクトを生成する。

## 使用されたデザインパターン(27分あたり)
### Facadeパターン
コントローラーを導入

### Enumを使った多態性
switch文を排除し、多態性でバリエーション保護
これはあまたのクーポンのドメインロジックのバリエーションを表現するには、かなり効果を発揮したのではなかろうか？

## DDDによる効果
ビジネス要求への追従スピードは爆速になったそう。

コードと業務モデルの一体化によって、ビジネス仕様 ≡ システム　の形状に。

:::note info
これによって仕様は簡単なのに、システムは非常に複雑というシステム都合で工数が多くかかるといった、見積もりの不確実さも緩和される。
:::

またチーム全体でコアドメイン部分の改善活動に取り込めるようになった。

継続的リファクタリングによって、コアドメイン部分が明らかとなり、
よりよい表現で業務ロジックを表現する活動の中で事故発生率が減少したそう。

##

# DDDによるdodaダイレクトのリビルド実践