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
610
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
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
1.9k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
How To Stay Up To Date on Web Technology
chriscoyier
788
250k
Making Projects Easy
brettharned
115
5.9k
4 Signs Your Business is Dying
shpigford
180
21k
VelocityConf: Rendering Performance Case Studies
addyosmani
325
24k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.8k
Building Applications with DynamoDB
mza
90
6.1k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
250
21k
Fireside Chat
paigeccino
34
3k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
Optimising Largest Contentful Paint
csswizardry
33
2.9k
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/ ◦ 「実践クリーンアーキテクチャ」 ◦ 「クリーンアーキテクチャの右下の図」 ◦ 図の解説がより詳しく、加えてコード例も含めて載っている