Slide 1

Slide 1 text

実録! LOHACOにおける DDDとCleanな Architecture 2019.5.11 レガシーをぶっつぶせ。現場でDDD! アスクル株式会社

Slide 2

Slide 2 text

自己紹介

Slide 3

Slide 3 text

さとうだいすけ @dskst9 アスクル株式会社 エンジニアリングマネージャー エンジニアリングマネージャーって楽しいよというのを世の 中に広めたい DDDはエンジニアの必修科目ではないかと最近思う

Slide 4

Slide 4 text

なかむらとしゆき アスクル株式会社 LOHACOのフロントエンド(寄り)なエンジニア Kotlin + TypeScriptを嗜んでます DDD/Clean Architectureをコツコツ学習中

Slide 5

Slide 5 text

今日お話すること ● レガシーシステム刷新で ○ DDDを実践した話 ○ Clean Architectureを導入した話

Slide 6

Slide 6 text

LOHACO 「LOHACO」の由来は、Lots of Happy Communities “くらしをかるくする”をコンセプトに、暮らしを潤すこだわりの商品を、いつでもリーズナブ ルかつスピーディーにお届けする日用品ショッピングサイト

Slide 7

Slide 7 text

LOHACOの開発歴史 ● 2012年にサービス開始 ● 7年+αの歴史がある ○ 巨大なモノリシックシステム ○ 肥大化したデータベース ○ 複雑化する仕様

Slide 8

Slide 8 text

歴史は遺産となる

Slide 9

Slide 9 text

● ストラングラー・アプリケーショ ン・パターンで ○ サービス分割してモノリスか ら脱却 ○ 小さいサービスからモダンに する レガシーからの緩やかな変革

Slide 10

Slide 10 text

【最古】 モノリシック サーバ LOHACOのシステム構成変革

Slide 11

Slide 11 text

API群 【最古】 モノリシック サーバ フロントサーバ (WEB) LOHACOのシステム構成変革

Slide 12

Slide 12 text

【少し古め】 API群 【最古】 モノリシック サーバ 【現役】 フロントサーバ (WEB) 【新】 API群 【新】 カゴレジ フロントサーバ(WEB) LOHACOのシステム構成変革

Slide 13

Slide 13 text

どの世代でも悩みは同じ ● LOHACOのドメインは複雑 ○ 在庫モデル + マーケットプレイスモデル + 細かな配送日時・エリア + 生鮮販売 + 注文後精米 … などなど ● 今後も機能追加・改善は続く ● なんとか開発速度・DXを保ちたい

Slide 14

Slide 14 text

複雑なのはドメインそのもの、 すなわち、ユーザの活動やビ ジネスなのである。ドメインの 持つこの複雑さが設計で扱わ れないのであれば、基盤となる 技術が適切に考えられていた としても意味がない。 引用元 Eric Evans. エリック・エヴァンスのドメイン駆動設計 (Kindle の位置No.260-261). Kindle 版.

Slide 15

Slide 15 text

複雑さと戦う

Slide 16

Slide 16 text

複雑さへの戦略と戦術 ● 戦略 ○ 複雑さをコントローラブルにする ● 戦術 ○ ドメインモデリングを行う

Slide 17

Slide 17 text

複雑さと戦う DDD

Slide 18

Slide 18 text

その前に… DDDが難解

Slide 19

Slide 19 text

複雑さへの戦略と戦術 ● 戦術 ○ ドメインモデリングを行う ■ 貧弱なドメインモデルを許容し、軽量 DDDからDDDを理解 ■ ファーストステップは小さなサービスで 実践

Slide 20

Slide 20 text

【少し古め】 API群 【最古】 モノリシック サーバ フロントサーバ (WEB) 【新】 API群 【新】 カゴレジ フロントサーバ(WEB) 小さくDDDを始めてる半ば この辺の お話

Slide 21

Slide 21 text

