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
Git: the NoSQL Database
bkeepers
PRO
427
64k
Ruby is Unlike a Banana
tanoku
97
11k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Speed Design
sergeychernyshev
25
620
YesSQL, Process and Tooling at Scale
rocio
169
14k
Site-Speed That Sticks
csswizardry
0
31
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
28
2k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Building Applications with DynamoDB
mza
90
6.1k
Faster Mobile Websites
deanohume
305
30k
Into the Great Unknown - MozCon
thekraken
32
1.5k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
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/ ◦ 「実践クリーンアーキテクチャ」 ◦ 「クリーンアーキテクチャの右下の図」 ◦ 図の解説がより詳しく、加えてコード例も含めて載っている