Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
フロントエンドのモデルに境界を引く
Search
baby
October 12, 2026
390
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
フロントエンドのモデルに境界を引く
フロントエンドカンファレンス関西2026スライド
baby
October 12, 2026
Featured
See All Featured
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
870
We Are The Robots
honzajavorek
0
390
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
2
6.3k
Being A Developer After 40
akosma
92
590k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Navigating Weather and Climate Data
rabernat
0
550
Prompt Engineering for Job Search
mfonobong
0
500
Raft: Consensus for Rubyists
vanstee
142
7.7k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
Amusing Abliteration
ianozsvald
1
330
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Product Roadmaps are Hard
iamctodd
55
13k
Transcript
フロントエンドのモデルに境界を引く
⾃⼰紹介 Hiroki Mizoguchi Front-End Developer at KINTO Technologies X:@babywkb GitHub:babywkb
blog:https://babywkb.hatenablog.com/
開発環境 システム • • • BEから受け取った状態に応じて、UI の表⽰‧操作が変わる BEは状態を返し、表⽰や操作の可否 はFE側で判定することも多い 稼働中のシステムの保守開発
組織体制 • • • • FE/BEでロールが分かれ、それぞれ 開発している エンジニアはチーム開発で複数⼈が 同時並⾏でシステムに変更を⼊れる システムによって業務を遂⾏する担 当者が別途存在する 業務に詳しい⼈とは⽇常的には話さ ないが、要件定義などの場で質問‧ 確認はする
Q. システムの仕様を変える時 「どこを変えればいいか」「誰と合意が必要か」 すぐ答えられますか?
⽇々の開発の課題感 • 仕様変更のコストが重い... ◦ ◦ ◦ ◦ ◦ 変更すべき箇所の洗い出しに時間がかかる 認識齟齬からの対応漏れ
画⾯要件がビジネス要求に整合しているのかの確認が難しい BEとFEの実装が整合していない 誰がどの部分の仕様を決めているのかわかりにくい 判定が画⾯ごとに散らばっていて、どこに何があるか追いきれない。 その判定がデザインの都合なのか業務の決まりなのかわからない。 エンジニア内外のコミュニケーションのコストが⾼い。
実装速度の向上でよりハードに ⽣成AIによって実装のアウトプットが加速することで、 既存の挙動や要件について深く理解する余裕なく実装がどんどん出てくる コードレビューで顕著... もっとスムーズにシステムの挙動‧業務仕様の共通理解を作りたい
なぜ共通理解が作りにくいのか? 仕様の関⼼にはレイヤーが混在しているかも...? • • • • 業務:ユーザーに何をさせてよい 体験:何をどう認知させるか 表現:どこでどう⾒せるか etc…
関係者との会話でも、コードレビューでも、 層が混ざっていると何を判断すべきかが分からず、認知負荷が上がる
ごちゃまぜの関⼼を紐解く 仕様の関⼼が混ざっている現状を紐解くために、 まずは⼟台にある「業務」の層から捉えたい... ドメインモデルを把握しにいこう
ドメインモデルとは
ドメインモデルとは ドメインモデルは実装そのものを指すわけではない(コードで表現することは強く推奨されるが) 特定の⽂脈における業務知識を、意味のある構造として表したもの 業務概念、規則、振る舞いを問題解決に使える形で表したもの
ドメインモデルとは 業務知識‧モデルの完全なものがいきなり出てくるわけでもないので 対話やドメインモデルのテストを書くなどしてドメインモデルを育てていく
ドメインモデルとは システムが表現する対象であり システムの正しさを判断する基準であり システムをつくることを通じて更新されうるもの
ドメインモデリングを始めたいが 業務を理解し、システム内の整合も取れる素晴らしい取り組み とはいえ...
ドメインモデリングをするには体⼒がいる • • 関係者を広く巻き込む ◦ 業務担当者、PdM、BE、デザイナー、FE、QA 時間を取って会話を重ねる ◦ ヒアリング、⽤語を揃える、実装&テスト、⽭盾や不⾜の確認 ⼿ぶらでいきなり動きにくい...
現実的な⼊⼝を探す なにかできることはないか... フロントエンドで業務の知識の理解と整理を深められないか? フロントエンドからドメインモデリングのきっかけを作れないか?
フロントエンドのモデルという⼊⼝
フロントエンドのモデルとは 画⾯の表⽰制御に混ざっている判断‧知識を、 概念‧規則‧振る舞いとして表したモデル 含むもの「何を決めているか」 • ⾒せ⽅のための決め事 • 業務ルールの適⽤ 含まないもの「どう描くか」 •
表⽰制御(表⽰/⾮表⽰、活性/⾮活性、⾊や⽂⾔の出し分け)
フロントエンドモデルの例 「ECサイトの注⽂確認画⾯サンプル」 • • 購⼊者向けの配送段階を6段階から4段階に丸める(⾒せ⽅の決め事) 注⽂のキャンセル可否の判定(業務ルール)
画⾯の中にある判断をモデルとして抜き出す
フロントエンドモデルだけでも⼗分価値はある モデルは画⾯に依存していない判断なので、画⾯‧UI部品を横断して利⽤可能
フロントエンドモデルからドメインモデルの仮説を⽴てる フロントエンドモデルからシステム全体のドメインモデルの仮説を⽴てる。 仮説を元にドメインモデルのためのコミュニケーションを重ねる フロントエンドモデル 画面から切り出した概念・規則 規則を抽出 ドメインモデルの仮説 既存の場で確認 ドメインエキスパートと会話 仕様レビュー・問い合わせ
複数画面に出現・食い違い
仮説を持ち込み、コンパクトにモデリングを始める 場を設けて⼀から掘り起こすことで、未知の概念‧例外まで広く拾えるが、 関係者を集めて時間を多く取る必要がある。 エンジニアから仮説を持ち込むことで、 要件定義や開発中の仕様確認の場で、簡潔にモデルについて会話できる。 ⼿ぶらではいきなり動きにくいが、 仮説を持ち込むことで、コンパクトにモデリングを始められる。 最終的には確認の中で⾒えた⾷い違いが、本格的なモデリングの場につながっていく。
フロントエンドモデルの 実装フロー&実装イメージ
1. UI制御の中の判断を洗い出す やること:既存の表⽰制御の中にある判断を洗い出す 対象:1つの画⾯または1つの機能ずつ 注⽬する箇所 • • 表⽰の分岐(条件付き描画、ラベルの変換) ⼊⼒の制御(検証、送信できるかどうか、ステップの進⾏) すべてのif⽂など判定系の処理を関数に切り出して関数名をつけてしまうのがオススメ
2. 判断が答える問いを明らかにする 各判断について、「この分岐は何を決めているのか」を⾔語化する 主語述語がモデルの設計図になる やること 例 0 元の関数名 キャンセルボタンを活性にするか 1
UI部品の⾔葉を外す キャンセルできるか 2 主語を判断の対象にする この注⽂はキャンセルできるか
3. モデルを実装する-APIレスポンス型API レスポンスは通信回数の省略や他システムとの共通化など、 ドメインモデルとは無関係の都合で構造が決まることも多々ある // APIレスポンス(通信の都合で決まる形) export type OrderDetailResponse =
{ id: string; status: | "PENDING_PICKING" | "PICKING" | "PACKED" | "SHIPPED" | "DELIVERED" | "CANCELLED"; // 注文の状態とは別に進む(キャンセル後も返金中がありうる) paymentStatus: | "AUTHORIZED" | "AUTHORIZATION_FAILED" | "CAPTURED" | "REFUNDING" | "REFUNDED"; shippingAddress: 略; items: 略; totalPrice: 略; };
3. モデルを実装する-フロントエンドの概念型へ変換APIレスポンス型を、必要な概念の型に変換する(腐敗防⽌層) ルールが使わない⽀払い状態‧お届け先‧商品‧⾦額は持ち込まない // 概念:注文の状態(ドメインモデルの仮説) export type OrderStatus = |
"PENDING_PICKING" | "PICKING" | "PACKED" | "SHIPPED" | "DELIVERED" | "CANCELLED"; // 概念:注文 export type Order = { id: string; status: OrderStatus }; // 腐敗防止層:APIの形から、ルールが使う概念だけを取り出す export const toOrder = (r: OrderDetailResponse): Order => ({ id: r.id, // APIのenumが増えたら、ここでコンパイルエラーになる // 状態の分け方がAPIと食い違ったら、ここで対応づけを書く status: r.status, });
3. モデルを実装する-規則を定めて振る舞いを作る// 概念:判定結果と理由 export type CancelReason = "fulfillmentStarted" | "alreadyCancelled";
export type CancelDecision = | { can: true } | { can: false; reason: CancelReason }; // 振る舞い:規則に従って判定結果を出す // 規則:出荷作業(ピッキング)の開始前ならキャンセルできる export const decideCancel = (order: Order): CancelDecision => { switch (order.status) { case "PENDING_PICKING": return { can: true }; case "PICKING": case "PACKED": case "SHIPPED": case "DELIVERED": return { can: false, reason: "fulfillmentStarted" }; case "CANCELLED": return { can: false, reason: "alreadyCancelled" }; default: // statusが増えたらコンパイルエラーで気付ける return order.status satisfies never; } };
3. モデルを実装する-責務を分けるContainer(OrderDetailContainer) API呼び出し → toOrder:概念へ変換 → decideCancel‧toDisplayPhase:判定 概念の型だけを渡す CancelDecision‧DisplayPhase Presentational(OrderDetail)
statusの値を知らず、受け取った判定を表⽰‧操作の制御に変換する
3. モデルを実装する-Containerで組み⽴てる// Container:API呼び出しとモデルへの変換を担う export function OrderDetailContainer({ orderId }: { orderId:
string }) { const res = useOrderDetailQuery(orderId); // Suspense前提でデータを返す const order = toOrder(res); } return ( <OrderDetail phase={toDisplayPhase(order)} cancel={decideCancel(order)} onCancel={() => cancelOrder(order.id)} /> );
3. モデルを実装する-判定結果でUIを制御する// Presentational:概念の型だけを受け取り、 statusの値は知らない type Props = { phase: DisplayPhase;
cancel: CancelDecision; onCancel: () => void; }; const reasonLabel = { fulfillmentStarted: "出荷準備が始まったため、キャンセルできません ", alreadyCancelled: "この注文はキャンセル済みです ", } satisfies Record<CancelReason, string>; export const OrderDetail = ({ phase, cancel, onCancel }: Props) => ( <section> <DeliveryProgress phase={phase} /> <button disabled={!cancel.can} onClick={onCancel}> 注文をキャンセル </button> {!cancel.can && <p>{reasonLabel[cancel.reason]}</p>} </section> );
4. フロントエンドモデルをルールの所有者で分類する このルールは、誰が決めている? 仮説を⽴てるために、フロントエンドモデルをルールの所有者で分類する 所有する 所有しない 画⾯の⾒せ⽅の都合で決められる 普遍的な業務ルールに従っている 例:配送段階を6段階から4段階に丸める 例:注⽂をキャンセルできるか
4. ルールの所有者を確認する問い 普遍的なルール(業務ルール)に従っているのか • • • 「『なぜそうなっているのか』の答えは、画⾯の外にある?」 「変えるとき、誰の合意が必要か?」 「無視したら何が壊れるか?」
4. ルールの所有者を確認する問い 問い キャンセル可否 配送状態の段階表⽰ なぜ?の答え ピッキング以降、棚に 戻すのは労⼒がかかる から 購⼊者がわかりやすいから
変更に誰の合意が必要か 物流‧配送コスト管理 者 デザイナー 無視したら何が壊れるか 出荷作業 ユーザーのわかりやすさ ルールを所有するか 所有する 所有しない
ルールの所有判定とドメインモデル仮説の関係 ルールをフロントエンドで所有しないフロントエンドモデルは ドメインモデルの仮説になる
所有しないルールを仮説にして、会話する 仮説を元にドメインモデルのためのコミュニケーションを重ねる フロントエンドモデル 画面から切り出した概念・規則 所有しないルールを抽出 ドメインモデルの仮説 既存の場で確認 ドメインエキスパートと会話 仕様レビュー・問い合わせ 複数画面に出現・食い違い
現在地
フロントエンドモデルを段階的に切り出し中 システム全体への導⼊はまだ。段階的にモデルを抽出&実装中。 • 仕様変更のタイミングで既存画⾯のリファクタから⼊る ◦ ◦ • 既存の画⾯の挙動や業務ルールを理解する⾒返りが⼤きい ドメインエキスパートとコミュニケーションを取れる場が多い 画⾯単位で切り出し、重複は⼀時的に許容
◦ ◦ 画⾯横断の概念をいきなり⾒つけるのは難しく、浸透もしにくい 共通化を急がず、モデルを横断⽐較し重複を発⾒ -> 共通化のプロセスにする
ルールの所有元による区別 • 開発フローにはまだ組み込めていない ◦ ◦ • 所有の仕分けは、明確な開発⼿順として定められていない 開発フローを重くしすぎずまずはモデル化を浸透させたい それでも、所有する/しないの区別は格段につけやすくなった ◦
開発フローとしてルールにはしていないが、ドメインエキスパート‧デザイナー‧BEなど FE以外の関係者へシステムの規則について会話‧確認するきっかけが増えている
層の分離により、レビューがしやすくなった • ⼈によるレビュー ◦ ◦ ◦ • 関⼼事が絞られ、どの層の変更かがすぐわかる(所有の有無を問わない) 特にテストコードが読みやすい 業務のどういう状態のケースを実装しているのかが見えやすくなる
AIによる実装‧レビュー ◦ コンテキストが限定され、提案や指摘の精度が体感で上がった
最終的に⽬指す状態 • • • 業務の決まりや仕組みを変える時、直す場所と確認相⼿がわかる 規則の変更が1箇所で済む状態へ(画⾯ごとのモデルを徐々に共通化し、 重複を排除) フロントエンドのモデル実装から、関⼼を持つべきドメインモデルを読み 取れる状態へ
課題・難しさ
課題‧難しさ① フロントエンドモデルにするべき対象の抽出⾃動化
フロントエンドモデルにするべき対象の抽出⾃動化ができ ていない モデルにしたいのは表⽰の形式ではなく「意味」 変換の性質 例 実装したい場所 文言・ロケール・装飾だけ PENDING_REVIEW → "審査待ち"
表示制御処理・プレゼンテーション な実装の近く 画面固有の見せ方 PENDING_REVIEW → バッジ色、説 明、ボタン状態 表示制御処理・プレゼンテーション な実装の近く クライアントの概念への意味 変換 PENDING_REVIEW と QUEUED を「処 理待ち」として統合 フロントエンドモデル サーバーの都合を隠し、クラ イアント独自の状態体系を作 る API状態から Editable / AwaitingResult / Completed を 構成 フロントエンドモデル
フロントエンドモデルにするべき対象の抽出⾃動化 • 「意味」の抽出は⾃動判定しにくく、開発者のスキルに依存している • 「表⽰の形式」と「表⽰に依存しない意味」境界を機械的に判定できない • 分類はシステム外の合意が不要なので、AIで⾃動化したい ◦ モデルの賢さに任せても⾃動化できる⽔準に到達するかも
課題‧難しさ② AIによるドメインモデルのテスト⽣成
AIによるドメインモデルのテスト⽣成 期待 モデルのテストを書く中で、業務との不整合や検討不⾜に気付ける 現実 テストはAIに⽣成させ、⼈間が評価するのが主流 AIは業務上ありえないケースも、説明付きでもっともらしく書く 他システムやドメインエキスパートへの確認が省かれやすい 対策 もっともらしいテストを鵜呑みにせず、知らない知識は確認に回す
課題‧難しさ③ 明らかになったドメインモデルの全容を残す場所
フロントエンドの実装だけでは不完全なドメインモデルし か表現できない フロントエンドはドメインモデルの振る舞いのうち、 状態変化をバックエンドに委ねて⾃分で実装を持たないケースが多い
フロントエンドの実装だけでは不完全なドメインモデルし か表現できない 規則はフロントでも使うが、 状態の変更はデータの永続化を担うバックエンドに任せることが多い
システム全体のドメインモデルをどこに記録するべきか フロントのコードでは、仮説は⽴てられても確認済みの全体像は残せない FEが「どの規則を、どの程度の厳密さで使っているか」まで残したい... 記録先の候補 欠点 ドキュメント 陳腐化しやすい 結合テスト ドメインモデルの構造を把握しにくい BEのコード(本来はベスト)
FEエンジニアから参照しにくく実装に手が出せない
まとめ
まとめ • UIに混ざった判断を、フロントエンドのモデルとして切り出す • FEが所有しないルールを、仮説としてBE‧ドメインエキスパートと確認する • 始めるなら、確認や会話の機会が多い仕様変更のタイミングがよい • 関⼼事が絞られ、⼈とAIのレビュー負荷が下がる •
課題:抽出の⾃動化 / AI⽣成テストの検証 / ドメインモデルの記録先
なぜ、境界を引くのか AIでコードを変えるのは容易になり、 システムを変えて、反応を⾒て、また変えるループはより⾼速化している システムをAIで⾼速に変える中で、 業務の決まりのような合意形成が必要な部分を無⾃覚に変えないようにしたい 業務の決まりを変える場合は安全に素早く変えたい フロントエンドのモデルに境界を引くのは、 システムを⾼速に変えながら、守るべきルールを⾒失わないため。
FAQ
BEでドメインモデルが実装されていれば不要では? UXのために、ユーザーができること‧できないことを表現する都合、FEにも ドメインモデルの規則を利⽤‧実装する部分は発⽣する。 BEのドメインモデルが全体像になるが、FEがドメインモデルのどこを完全or 部分的に利⽤しているかをFEのモデル化によりわかりやすくすることで、BE のドメインモデルの変化をFEに反映させやすくなる。 逆に、FEやデザインだけの判断だけでドメインモデルを変えてはいけないこと にも気付くことができる。 「FEが所有しない」ルールであることにFEが気づける状態を作ることに価値 がある。
実⾏できる操作をAPIから受け取ってBEに判断させれば? 返し⽅次第。フラグの羅列は避けたい。 ありえない状態を表現できない形で返せるならアリかも(OpenAPIのoneOf などで⼯夫?) 実態は is〇〇 フラグの羅列が多く、業務上ありえない組み合わせも表現できて しまう → 結局FEが判断を負うケースが多い。
APIからレスポンスの状態ごとに実⾏可能な操作⼀覧を返す設計もあるが、⼀ 般的ではないイメージ...
どのプロダクトでも取り⼊れるべき? ドメインモデルをFEから⼿軽に始められるとはいえ、コストがかからないわけでは ない。 ドメインモデルを想定外に変えるリスクを避けられるという恩恵が得られないほど ドラスティックにドメインが変わる領域(0->1スタートアップやPoC)ではFEのモデ リングから必要はないかも。
業務判定を共通関数にするのと何がちがう? 関数に切り出すという点は同じ。 概念型から別の概念型への変換として実装することで、ロジックが何の業務概 念に属し、どんな値しか取り得ず、どんな操作だけが許されるかを表現できる 点で違いがある。
参考
参考⽂献‧セッション‧記事 DDD on the frontend - Talysson Oliveira Cassiano -
DDD Europe 「オブジェクト指向UIデザイン──使いやすいソフトウェアの原理」- ソシオメディア株式会社,上野学,藤 井幸多 著 上野学 監修 「ドメイン駆動設計をはじめよう―ソフトウェアの実装と事業戦略を結びつける実践技法」Vlad Khononov 著、増⽥ 亨、綿引 琢磨 訳 「関数型ドメインモデリング ドメイン駆動設計とF#でソフトウェアの複雑さに⽴ち向かおう」 Scott Wlaschin (著), 猪股 健太郎 (翻訳)