ドメイン分析 - 例 引用元 ヴァーン・ヴァーノン. 実践ドメイン駆動設計 (Japanese Edition) (Kindle の位置No.1721). Kindle 版.

Slide 22

Slide 22 text

ドメイン分析 - 例 引用元 ヴァーン・ヴァーノン. 実践ドメイン駆動設計 (Japanese Edition) (Kindle の位置No.1857-1858). Kindle 版.

Slide 23

Slide 23 text

ドメイン分析 注文サブドメイン 商品サブドメイン 配送サブドメイン 在庫サブドメイン ユーザサブドメイン 受注サブドメイン

Slide 24

Slide 24 text

ユビキタス言語 ● ユビキタス言語の辞書を作った ● 次第に各サブドメインの中に閉じていった ○ 会話の中に生きている ○ ユビキタス言語を育てているとは言えない 境界づけられたコンテキストの統合で 問題が起こったのは後のお話

Slide 25

Slide 25 text

コンテキストマップ ● サブドメインから境界づけられたコンテキストを定義 ● コンテキストマップをつくりサービス分割を行った ○ 注文 ○ 配送 ○ 商品 ○ ユーザー

Slide 26

Slide 26 text

コンテキストマップから サービス分割

Slide 27

Slide 27 text

境界づけられた コンテキストの統合 ● 境界づけられたコンテキストの統合は RESTful リソースを 使用 ○ ドメイン知識をどこまで公開するべきか悩む ○ ユビキタス言語のブレに悩む ○ コンテキストの統合というより、コンテキストの密結合、 あるいは一つのコンテキストになった?

Slide 28

Slide 28 text

ドメイン分析 EC LOHACO 注文サブドメイン 商品サブドメイン 配送サブドメイン 在庫サブドメイン ユーザサブドメイン 受注サブドメイン

Slide 29

Slide 29 text

探索は 終わらない

Slide 30

Slide 30 text

引用元 https://domainlanguage.com/ddd/whirlpool/ ストーリーを語 りドメインに フォーカスして モデルを提示 探求して 間違え テストコードを 起こし洗練探求 して 間違え

Slide 31

Slide 31 text

DDDプラクティスとの付き合い 実践 課題 エンティティ 一意な識別子がないなど 値オブジェクト 集約 ❌ 集約の境界の見定めなど リポジトリ レガシーDBの相性など アプリケーション サービス Commandパターンと融合

Slide 32

Slide 32 text

レガシーな現場で 軽量DDDから得た教訓 ● レガシーDBに引きずられるな、腐敗防止層はマスト ● データモデリングを受け入れるな ● ユビキタス言語を育てないと後で泣く ● 開発当初からDDDを導入しないと辛い ● 全員がDDDをやるという認識を持つこと ドメインモデル貧血症に要注意!!

Slide 33

Slide 33 text

DDDファーストステップ所感 1. ドメインモデルの理解が進む、コードが語り始める 2. レガシーDBとはどこまで戦うかが重要 3. 即効性のあるプラクティスはどんな現場でも有効 習うより慣れろ 抽象を理解しても仕方ない DDDはやらないと具体が理解できない

Slide 34

Slide 34 text

もう少し 具体的なお話

Slide 35

Slide 35 text

その前に

Slide 36

Slide 36 text

DDD Clean Architecture 完璧に理解した人

Slide 37

Slide 37 text

私はというと・・・

Slide 38

Slide 38 text

とりあえず 本を買いました

Slide 39

Slide 39 text

引用元URL https://lohaco.jp/ksearch/?searchWord=ドメイン駆動設計

Slide 40

Slide 40 text

引用元URL https://lohaco.jp/ksearch/?searchWord=実践ドメイン駆動設計

Slide 41

Slide 41 text

引用元URL https://lohaco.jp/ksearch/?searchWord=現場で役立つシステムシステム設計の原則

Slide 42

Slide 42 text

引用元URL https://lohaco.jp/ksearch/?searchWord=clean%20architecture

Slide 43

