Slide 1

Slide 1 text

ビジネスの構造を扱うアーキテクチャと ユーザとの接点を扱うアーキテクチャ 2019/08/30 Builderscon Tokyo 2019 末並 晃 @a_suenami

Slide 2

Slide 2 text

自己紹介 ● 末並 晃 @a_suenami ● 生息している界隈: DDDとか、TDDとか、RDBとか ● お仕事で使ってる技術スタック: Rails, React, 最近 Java とかも 少々 ● 好きな RDBMS: PostgreSQL ● 好きな制約: チェック制約 ● 好きな焼肉の部位: ハラミ ● 好きな(ry

Slide 3

Slide 3 text

インターネット上での立場

Slide 4

Slide 4 text

インターネット上での立場 ひたすら焼肉をタカられるという エンターテイメントをインターネットに提供し ています。 (焼肉を奢るとは言ってない)

Slide 5

Slide 5 text

インターネット上での立場 とはいえ、すえなみチャンスは わりと真面目に募集しています。 いろいろ教えてください。

Slide 6

Slide 6 text

今日の話 SoR と SoE

Slide 7

Slide 7 text

SoRとSoE ● SoR: System of Record ○ その名の通り、「記録」のためのシステム。 ○ 入力の事前チェックの堅牢性、データ整合性の担保などが求 められる。 ● SoE: System of Engagement ○ 利用者との関係を構築するためのシステム。 ○ 今どきの言葉を使うとよい UX を提供するためのシステム、と 言い換えてもよい。

Slide 8

Slide 8 text

SoRとSoEの対比 SoR SoE 基本的な設計観点 データ整合性 柔軟性、性能 データストア トランザクショナルな DB 多くの場合、RDB スケーラビリティがある高速なデータ ストア ドキュメント指向DB、KVS、全文検索 インデックスなど リリースサイクル SoEと比べると相対的に長い(諸説あ るかも) 高速なリリースサイクルが求められる 品質評価 トラディショナルなソフトウェアテスティ ング手法を適用しやすい トラディショナルな手法に加え、ユー ザーテスト、ユーザーインタビュー、 A/Bテストなど カナリアリリースも実トラフィックを利 用したテストと捉えることができる データ整合性 トランザクション整合性が必須 結果整合性でよい要件も多い 要するに? 堅牢なMutation 柔軟なQuery 設計を駆動する(しやすい)もの ドメインモデル、概念データモデル UI(ビジュアルデザイン、ユーザインタ ラクション)、キャッシュ

Slide 9

Slide 9 text

本発表のモチベーション ● システム特性を SoR/SoE という分類をするのは直感的によいと 思ったが、何故そう思ったかを各設計原則や設計パターンをベー スに言語化したくなった。 ● 単なるバズワードとしてではなく、どのような設計観点があり、ど のような要求に対応し、どのような品質特性を満たすべきかを捉 え直したい。 ● 現在、扱っているアーキテクチャ設計についてご紹介をしたい。

Slide 10

Slide 10 text

注意 ● SoR/SoE は物理的に分けられている必要は必ずしもなく、言語やフ レームワークが持っているモジュール化や抽象化の仕組みで十分に分 割できる。 ● 物理的に分割するべきかどうかは microservices 界隈でさんざん議論 されてるように、リリースサイクルや組織構造の問題であり、それが構 造を与えるものか、接点を与えるものかとは別問題である。

Slide 11

Slide 11 text

今日しゃべること ● モデルとは何か ● 各設計原則とSoR/SoE ● SoR/SoEの実践

Slide 12

Slide 12 text

モデルとは何か

Slide 13

Slide 13 text

https://speakerdeck.com/a_suenami/moderutohahe-deatute-he-denaifalseka-number-kichijojipm

Slide 14

Slide 14 text

モデルとは? https://ja.wikipedia.org/wiki/統一モデリング言語

Slide 15

Slide 15 text

モデルとは?

Slide 16

Slide 16 text

モデルとは? https://eng-etymo.com/archives/829#toc4

Slide 17

Slide 17 text

解決したい問題領域から 必要だと思われる情報を抽出して (逆に不要だと思われる情報を捨て) 記号化、可視化したもの

Slide 18

Slide 18 text

例: 地図 ● 方角、距離、面積などのあらゆ る変数があるなか、それを正 確に表現できているのは地球 儀のみ ○ それでも完全に正確とは言 えない ● メルカトル図法、正距方位図法 など、目的に応じてさまざまな 図法がある

Slide 19

Slide 19 text

例: 連立方程式

Slide 20

Slide 20 text

モデルの世界と現実の世界

Slide 21

Slide 21 text

エリック・エヴァンスのドメイン駆動設計

Slide 22

Slide 22 text

モデル駆動設計

Slide 23

Slide 23 text

モデル駆動設計とは ● 分析モデルと設計モデルを分けず、単一のモデルで両方の営み を実現する手法をエリック・エヴァンスはモデル駆動設計と呼び、 ユビキタス言語と並び DDD 本の中心的な主張となっている。 ● そのためにオブジェクトモデルをモデルの中心として採用するべ きだと言っているが、他のモデリングパラダイムを否定しているわ けではない。

Slide 24

Slide 24 text

第一部まとめ ● モデルとは解決したい問題のうち、必要な情報を抽出し、特徴づ け、記号化/可視化をしたものである。 ● これ自体はソフトウェア開発に閉じたものではないし、実装の方 法論というわけでもない。 ● どのようなモデルが有効であるかは当然ながら対象とする問題領 域に依存する。

Slide 25

Slide 25 text

既存の設計手法とSoR/SoE

Slide 26

Slide 26 text

[再掲] 本発表のモチベーション ● システム特性を SoR/SoE という分類をするのは直感的によいと 思ったが、何故そう思ったかを各設計原則や設計パターンをベー スに言語化したくなった。 ● 単なるバズワードとしてではなく、どのような設計観点があり、ど のような要求に対応し、どのような品質特性を満たすべきかを捉 え直したい。

Slide 27

Slide 27 text

今回扱う事例: 2-sided platform ● モール型 E-Commerce サービスを考える ● システム利用者 ○ 購買者ユーザ ○ 店舗ユーザ モール型 EC プラットフォーム 購入者 店舗

Slide 28

Slide 28 text

Clean Architecture

Slide 29

Slide 29 text

単一責務の原則(SRP) ● SOLID 原則の一つで「クラスの変更理由はひとつであるべきであ る」とする設計原則。 ● アンクル・ボブは Clean Architecture においてこの「変更理由」 をさらに「アクター」と言い換えた。 ● つまり、あるクラスやモジュールの変更は単一のアクターの変更 要求によるものであるべきである。 ● DBA や経営者もアクターの例として挙げられており、利用者だけ でなく、より広範な利害関係者を指している。

Slide 30

Slide 30 text

単一責務の原則(SRP) ● CleanArchitecture ではクラスやモジュールの設計という観点で 取り扱われているが、アプリケーション全体をある単一のアクター のためのものであると考えることも可能ではないか、というのを思 考の出発点にする。

Slide 31

Slide 31 text

しかし、素朴に分割すると…

Slide 32

Slide 32 text

分断されたモノリス!! 購買者向け システム 購入者 店舗 店舗向け システム 共通DB

Slide 33

Slide 33 text

複数のアクターの要求がDBに直撃する 購入者 出荷担当者 いつ届くの? キャンセルしたい 商品を間違ったので 変更したい 出荷しないと! 在庫が残り少ないので仕 入れ指示をしたい キャンセルされたので出 荷を止めます 「商品」「購入」などは一見ユビキタス言語かのように思われる が、多くの場合、次第に乖離し始める。 共通DB ふ、ふええ…

Slide 34

Slide 34 text

もう一度、全アクターを見てみる 経営者 オペレーター マーケティング 責任者 倉庫・物流 管理担当者 商品購入者 システム連携 クライアント 出荷 担当者

Slide 35

Slide 35 text

アクターを分類してみる 経営者 オペレーター マーケティング 責任者 倉庫・物流 管理担当者 商品購入者 システム連携 クライアント 出荷 担当者 事業者アクター 利用者アクター

Slide 36

Slide 36 text

利用者アクターと事業者アクター ● 利用者アクターは自分がやりたいことややるべきことをできるだけ 簡単にストレスなく完遂できることを望む。 ● 事業者アクターは自分たちの事業を円滑に進めること、事業上の 意思決定の支援をすること、蓄積されたデータや情報から新たな 事業を創出すること等を望む。 ● ドメインモデルと呼ばれるものは事業者アクターの視点のモデル であることが多いと感じる。 ○ それがいいことかどうかは何とも言えない。

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

中央に事業者向けのモデルがあると考える 購買者向け システム 購入者 店舗 店舗向け システム 事業者の モデル ● DB を直接共有しないため、利用者アクターのユースケースに依 存しない不変条件を維持することができる。 ● システム全体が、事業者、購買者、店舗をそれぞれの要求元とす るサブシステムに分割された。

Slide 39

Slide 39 text

勘のいい皆さんはもう気づきましたね?

Slide 40

Slide 40 text

SoR と SoE 購買者向け システム 購入者 店舗 店舗向け システム 事業者の モデル SoE SoR

Slide 41

Slide 41 text

ここまで考えると 他の設計原則やパターンとの 関連性も見えてきます

Slide 42

Slide 42 text

プレゼンテーションとドメインの分離(PDS) ● マーティン・ファウラーが提唱した、プレゼンテーションのロジック とドメインのロジックは分離するべきだとする設計原則。 https://martinfowler.com/bliki/PresentationDomainSeparation.html

Slide 43

Slide 43 text

プレゼンテーションはモデルなのか

Slide 44

Slide 44 text

再び DDD 本

Slide 45

Slide 45 text

境界付けられたコンテキストとコンテキストマップ ● エリック・エヴァンスはあるモデルが有効な範囲を境界付けられた コンテキストと呼び、その間の関係はコンテキストマップで描くべ きだと主張した。

Slide 46

Slide 46 text

ドメインとプレゼンテーションの関係 ● ドメインとプレゼンテーションの依存関係は、一般にプレゼンテー ションからドメインへの単方向依存である。 ● DDD 本ではコンテキストマップのパターンがいくつか紹介されて いるが、ドメインとプレゼンテーションのこの関係は「顧客/供給 者」パターンに最も近い。 ● 「顧客」である利用者アクターのモデルから「供給者」たる事業者 アクターのモデルに適切に振る舞いを移譲することによって、利 用者アクターのモデルはプレゼンテーション優位の状態にでき る。 ● プレゼンテーション優位なアプリケーションは適切なデータモデル (ドキュメントストア、KVSなど)を選定することによって入出力駆 動での開発を進めやすくなる。

Slide 47

Slide 47 text

再び Clean Architecture

Slide 48

Slide 48 text

ペリフェリックアンチパターン ● 中央にあるドメインを経由せずに、インフラストラクチャのコードを 直接呼び出してしまうアンチパターン。 ● パリ郊外にあるブルヴァール・ペリフェリック環状高速道路に由来 する。 ドメイン インフラストラクチャ

Slide 49

Slide 49 text

ペリフェリックアンチパターン ● アンクル・ボブは Clean Architecture においてこれをアンチパ ターンとしたが、プレゼンテーション優位な技術駆動アーキテク チャを選択する場合は、むしろ立派な実装パターンであると言え る。

Slide 50

Slide 50 text

CQRS https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf

Slide 51

Slide 51 text

CQRSとの関係

Slide 52

Slide 52 text

CQRSとの関係 ● SoR/SoE という分類と Command と Query の非対称性に着目し た分離(=CQRS)は共通している部分が多く、得られる恩恵も近 い。 ● Command のモデル(≒ドメインモデル)から Query のモデルへ の変換の責務をどこが担うかという違いはあるような気がする?

Slide 53

Slide 53 text

Command/QueryとSoR/SoE SoR SoE Command いわゆる DDD というものが最 も活躍する領域となる。 入力値のみから可能なバリデーショ ンを行い、具体的な振る舞いをSoRに 移譲する。 現在の状態に依存するバリデーショ ンが必要な場合は、それもSoRへ移 譲する。 Query リソース指向、あるいはドメイン ロジック由来の集約を単位とす るデータ構造での参照のみで きる。 RDBのマテリアライズドビューやサマ リーテーブル、ドキュメントストア、 KVS、検索インデックスなどの具体的 実装技術への依存を受け入れること によって性能、柔軟性、開発速度など を向上させることができる。

Slide 54

Slide 54 text

第二部まとめ ● SoRは事業者アクターを要求元とするドメインモデルをもとにした アプリケーション、SoEは利用者アクターを要求元とするプレゼン テーションモデルをもとにしたアプリケーションと捉えることができ るのではないか。 ● これは、Clean Architecture において主張された SRP の定義を 発端に、PDS、境界付けられたコンテキストとコンテキストマップ、 CQRS等、既存の設計原則や設計パターンで説明することができ る。

Slide 55

Slide 55 text

第二部まとめ ● プレゼンテーションモデル優位の場合は設計を入出力に駆動さ せやすく、ドメインロジックを必要としないことが多い。 ○ ペリフェリックパターンは、 Clean Architecture においてはア ンチパターンとして紹介されているが、具体的実装技術に駆 動させやすいアプリケーションにおいてはむしろ立派な実装パ ターンと言えるのではないだろうか。 ○ 実際、Greg Young の主張する CQRS パターンはそういう設 計・実装パターンである。

Slide 56

Slide 56 text

SoR/SoEの実践

Slide 57

Slide 57 text

簡易アーキテクチャ図 ユーザ Cache Store CDN Pub/Sub Topic Master Database Subscribe Command SoE SoR

Slide 58

Slide 58 text

設計観点 ● バリデーション ● 整合性 ● 採番 ● 状態管理 ● キャッシュ

Slide 59

Slide 59 text

バリデーション

Slide 60

Slide 60 text

[再掲] Command/QueryとSoR/SoE SoR SoE Command いわゆる DDD というものが最 も活躍する領域となる。 入力値のみから可能なバリデーショ ンを行い、具体的な振る舞いをSoRに 移譲する。 現在の状態に依存するバリデーショ ンが必要な場合は、それもSoRへ移 譲する。 Query リソース指向、あるいはドメイン ロジック由来の集約を単位とす るデータ構造での参照のみで きる。 RDBのマテリアライズドビューやサマ リーテーブル、ドキュメントストア、 KVS、検索インデックスなどの具体的 実装技術への依存を受け入れること によって性能、柔軟性、開発速度など を向上させることができる。

Slide 61

Slide 61 text

バリデーション ● バリデーションと一般に呼ばれるものにも種類がある。 ○ 入力値のチェック(長さや範囲、正規表現マッチなど) ○ その事業において必要な不変条件 ○ Ruby の ActiveRecord 実装が(ry ● 構造的に自明だが、前者は後者の制約より同等かそれより厳しく なければならない。 ● 現在状態に依存せず、値のみで可能な入力チェックは SoE で可 能であり、そのほうが利用者に対してよい UX を提供できる可能 性が高い。 ○ JavaScript によるリアルタイムバリデーションなど

Slide 62

Slide 62 text

バリデーション

Slide 63

Slide 63 text

バリデーション ● バリデーションに関して重複を排除したいと考えた場合、基本的 に誤った共通化の可能性を考えたほうがよい。 ○ そういう意味では SoR と SoE が物理的に分割されているほう がよいケースもある。 ○ サーバーサイドと同じバリデーションを JavaScript でもやるこ とに違和感を感じる人は多くないと思う。 ● SoR でドメインモデルを構築している前提であれば、不変条件は 独自型(ValueObject, etc)になり、コンパイラの恩恵も受けられ る。

Slide 64

Slide 64 text

整合性

Slide 65

Slide 65 text

以前、発表したやつ https://speakerdeck.com/a_suenami/soe-akitekutiya-number-kichijojipm

Slide 66

Slide 66 text

グローバルな整合性とユーザローカルな整合性 ● SoR 的世界観ではシステム全体、あるいは連携システムも含め た全世界(大げさ)で不整合がないことが求められる。 ● 一方、SoE 的世界観ではそれを利用する利用者一人ひとりが自 分自身の世界を持っており、それがその人にとっては世界のすべ てである。

Slide 67

Slide 67 text

グローバルな整合性とユーザローカルな整合性 ● SoR / SoE 間の疎結合性や耐障害性を高めるために、基本的に 非同期、結果整合性でのアーキテクチャを検討するといいかもし れない。 https://speakerdeck.com/a_suenami/soe-akitekutiya-number-kichijojipm?slide=16

Slide 68

Slide 68 text

[再掲] Command/QueryとSoR/SoE SoR SoE Command いわゆる DDD というものが最 も活躍する領域となる。 入力値のみから可能なバリデーショ ンを行い、具体的な振る舞いをSoRに 移譲する。 現在の状態に依存するバリデーショ ンが必要な場合は、それもSoRへ移 譲する。 Query リソース指向、あるいはドメイン ロジック由来の集約を単位とす るデータ構造での参照のみで きる。 RDBのマテリアライズドビューやサマ リーテーブル、ドキュメントストア、 KVS、検索インデックスなどの具体的 実装技術への依存を受け入れること によって性能、柔軟性、開発速度など を向上させることができる。

Slide 69

Slide 69 text

整合性 ● リクエスト可能かどうかに応える(可能な場合は一定期間ロックを とる)エンドポイントを SoR から提供し、そこは同期的に結果を返 すようにする。 ● 決済処理における与信(オーソリ)と確定(キャプチャ)の関係。

Slide 70

Slide 70 text

採番

Slide 71

Slide 71 text

採番 ● コマンドを結果整合性に寄せた場合、SoE はその完了を知ること ができなくなる。現実的には、ポーリングか Pub/Sub、あるいは 何らかの画面レンダリングをフックに実データを問い合わせる形 になるが、そのときのキーはリクエスト完了時には確定している 必要がある。 ● 実装パターンはいくつかある。 ○ 採番のみを行うエンドポイントを SoR が提供する。 ○ コマンドリクエスト完了時に同期的にキーを返す。 ○ UUID など、SoE 側で採番可能な採番体系を選択する。

Slide 72

Slide 72 text

採番 ポーリングモデル

Slide 73

Slide 73 text

採番 Pub/Subモデル

Slide 74

Slide 74 text

状態遷移・状態管理

Slide 75

Slide 75 text

状態遷移・状態管理 ● SoE のベースにあるのは特定の利用者アクターにとってのモデル なので、SoR が持つ事業全体の状態遷移のモデルとは基本的に 異なる。 ● SoR の状態遷移の一部だけが利用者にとっての関心領域であ り、SoE にその複雑さを持ち込まないようにする。

Slide 76

Slide 76 text

状態遷移・状態管理 購入者 下書き レビュー待 ち 公開済み レビュー中 商品特集記事状態遷移 購入者の関心領域

Slide 77

Slide 77 text

状態遷移・状態管理 ● 実装としては、RDB のビュー、別のテーブルやデータストアに保 持するといったいくつかのパターンがある。 ● 物理的に分離する場合は、採番後の実データ問い合わせと同 様、ポーリングや Pub/Sub 等で状態を最新に保つ工夫をする必 要がある。

Slide 78

Slide 78 text

キャッシュ

Slide 79

Slide 79 text

キャッシュ ● キャッシュは基本的に SoE の関心時だと心得る。 ● SoR 側の構造に引きずられないように、あくまで利用者の UX を ベースに考える。 ○ ネイティブアプリや SPA (Single Page Application) のように サーバーサイド API とクライアントが分離されている場合はク ライアントがキャッシュしたい単位でエンドポイントや JSON 構 造を設計する。 ○ 難しい場合は BFF (Backend For Frontend) の導入も検討す る。

Slide 80

Slide 80 text

[再掲] 簡易アーキテクチャ図 ユーザ Cache Store CDN Pub/Sub Topic Master Database Subscribe Command SoE SoR

Slide 81

Slide 81 text

キャッシュ キャッシュ指向のJSONオブジェクト設計

Slide 82

Slide 82 text

キャッシュ ● キャッシュとそのリフレッシュに対する戦略はいろいろ考えられ る。 ○ キャッシュしない(毎回、SoR へ問い合わせる) ○ Pub/Sub によるリフレッシュ ○ Expire を待つ(一時的な不整合を許容する) ○ etc...

Slide 83

Slide 83 text

まとめ ● アプリケーションの要求元を事業者と利用者に分け、そのそれぞ れについてモデルを構築し、実装を考えると、それは一般に SoR / SoE の特性と呼ばれているものと一致する。 ● バリデーション、整合性、採番、状態管理、キャッシュなどの具体 的実装について、SoR / SoE のシステム間連携をどのように行う かの事例を紹介した。

Slide 84

Slide 84 text

まとめ

Slide 85

Slide 85 text

まだまだ試行錯誤している最中なので ぜひいろいろ議論したいです。 よろしくお願いします。