SPAでのレイヤードアーキテクチャの考察と不確実性へのマインドセット
#設計 #宣言的UIの設計レシピ #アーキテクチャ
モジュラフロントエンドのメモ を読んだkoushisa.iconの感想と、フロントエンドのレイヤードアーキテクチャについての紐解き
ここでのレイヤードアーキテクチャとは、Repositoryとかサービス(Service)みたいなDDDの戦術由来の概念のこと
結論
Render As You Fetchパターンがインフラストラクチャレイヤを置き換える
Webフロントエンドのメンタルモデル再構築
ほとんどのレイヤードアーキテクチャは問題空間の定義に一貫性や集合知を形成しきれず破綻する
戦略の失敗は戦術で補うことはできない
プレゼンテーション層におけるドメインとは、ユーザーが期待する振る舞いの構築である
ユーザーインタフェースにおける問題提訴と問題空間と問題解決
レイヤリングはアプリ全体ではなくシナリオやユースケース単位で行うとよい
→SVO型のパッケージングで機能的凝集を目指すオニオンアーキテクチャ
関連: 日本の開発者、まだClean Architectureで消耗しているの?
---
追記
少なくともkoushisa.iconの観測範囲では、Render As You Fetchパターンを使っていればSPAの実装をレイヤー化して冗長化する必然性がない
スコープは小さいに越したことはない
クリーンアーキテクチャの功罪
もし2022年以降のSPAのデータアクセス周りでレイヤードアーキテクチャを取り入れようか悩んでる人がいたとしたら、一度立ち止まって思い直して見てほしい
データ取得ライブラリを SPA に導入するとなぜ嬉しいのか
本当に欲しいのは「それがなにか」(What)と「どうするか」(How)の分離なのかもしれない
GUIのデータアーキテクチャと状態管理の変遷
歴史は繰り返されており、どの時代でも同じ傾向や原則がある
WhatとHowの分離
副作用とドメインを切り離す
技術の螺旋がどう回っているか
いまはZustandやAtomic State ManagementでSuspense使えば大体なんとかなる
super simple codeを目指したい
SPA以外の選択肢もある
戦略の失敗は戦術で補うことはできない
App Routerとか、AstroやCloudflare Workersでマイクロフロントエンドの選択肢もある
関連: Rich Harris on frameworks, the web, and the edge
外部への複雑な依存関係を持つ外部サービスとか、データアクセスをマッシュアップするのが主であるようなサービスであれば、インタフェースの後方互換性を維持する目的でのRepositoryはアリかもしれない
ここに関してもGraphQLやAtomic State Managementなどがある
Atomic State Managementは後方互換性を保ちやすい
知らない技術を採用するのが恐いというハードルの高さはあるかもしれないが、試してみて向き合うしかない
アイデアの価値は「検証」してみないとわからない
開発期間をnとすると新技術によるコスト削減量はO(n)
積極的な技術選定と消極的な技術選定
隣の芝生へ積極的に片足を踏み入れる
ここから本題
複雑性を緩和することを目的としてReactでレイヤードアーキテクチャはペイするのか
サーバーと違い、フロントエンドには長く残すべきドメインモデルのようなモデルはない
フロントエンドの関心は UI とそれにまつわる必要な処理だが、それらは頻繁に変わる。フロントエンドでの短命のモデルに変更を加え続けるよりも、レイヤーやモデルの存在を気にせず E2E でべた書きした方が将来の保守性・実装速度が上という状況はあり得る。短命なモデルしかないフロントエンドに、レイヤードアーキテクチャはどの程度役に立つのだろうか。
領域全体を常にすぐに把握しやすい状態に保つことができれば追加実装しやすい。レイヤードアーキテクチャの欠点はボイラープレート的コードが必要になることと、E2E での把握がしにくくなることだ。フロントエンドではJSON色付け係という言葉があるようにサーバーから取得したデータをユーザーに見せる処理で完結する場合も多く、その中間のロジックもあまりないので技術的詳細を隠蔽してもあまりうれしくない。フォームをはじめユーザーに操作してもらうところも多いが、こちらも HTML の仕様と強く結びついているので隠蔽の旨味は少ないと思う。
「短命なモデルしかないフロントエンド〜」の下りはまさに同意koushisa.icon
レイヤを作ったとしてもどこかで、「これ本当に必要?」となりがち
「実装の迷いを減らしたい」について
共通化と抽象化
宣言的UIのデータアーキテクチャはコンポーネントを中心に考える
そうであれば、むしろレイヤーを取っ払って、データ取得と表示を近くに書いてみたらどうだろうか。ボイラープレートが減って E2E での把握もしやすい、把握しやすくミニマムなコードができるのではないか。(ドメインモデルがあるような普通のサーバー的には失格かもしれないが)
→Render As You Fetchパターン
フロントはJSON色付け係に徹するとジュニアや片手間フロントエンドでも把握しやすいコードベースになる
もちろんUI/UXの要求で複雑なインタラクションや状態のケースパターンが増えるときはあるのだが...
以下のような思想とも似ている
Next.jsのgetServerSideProps
Remix
Fullstack Components
今の実装(の一部分)を捨てて作り直すすることに躊躇しなくなると何がうれしいか。フロントエンドで(一部分の)実装を捨てるという事態は、負債解消や機能追加等の実装上の理由だけでなく、UI デザインの変更や検証で部分的に作り変える、という理由でも起きる。
むしろ、現実の使い捨て製品のように、捨てるコストが低い方が運用の柔軟さに勝り、実装や UI デザインの試行錯誤や改善が行いやすい。
わかるkoushisa.icon
たとえば、ちょっとした買い物でも、抗菌・消臭などの付加価値がある高級な消耗品を買うぐらいなら、1ヶ月スパンごとに百均で新品を買いなおすほうがもろもろコストがいいしキレイだし気分もいいみたいな
UIをインクリメンタルに考える
捨てる前提で作ると運用しやすい
hooksはUIを捨てるときの影響範囲を最小限にするための抽象化として捉える
コンポーネントのデータアクセスをカスタムフックでラップするメリット
経年劣化に耐える ReactComponent の書き方
参照記事系
microCMSのWebフロントエンドにクリーンアーキテクチャを採用した話【前編】
microCMSのWebフロントエンドにクリーンアーキテクチャを採用した話【後編】
Webフロントエンド再設計: レイヤードアーキテクチャの導入 ~ 高品質なコードを実現するために ~ #再設計
一休.com 宿泊管理システムのフロントエンド設計と改善の変遷 - Developers Blog
フロントエンド におけるレイヤードアーキテクチャの導入
フロントエンド API通信戦略
ウェブフロントエンドの設計力を高めるためにアプリケーションの構造を捉えてみる話
/mrsekut-p/React Hooks指向のfrontendのarchitectureを考える
フロントエンドで長持ちするプロダクトを開発するための心構え
フロントエンドとSPA職人の目指したものの歴史と概略
@occar421: SPA のサーバー通信では何かのアーキテクチャを入れる前にまずデータ取得ライブラリの導入を検討してよというお気持ちになる。
@Nkzn: React + Layered Architectureの試み、自分の中では5年前にチャレンジして筋が悪いという結論が出ちゃったんだよな
https://t.co/Us7VgpdvkQ
#Almin.js
@okunokentaro: クリーンアーキテクチャ採用する前にまずクリーンなコードを書くようにしよ。
フロントエンドではユーザーが期待する振る舞いが価値
価値はニーズとトレードオフに依存する
使いやすさの正体とは普段利用しているモノの形や構造の中の規則から生まれる予測容易性
振る舞いについて適合/不適合を明確に判定できる仕様もないのに「バグ」なんて存在しないはず
UIを操作するシナリオが違えばドメインも違う
コードスニペットはインターネットに溢れているのに対しコードベースはすべてユニーク
ドメインをデータのワークフローと捉えるのか、ユーザーが期待する振る舞いと捉えるか
ユースケース毎にレイヤリングしたい
SVO型のパッケージングで機能的凝集を目指すオニオンアーキテクチャ
境界づけられたコンテキストを跨いで共通化するな
テストについて
2023/04/25 フロントエンドのテスト設計とアーキテクチャ
まとめ
Worse is Betterに尽きる
不確実性や複雑性は隠蔽するのではなく向き合い方を知るべし
宣言的UIのデータアーキテクチャはコンポーネントを中心に考える
GUIでスケーラブルなアプリを書く秘訣は、良いコンポーネントを適切なタイミングで抽出することで、それ以上のことはない
経年劣化に耐える ReactComponent の書き方
大量生産・大量消費であるフロントエンドにとってレイヤードアーキテクチャがペイすることは少ない
一つの価値に対してレイヤ横断実装は少なければ少ないほど良い
影響範囲閉じてるほうが嬉しい
既存の状態管理を理解するコスト > 0から設計し直して作り直すコスト
機能は追加よりも変更したり削除するほうが難しい
設計意識が薄いということについて
SPAをどうやって作るか、の時代は終わりつつある
今やるべきインプット
ライブラリのドキュメントを読み、思想を理解する
なぜReactを使用するのか
なぜNext.jsを使用するのか
言語仕様を把握する
今やるべきアウトプット
自分が何をすることになったのか自分で理解して作る
常に自分がいなくなっても他人に説明できるものを書く
関連
なぜゲーム作りをまるごと理解できる人が増えないのか?
フロントエンドではソフトウェア式年遷宮や犠牲的アーキテクチャが通用する
レイヤを重ねて冗長化するのではなく、必要十分でミニマムな設計を目指す
テストやパフォーマンス最適化の余地を残す
レイヤ化する場合は目的を明確にする
がっちり依存制御したいならdependency injectionを公式でサポートしているAngularが向いていると思うkoushisa.icon
レイヤーがペイするであろうn年後には基盤技術が総入れ替えで1から書き直したほうが早い
歴史的には3年ごとにデータアクセスのテクニックは変更される
特にAIとの協働の動向は要チェック
開発プロセスそのものが変わろうとしている
@erukiti: 今、無駄に頑張って技術的負債の返済をするくらいならビジネスをガシガシドライブして返済を未来の技術で踏み倒す方が賢いんじゃないかなと思うわけだ
事業の思考
サンクコストを感じないレベルに、そして事業の思考をバックグラウンド実行しながら、片手で作れる力
これからも開発効率化を掲げてツールやライブラリや設計論は増えつづける
車輪の再発明もある
その本質や技術の螺旋を見抜く技術の審美眼を鍛える
プログラミング知識の中でも無形資産は潰しが効く
重要なことと重要ではないことを区別する
基本的にどのライブラリを使うとしても剥がすのは大変
薄く使えるに越したことはないが、利用するとき決めたなら中途半端に剥がしやすく使うよりも恩恵を受けられるように全振りするほうがメリットは大きい
どこが変わる可能性があるか、どうやって捨てるか、レイヤを配置することが本質的なのかは問い続ける
技術の変遷や経年劣化への対応
経年劣化に耐える ReactComponent の書き方
何かを得る時は同時にどうやって捨てるか考える
たとえば、PofEAAではActive Recordは過渡期の捨て駒で本命はData Mapperだった
UIは常に仮説検証やトレンドに左右される。いずれは捨てられる前提に考える
その代わりUIを構成するコアロジックを守る
#宣言的UIの設計レシピ
#アプリの設計にレイヤーを取り入れる前の問いかけ