Slide 43 text

引用元URL https://www.amazon.co.jp/dp/4048930656/

Slide 44

Slide 44 text

読んだ

Slide 45

Slide 45 text

なるほどわからん

Slide 46

Slide 46 text

とはいえ ● LOHACOのドメインは複雑 ○ 在庫モデル + マーケットプレイスモデル + 細かな配送日時・エリア + 生鮮販売 + 注文後精米 … などなど ● 今後も機能追加・改善は続く ● なんとか開発速度・DXを保ちたい

Slide 47

Slide 47 text

Cleanな Architecture とDDD を導入

Slide 48

Slide 48 text

【少し古め】 API群 【最古】 モノリシック サーバ フロントサーバ (WEB) 【新】 API群 【新】 カゴレジ フロントサーバ(WEB) LOHACOのシステム構成 さっきの お話

Slide 49

Slide 49 text

【少し古め】 API群 【最古】 モノリシック サーバ フロントサーバ (WEB) 【新】 API群 【新】 カゴレジ フロントサーバ(WEB) この辺のお話 この辺の お話

Slide 50

Slide 50 text

カゴレジフロントサーバ? ● LOHACOのカート/決済画面を表示 ● 新旧複数のAPIを呼び出す ● ビジネスロジックも含む

Slide 51

Slide 51 text

使用技術 ● Kotlin 1.3 ● Spring Boot 2.1 ● Maven

Slide 52

Slide 52 text

アーキテクチャ

Slide 53

Slide 53 text

引用元URL https://dzone.com/articles/onion-architecture-is-interesting ヴァーン・ヴァーノン 実践ドメイン駆動設計 図4-4 引用元URL https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html Onion Architecture Hexagonal Architecture Clean Architecture 依存は外から内へ

Slide 54

Slide 54 text

レイヤーを分けた 引用元URL https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html Domain Application Infrastructure Web

Slide 55

Slide 55 text

Web 依存関係 Domain Infrastructure (API) Application ※ A->BはAはBに依存することを表す

Slide 56

Slide 56 text

Web 依存関係詳細 Domain Infrastructure (API) Application MVCのController UI表示 Domainを 組み合わせる ビジネスロジック API call 実装

Slide 57

Slide 57 text

サンプル コード

Slide 58

Slide 58 text

引用元URL https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html Domain層 = Entities Domain 層

Slide 59

Slide 59 text

引用元URL https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html ※ Clean Architectureに 忠実に則るならPresenter をDIするべきだが・・・ Application層 = Use Cases Application 層

Slide 60

Slide 60 text

引用元URL https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html Infrastructure層 = Gateways Infrastructure 層

Slide 61

Slide 61 text

引用元URL https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html Web層 = Web/UI ※右図の Presenter とは違う Web 層 Web 層

Slide 62

Slide 62 text

チーム開発で Cleanな Architecture を保つために

Slide 63

Slide 63 text

工夫点1

Slide 64

Slide 64 text

外から内への 依存関係を厳守するために Maven multi-module 構成に

Slide 65

Slide 65 text

Maven multi-moduleとは lohaco
 ├─pom.xml
 ├─domain/
 | ├─src/ | └─pom.xml
 ├─application/
 | ├─src/ | └─pom.xml
 ├─infrastructure/
 | ├─src/ | └─pom.xml
 └─web/
 ├─src/ └─pom.xml
 
 プロジェクト内に サブモジュールを定義できる

Slide 66

Slide 66 text

サブモジュール間の依存関係を制御 domain を使える? application を使える? infrastructure を使える? web を使える? domain ⛔ ⛔ ⛔ application ⛔ ⛔ infrastructure ⛔ web

Slide 67

Slide 67 text

工夫点2

Slide 68

Slide 68 text

レイヤ毎に 極力 ライブラリ非依存 にする

Slide 69

Slide 69 text

『Clean Architecture』 第32章 フレームワークは詳細 「フレームワークとなん か結婚するな」

