https://fortee.jp/object-oriented-conference-2020/speaker/proposal/view/b06110e6-717e-4cb2-97c3-cd8d53693378 の初版スライドです
当日の発表版は https://speakerdeck.com/tooppoo/consideration-of-software-design-in-web-front-end で公開しています。
WEBフロントエンドにおけるソフトウェア設計の考察1@Philomagi2020/02/[email protected] Doでしょう #17#javado
View Slide
発表者@Philomagi● 主にフロントエンド主体のWEB系エンジニア● ScalaとTypescriptとRubyが好き○ Rubyは最近、公私共に若干疎遠● PHPは中々縁が切れない悪友○ 最近は、「然程悪いやつでもないな」と思い始めてる2
注以降、特に断りが無い場合は「フロントエンド = Webフロントエンド」の意味で使います3
注● 今の主な関心事がWebフロントエンド● 他のフロントアプリ事情に詳しくない○ iOS/Android/デスクトップとかという理由です4
目次1. 現代フロントエンドの難しさ2. フロントエンドの「ドメイン」3. フロントエンドを「設計」する4. フロントエンドアーキテクチャ考察5
主張したいこと● 現代のフロントエンドは単に「画面表示」と言えるほど単純ではない● 「ロジック」も「ドメイン」も、フロントエンドには存在する● 「画面設計」だけでなく「ソフトウェア設計」も、フロントエンドには必要6
反論したいこと❌ フロントエンドは表示して終わり❌ 表示だけなので、「ドメイン」も「ロジック」も存在しない❌ フロントエンドの「設計」と言えば「画面設計」(で終わる議論)7
1. 現代フロントエンドの難しさ8
フロントエンドといえば9
開発環境の多様化・複雑化10
開発環境の多様化・複雑化11本質的な問題ではない
開発環境の多様化・複雑化12道具選びが大変なのは事実
開発環境の多様化・複雑化13しかしフロントエンドの難しさ = 道具選びではない
フロントエンドを複雑にするもの14
ユーザー操作の複雑化● よりリッチ/インタラクティブなUI● 操作のバリエーション増加● 入力バリデーションの組み合わせ画面に対する操作が複雑になっている15
画面状態の複雑化16● 状態毎に複雑に切り替わる表示内容● 複数状態の組み合わせによる表示変化● 操作に応じて動的に切り替わる画面表示画面の表示状態が複雑になっている
現代フロントエンドの複雑さ17● 複雑なユーザー操作● 複雑な画面状態
現代フロントエンドの難しさ18● 複雑なユーザー操作● 複雑な画面状態この2点を如何に捉え管理するか
2. フロントエンドの「ドメイン」19
ここでの「ドメイン」について20すべてのソフトウェアプログラムは、それを使用するユーザの何らかの活動や関心と関係がある。ユーザがプログラムを適用するこの対象領域が、ソフトウェアのドメインである。-「エリック・エヴァンスのドメイン駆動設計」p.2
フロントエンドの「ドメイン」を探る21フロントエンドが対象とする「ユーザの何らかの活動や関心」は何か?
再掲)現代フロントエンドの複雑さ22● 複雑なユーザー操作● 複雑な画面状態この2点を如何に捉え管理するか
再掲)現代フロントエンドの複雑さ23● 複雑なユーザー操作● 複雑な画面状態この2点を如何に捉え管理するかなぜこの2点が複雑化するのか?
操作と状態が複雑化する理由24それがフロントエンドのユーザの主たる「活動や関心」だから
「ポップアップメニュー」のエピソード25いつものカット・アンド・ペーストをやったとき、(中略)ピーター・ドイッチュが立ち上がってスクリーンを指さしていた。「今やったのは、やったんじゃないかと俺が思ってることか?」「未来をつくった人々」 - Chapter15, p.323注:「ポップアップメニュー」の先駆けが初めてデモされた時のエピソード。 BitBltという技術の開発により、オーバーラッピングウィンドウが実用化されたことに依る。
フロントエンドのドメイン26ユーザーが「した」と思ったことを画面に表すこと
フロントエンドのドメイン27操作(「した」)と表示(画面に表す)
3. フロントエンドを「設計」する28
フロントエンドの何を「設計」するのか292種類の「設計」対象が存在する● 画面○ ex. Atomic Design, UIデザイン● ソフトウェア○ ex. モジュール設計, 依存設計
フロントエンド「設計」への問題提起30画面の「設計」ばかりが語られていないか?● 画面の「設計」は重要だが、それだけで完結はしない(はず)● 画面の奥にあるソフトウェアをいかに組み立てるかの議論が不足していないか?
Atomic Designと「設計」31● Atomic Design はUIパーツの設計方法論○ ソフトウェアの設計までカバーするものではない○ Atomic Design のスコープは「UIパーツをどう組み立てるか」まで○ Atomic Design で「設計」は完結しない
今回の発表が扱う「設計」32「画面設計」ではなく、「ソフトウェア設計」に焦点をあてる
どうやって設計するのか?33フロントエンドソフトウェアを、どうやって設計するか?
どうやって設計するのか?34フロントエンドソフトウェアを、どうやって設計するか?Atomic Design のような、フロントエンドソフトウェア設計の新たな方法が必要だ!
どうやって設計するのか?35フロントエンドソフトウェアを、どうやって設計するか?Atomic Design のような、フロントエンドソフトウェア設計の新たな方法が必要だ!
どうやって設計するのか?36フロントエンドソフトウェアを、どうやって設計するか?Atomic Design のような、フロントエンドソフトウェア設計の新たな方法が必要だ!(そうした方法を考えても良いけれど)有力な方法論が既に存在している
オブジェクト指向37
再掲)フロントエンドのドメイン38操作(「した」)と表示(画面に表す)
オブジェクト指向をどのように用いるか?フロントエンドのドメインである「操作」と「表示」に注目する39
オブジェクト指向をどのように用いるか?フロントエンドのドメインである「操作」と「表示」に注目する40↓「操作」と「表示」に関わる要素をオブジェクトとして抽出する
サンプル41
複雑な「操作ルール」を考える42
複雑な「操作ルール」を考える43Loading中はクリックしても反応しない
複雑な「操作ルール」を考える44
複雑な「操作ルール」を考える45Loading後はクリックするとポップアップ
複雑な「操作ルール」を考える46Loading後はクリックすると再読み込み
複雑な「操作ルール」を考える47
複雑な「操作ルール」を考える48
複雑な「操作ルール」を考える49
複雑な「操作ルール」を考える50
複雑な「操作ルール」を考える51Stateパターン
複雑な「操作ルール」を考える52Strategyパターン
複雑な「操作ルール」を考える53(有る種の)MVC
オブジェクト指向をどのように用いるか?● 基本は他のソフトウェアと変わらない○ 必要なオブジェクトを分析し○ オブジェクト間の関連を組み立てて○ オブジェクトの振る舞いを実装する● 一般に用いられる設計手法も活用する54
要するに「ちゃんと設計しよう」「ちゃんとオブジェクト考えよう」って言ってるだけじゃない?55
YES56
YES57その「ちゃんと」が大変で難しいけれど ……
再掲)フロントエンド「設計」への問題提起58画面の「設計」ばかりが語られていないか?● 画面の「設計」は重要だが、それだけで完結はしない(はず)● 画面の奥にあるソフトウェアをいかに組み立てるかの議論が不足していないか?
注意点● 関心の中心が「表示」と「操作」であること● サーバーサイドだと「UI層の話」として、あまり気にしない部分が中心● サーバーサイドの感覚のままで考えると、オブジェクトや関連を見落としやすいと思う59
60横道)フロントエンドと「ロジック」● ここで言う「ロジック」とは何か?● 「ロジック」=ビジネスルール・業務ルールとは限らない○ 「ロジック」といえばビジネスルール・業務ルールというのは、主にバックエンドというコンテクストにおける表現○ この意味での「ロジック」ならば、フロントエンドには無い(むしろ、有ってはいけない)● フロントエンドにおける「ロジック」は、表示と操作のルール○ そもそもフロントエンドとバックエンドでコンテクストが異なるのだから、「ロジック」が同じ意味であるという保証は無い○ むしろ、それぞれ関心事が違うのだから、扱う「ロジック」は異なって当然
4. フロントエンドアーキテクチャ考察61
フロントエンドアーキテクチャの候補62● フロントエンドソフトウェアの設計○ オブジェクト指向が有力そう● フロントエンドソフトウェアのアーキテクチャ○ ???
Fluxアーキテクチャ63https://www.infoq.com/jp/news/2014/05/facebook-mvc-flux/
Fluxアーキテクチャ64https://www.infoq.com/jp/news/2014/05/facebook-mvc-flux/
Fluxアーキテクチャへの見解● Fluxは強力だが、Fluxだけでアーキテクチャを完結させるのは厳しい● 単方向データフローは有用だが、データフローを動作させるモジュールの構造については何も提供しない○ 巨大な泥団子、単なる巨大グローバル変数になりがち● 何か他のアーキテクチャ論と組み合わせて使うことになると思う● フロントエンドにおけるCQRS(+ES)という見方は有力かも○ cf. Almin.js | JavaScriptアーキテクチャ○ CQRS(+ES)の知見が薄いので、今回は深堀りしない65
Fluxアーキテクチャへの見解● Fluxは強力だが、Fluxだけでアーキテクチャを完結させるのは厳しい● 単方向データフローは有用だが、データフローを動作させるモジュールの構造については何も提供しない○ 巨大な泥団子、単なる巨大グローバル変数になりがち● 何か他のアーキテクチャ論と組み合わせて使うことになると思う● フロントエンドにおけるCQRS(+ES)という見方は有力かも○ cf. Almin.js | JavaScriptアーキテクチャ○ CQRS(+ES)の知見が薄いので、今回は深堀りしない66
他のアーキテクチャ67
68Clean Architecture (Kindle位置No.3141)
フロントエンドでクリーンアーキテクチャ(CA)?69
70Clean Architecture (Kindle位置No.3141)
こんな薄い層できるの?外周でやって意味有るの?71
72フロントにおけるCAの意義クリーンアーキテクチャの四重円は単なる例。図22-1の円は、概要を示したものである。したがって、この4つ以外にも必要なものはあるだろう。この4つ以外は認めないというルールはない。ただし、依存性のルールは常に適用される。ソースコードの依存性は常に内側に向けるべきだ。Clean Architecture (Kindle 位置No.3188)
73フロントにおけるCAの意義クリーンアーキテクチャの四重円は単なる例。図22-1の円は、概要を示したものである。したがって、この4つ以外にも必要なものはあるだろう。この4つ以外は認めないというルールはない。ただし、依存性のルールは常に適用される。ソースコードの依存性は常に内側に向けるべきだ。Clean Architecture (Kindle 位置No.3188)
74フロントにおけるCAの意義重要なのは同心円ではなく依存性のルール
75フロントにおけるCAの意義重要なのは同心円ではなく依存性のルール↓この「4重の同心円」という形を守る必要は無い
それならば76
77UI層ViewControllerModelStateActionUI層の中で、さらに依存関係の階層を作る
78UI層ViewControllerModelStateActionUI層の同心円内で依存性のルールを守り
79UI層ViewControllerModelStateActionUI層とその内部の層でも依存性のルールを守る
80Clean Architecture (Kindle位置No.3141)この同心円の図も、システムのほんの一面的な表現でしかない
Clean Architecture (Kindle位置No.3141) 81
Clean Architecture (Kindle位置No.3141) 82デバイス・DB・ウェブ・UIが外周に在るのは、それらに積極的に関心を持たない立場からシステムを見ているから↓「外周のものは重視せず、中央のものを重視する」という表明に過ぎない。内外の関係は、この一通りではない。
Clean Architecture (Kindle位置No.3141) 83DBの内部にはDBから見たデバイスの内部にはデバイスから見たUIの内部にはUIから見た内側(コア)と外側(周辺)がそれぞれ有ると考えたほうが自然
84
85同心円は入れ子状の構造になる
86
87
88参考)iOSアプリのクリーンアーキテクチャ@takasekさんによる発表資料● クリーンアーキテクチャの同心円を、山に例えて説明。最終的に山は 連峰へ● WebフロントエンドとiOSアプリの違いは有るが、主張の内容としては近い?● 「単純化された創界山に引きずられず、思考停止せずに丁寧に設計していきましょう」 -p.41
89UI層ViewControllerModelStateAction
サンプルで考える90
サンプルで考える91View
サンプルで考える92ViewController/Applcaton
サンプルで考える93ViewController/ApplcatonModel
94サンプルで試した感触● フロントエンドでも、クリーンアーキテクチャによる階層の整理は有用そうだった○ 中心の関心事(状態・操作)と周辺の関心事(html/css、DIやバインディング)を分けて思考・実装できる○ サンプルはVue.jsで実装したが、React、あるいはjQueryにも(バインディングを頑張って書けば)移植できそう!?→フレームワーク非依存● 「中心の関心事と周辺の関心事を分けて思考・実装できる」ことが大きい
まとめ95
フロントエンドのドメイン96● フロントエンドのドメインは「操作」と「状態」● ユーザーが「した」と思ったことを現実にするために、この2つをいかに管理するか
フロントエンドと「設計」97● フロントエンドには「画面」と「ソフトウェア」、2つの「設計」対象が有る● どちらか一方では不十分だが、画面の「設計」に議論が偏っていないか● フロントエンドでも、やはりオブジェクト指向の方法論は有力
フロントエンドとアーキテクチャ98● Fluxは有力だが、単体ではソフトウェア全体の構造を規定できない● フロントエンドでも、クリーンアーキテクチャの方法論は有力● フロントエンドは、UI層の中で新たな同心円を形作ることになる
最後に99
「フロントエンド」を誇ろう● 「表示」と「操作」こそ重大な関心事○ サーバーとフロントは、関心事が違うだけ○ それぞれの重要度は所与ではない(システムによる)● 胸を張って 「フロントエンド」に挑もう○ 「JSON色付け係」のような卑下は要らない100
● ドメインは避けられない○ ドメインを分析し理解することは、サーバーサイドだけの仕事ではない○ ドメインの分析・理解は、フロントにおいても重要な仕事● 「設計」も避けられない○ 「表示するだけ」では最早済まない。画面の奥に潜むロジックを飼い慣らす術を身に着けよう「フロントエンド」に立ち向おう101
参考資料(敬称略)102● エリック・エヴァンスのドメイン駆動設計○ Eric Evans(著)今関 剛(監訳)和智 右桂、牧野祐子(訳)● Clean Architecture 達人に学ぶソフトウェアの構造と設計○ Robert C. Martin(著)角 征典、高木 正弘(訳)● 未来を作った人々 - ゼロックス・パロアルト研究所とコンピュータエイジの黎明○ Michael Hiltzik(著)エ・ビスコム・テック・ラボ(監訳)鴨沢眞夫(訳)● オブジェクト指向のハードコア○ https://www.zerobase.jp/salon/2019/05/25/hardcore-oo.html○ (2) 哲学○ (3) Smalltalk by @sumim○ (8) GUI by 上野学(@manabuueno)● クライアントアプリの「中心」とは何か○ by @takasek○ https://speakerdeck.com/takasek/20200121-the-center-of-the-client-number-ios-ca
参考資料(敬称略)103● 複雑なJavaScriptアプリケーションに立ち向かうためのアーキテクチャ○ by しんぺい(@shinpei0213)○ https://speakerdeck.com/shinpeim/fu-za-najavascriptapurikesiyonnili-tixiang-kautamefalseakitekutiya○ http://techblog.reraku.co.jp/entry/2017/08/08/184313● Almin.js | JavaScriptアーキテクチャ○ by azu(@azu_re)○ https://azu.github.io/slide/2016/child_process_sushi/almin-javascript-architecture.html● CQRS+ES(再)入門○ by かとじゅん(@j5ik2o)○ https://speakerdeck.com/j5ik2o/cqrs-plus-es-zai-ru-men● Facebook の決断:MVCはスケールしない。ならば Flux だ。○ https://www.infoq.com/jp/news/2014/05/facebook-mvc-flux/● Vue.js + デザインパターンによるコンポーネント実装○ by @philomagi○ https://speakerdeck.com/tooppoo/vue-dot-js-dezainpatan-niyorukonponentoshi-zhuang-v2○ https://github.com/tooppoo/sample-for-vue-with-design-patterns
ご清聴ありがとうございました104