Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
20190523_nkowne63zf_1.pdf
Search
Nkowne63
May 23, 2019
0
390
20190523_nkowne63zf_1.pdf
Nkowne63
May 23, 2019
Tweet
Share
More Decks by Nkowne63
See All by Nkowne63
TypeScriptのコード生成をつらくしないために
neutron63zf
1
630
2020-11-05-side-effects-composition__1_.pdf
neutron63zf
1
400
vueで中規模以上のフロントエンドを組んでいて 役に立ったtips
neutron63zf
5
3.1k
20200128_nkowne63
neutron63zf
0
32
Vueで「見た目」「振る舞い」を分離してみよう
neutron63zf
0
560
「つなぎこみ」を自動化する
neutron63zf
0
460
for文禁止縛り in JS
neutron63zf
0
680
Featured
See All Featured
Done Done
chrislema
181
16k
Automating Front-end Workflow
addyosmani
1366
200k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
520
The Language of Interfaces
destraynor
154
24k
What's in a price? How to price your products and services
michaelherold
243
12k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.3k
Code Review Best Practice
trishagee
65
17k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
Visualization
eitanlees
146
15k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
2
170
Transcript
clean architectureの実践 (in React with Redux)
自己紹介 張 たいよ (GitHub: @neutron63zf) 東京大学理学部物理学科 4年 • ventus-inc ◦
JavaScript ( Vue.js / Nuxt.js ) ◦ Golang / Firebase • (元)東京大学五月祭常任委員会 ◦ AWS / Nginx / Docker ◦ Node.js ( Express )
構成 • 動機 • 前提知識 • clean architectureの概要 • reactでやってみる
• まとめ
動機:「vue/reactに振り回されたくない」 • フレームワークに振り回されている気がする ◦ (例)処理を全部 storeの中に書いてしまい、読みづらいコードになってしまっている。 ◦ (例)vueの限界で、配列をいじるときは直接代入ができない • テストしたいけど、テストしづらいコードができてしまった
• ロジックの部分は大して変わってないのに変更が多くて大変 「vue/reactに振り回されて、肝心の『本質』以外で消耗している気がする」
前提知識 • React ◦ 状態を更新することによって、描画が(ほぼ)自動で更新される。 ◦ コンポーネントを組み合わせることで、ウェブサイトを作れる。 ◦ (性質だけなら) Vueも近い。
• Flux Architecture(ここではredux) ◦ (すごくざっくり言うと) Storeというものに状態をまとめ、それに対して操作をする。 ◦ 「一方向のデータフロー」を課すことで、挙動を予測しやすくする。 • TypeScript ◦ JavaScriptに型アノテーションをつけることができる。 ◦ 予測変換が強くなる。便利。 ◦ 型にまつわるエラーをある程度コンパイル時に検知できる。
clean architecture の概要 (出典:https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
全体像 普通は「DB」や「フレームワーク」が最下層に あって、それらの上にアプリケーションを構築 していくが、clean architectureは逆に、 DI(Dependency Injection; 依存オブジェクト の注入)により、「DB」や「フレームワーク」を最 外層に追いやり、どちらにも依存しないコード
を書く 赤丸で囲ったところは普通は最下層にいるが、これ を外に出すことで、影響を減らす
内層:ビジネスロジック いわゆるロジックにあたる部分。 フレームワークに依存するコードなどは基本的 には書かず、データ構造だったり、「このアプリ ケーションでは何ができるのか 」を表現する。
外層:入出力 入力をデータベースに受け渡したり、逆に画面 に出力したり、 「純粋なロジック」と「外部のフレームワーク・ データベース」の間をとりもち、媒介する層
DIって? (非常にざっくり、語弊を恐れずに言うと、) 右下のように、実行時に依存しているオブジェ クトを指定すること。 たとえば、上のコードでは、クラス B以外のrun メソッドを呼び出すにはコードを書き換えるほ かないが、下のコードでは、コンストラクタで別 のrunメソッドを持つオブジェクトを指定してや れば良い。
これにより、より柔軟なコードが書けるようにな る。
reactでやってみる リポジトリをあげておきました
todoアプリからのスタート 「TypeScriptで Redux + React チュートリア ル」のページをもとに、「追加だけできる Todo アプリ(?)」をさくっと作る。 今回はこれにclean
architectureを適用してみ る。
内層を書く 内層のEntitiesとUseCasesの「interface」だ け書いておく。実際に下の UseCaseを実装す るのはまた別のクラス。 この10行かそこらがこのアプリのできることを 要約している。 普通はstoreなどのデータ構造に忖度して、 id を入れたりするが、なくても良い。
また、getTodosが引数(しかもany)をとってし まったの理由は後で解説する。 (src/structure/entities/todo_interface.ts) (src/structure/usecases/todos_interface.ts)
storeを外層に書く src/structure/store/store_repository.tsにインターフェースを、src/store_repository_react.tsに具体的な実装 を書いている。 storeはモデルと同等の扱いを受けがちだが、コードを実際に書くと、 フレームワークの制約を非常に厳しく受け るため、内層ではなく外層に書いている。
useCaseとcontrollerの実装 まず、useCaseの方は、リポジトリにデータを引き渡し、さまざまな永続化などを行う 。今回は割愛したが、APIで バックエンドにデータを保存する場合などはここに書くことになる。 次に、controllerの方は、ユーザーの入力を整形し、 useCaseに整形された入力を引き渡す 。
(補足)factoryの追加 少し蛇足だが、作ったこれらのクラスを実際に 使うときは、まず、実際のstoreを引数にとっ て、インスタンスをどんどん作ることになる。 ただ、毎回何回もnewを書くのは面倒なので、 factory関数を作ってあげる。 具体的には、右上のコードだけでコントロー ラーが取得できるようにしておく 。 (src/TodoComponent.tsxのconstructor内)
(src/todo_controller_factory.ts) (src/structure/todo_controller_factory.ts)
(補足)getTodosが引数を取る理由 getTodosが引数を取らないと、右の 「renderTodoList」が「this.propsに依存してい ない」とreactに判断されるのか、addTodoをし ても表示が更新されない。 たいへん気持ち悪いが、しかたなくこの実装に した。 (src/TodoComponent.tsx)
まとめ:処理の流れを追ってみる 実際にconsole.logして処理を追ってみると、 右にあるように、 「component→controller→ interactor(usecase)→repository」 となり、階層をまたいでデータが流れているこ とがわかる。
まとめ:良かった点 • 責務が分割されている ◦ つまり、「どこを変えればいいのか」がわかりやすく、また、煩雑にもなりづらい。 • ストアが軽くなりそう ◦ 今回は元からある storeを使ったが、storeの中身(reducerやactionsなど)もclean
architectureのusecaseなどで 扱えそう • テストがしやすい ◦ インターフェースに依存しているだけなので、同じインターフェースさえ満たせば、テスト用のオブジェクトなどを 入れることで比較的簡単にテスト可能
まとめ:微妙だった点 • めんどくさい ◦ 見ての通り、todoアプリでは圧倒的にめんどくさい。 ◦ 大規模になれば、あるいは、大規模になる見込みがあるコードベースでは役に立つ。 • フレームワークの影響を完全に遮蔽することはない ◦
getTodosみたいなのはそれの例。 ◦ 行けなくはないのだろうが、さらに大変になりそう。
参考資料・出典 • https://programmagick.com/blog?slug=react_typescript_redux_tutorial ◦ 「TypeScriptで Redux + React チュートリアル」 ◦
react + redux + typescript のサンプルとして • https://nrslib.com/clean-architecture/ • https://nrslib.com/clean-flow-of-control/ ◦ 「実践クリーンアーキテクチャ」 ◦ 「クリーンアーキテクチャの右下の図」 ◦ 図の解説がより詳しく、加えてコード例も含めて載っている