Slide 70

Slide 70 text

極力ライブラリ非依存に spring 使える? log4j2 使える? spring-web 使える? junit 使える? domain ⛔ ⛔ ⛔ application ⛔ infrastructure web

Slide 71

Slide 71 text

注: Clean Architectureと 異なる点

Slide 72

Slide 72 text

命名が違う ● Gateway -> Repositoryなど ● DDDに寄せた ● DDD寄りな命名の方が多くの開発メン バーが馴染みがあるだろうと判断

Slide 73

Slide 73 text

本家の流儀から外れている ● Application層からWeb層にDomain層の オブジェクトを返却 ○ 本家はPresenterでDIするイメージ ● 疎結合で得られるメリットと実装面・学習 面のコストを考慮して判断

Slide 74

Slide 74 text

Presenter ● Domain層のオブジェクトをUI向けに変換 する役割としてWeb層に定義 ● 実現したい役割はClean Architectureで 定義されているクラスと同じだったので名 前を流用

Slide 75

Slide 75 text

で、どうだった?

Slide 76

Slide 76 text

開発してみての感触 ● 依存関係の違反をコンパイラが怒ってくれ るのがありがたい ○ 新規メンバーが間違えにくい ○ コードレビューが楽 ● それぞれのレイヤのユニットテストも書ける (あまり書けてない)

Slide 77

Slide 77 text

失敗した点

Slide 78

Slide 78 text

依存関係ざっくり問題 ● Web層 -> Infrastructure層 への依存を許したことで ○ Web層におくべきものが Infrastructure層に置かれて ソースがカオス ○ Web層からRepository実装 を呼べてしまう Web(UI) Infrastructure (API) Application この依存は 失敗

Slide 79

Slide 79 text

ペリフェリックアンチパターン 引用元URL https://ja.wikipedia.org/wiki/%E3%83%9A%E3%83%AA%E3%83%95%E3 %82%A7%E3%83%AA%E3%83%83%E3%82%AF フランスの環 状道路 Infrastructure Web Domain Application

Slide 80

Slide 80 text

ヴァーン・ヴァーノン 実践ドメイン駆動設計 図4-4 Hexagonal Architecture サブモジュールを細かく するべきだった? ● Hexagonal Architectureでいうと ころのアダプター単位くらいで良 かったかも ● アダプター間の依存関係は当然持 たせないようにする

Slide 81

Slide 81 text

ところで DDDは?

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

即効性の ありそうな プラクティスは 取り入れている

Slide 84

Slide 84 text

Value Object ● 増田さんの提唱する型指向プログラミング ○ 言語が提供するそのままの型(String/Int)を極力使わ ない ○ 値の種類毎に ■ 独自のクラスを定義 ■ 有効な値の範囲を定義 ■ 判定・計算ロジックをもたせる

Slide 85

Slide 85 text

Value Objectの例 ※注 LOHACOは0円 サンプル商品がある

Slide 86

Slide 86 text

腐敗防止層 ● レガシーなAPIにドメイン層が引きずられないように ○ レガシーなクラス -> ドメイン層用クラスに変換 ○ 変換はレガシー具合にもよるが大変

Slide 87

Slide 87 text

腐敗防止層の例 APIのレスポンスと Domain層のオブ ジェクトをマッピング させる

Slide 88

Slide 88 text

まとめ ● LOHACOではDDD/Clean Architectureを絶 賛導入中 ● DDD/Clean Architectureはレガシーなシス テムと上手く付き合う武器となる

Slide 89

Slide 89 text

まとめ アスクルでは 一緒にDDD/Clean Architectureを 推進してくれるエンジニアを 絶賛募集中!!

Slide 90

Slide 90 text

告知 アスクル初の技術カンファレンスを開催します! https://askul.connpass.com/event/125471/

Slide 91

Slide 91 text

レガシーは 明日から モダンにはならない

Slide 92

Slide 92 text

ご静聴 ありがとうございました