フロントエンドの設計のメモ


メモ程度に残しておきます。あくまでも現時点の個人的な意見なので悪しからず。

呼び方はいろいろあるので違うかも。チームのメンバーで認識合わせができていればOKだと思います。


住み分け

  • ドメイン
    • システムの登場人物の型とかここでまとめておくと楽かも。data transfer objectみたいな感じで使う。
    • domain/とかmodel/とかでいいかなと。model/だったらなんかメソッドが生えてそうだけど実際はただの型で、ロジックや状態で使われる感じ。
  • ロジック
    • ドメインを使った計算や、ビジネスロジックを書く場所。
    • 他の人がなんて言ってるかわからないけど、logic/,service/とかでいいかな。
    • ここにロジックを固めて、ブラウザの処理や、UIの情報はいれないようにする。
    • 非ブラウザ環境でも動くべき。単体テスト必須。
  • UI
    • componentsって名前のディレクトリがほとんど。Atomic Designっぽくするならここでatomsとかを展開する。
    • なるべくロジックのディレクトリ以下にビジネスロジックを入れるように努力すれば、ここではUI関連の処理しか出てこないはず。
    • これは決めだと思うけど、atomsmoleculesはドメインを知らないほうが再利用がしやすい。あくまでのUIパーツとして振舞ってほしい。
  • 状態
    • 状態置き場。UIにデータやコールバックを供給するやつ。containersとか、storeって呼ばれたりしてる。
    • 一般的なCRUDの処理はcontainerコンポーネントで通信してもいいかな?とも思う。APIのテストもしたいならロジックの部分でやってもいいけど、チーム次第かなと。reduxなら、actionでやる。
    • 他のコンポーネントと同期するために必要なこともあるけど、選択状態とかUIの状態は極力いれない。

あとは必要に応じて、どこでも使える関数だったりドメインが関係ない処理なら、libとかutilとか作る。

ECサイトとかイメージすると、ディレクトリにするとこんな感じ?

src/
  domain/
    user
    order
    product
  logic/
    user
    order
    product    
  components/
    atoms/
      button
      input
      avatar
    molecules/
      itemList
      searchInput
    organisms/
      globalMenu
      shoppingItemList
    templates/
      Home
      Login
  container/
    Home
    Login
  util/
    string
    url

ドメインの部分とロジックの部分は一緒になってもいいかもしれない。


所感

多くのWebアプリは

  • フォーム要素に入力してその内容をjsonにして送信してレコードを作成
  • サーバーにリクエストして、データ表示したり
  • 表示したものを編集して、jsonでまた送ったり
  • 削除したり

だと思うのですが、基本的にUIにロジックを持たせると再利用しにくくなったり、テストがしんどいので、
ビジネスロジックや、ドメインを扱う処理の境界線を意識して、極力UIからUI以外の部分を切り離してロジック側に処理を書いて、そっちをしっかりテスト。

UIをなるべくステートレス(関数コンポーネント)に作るように工夫すれば意識すれば、in-outが明確になり複雑性(テストパターン)は減る。
。いろいろな要望があって、状態をいれないといけない時も、hooks使えばあとから、関数コンポーネントに状態を導入するのも楽なので、開発体験は結構いい。

UI(ブラウザやDOMの処理やreactの処理)とドメインの処理がコンポーネント内でごっちゃ混ぜになっていると結構しんどくなる。

正直Reduxをちゃんと使ったことがないけど、本当に必要になってから必要なものを入れるみたいなスタンスの導入でもOKだと思う。containerでやったほうが概念理解やボイラープレートの多さによって戸惑うことが少ないと思っています。(少なくとも自分が携わったやつでは問題がなかった。)参考: You Might Not Need Redux

「おしらせ、通知」などの処理は別画面に遷移したり、他のコンポーネントから変更されたものを反映させるのが難易度高いので、有効だと思う。
あとは多言語情報とか全部のコンポーネントで共有されてて、propsのバケツリレーが辛いとかだったら、コンテクストでもいいと思う。
お知らせもコンテクストAPIで実装できるならそれでもOKだと思う。


再確認

  • 登場人物は整理しておくと、ロジックや状態で使える。
  • UIはUIに徹した方がいい。
    • UIは変更される可能性が高いので、ドメインを加工する処理がちらばってると邪魔だし、反映漏れとかありそう。
    • ドメインをいじるような処理をUIで書くと開発効率悪い。
  • ロジックは切り出す
    • UI情報と隔離するのがポイントで切り出して関数テストをしっかり。
    • ここの関数とかは積極的に組み合わせて書いていくと短くできる。
    • 結局関数のまとまりなので、副作用無しで参照透過性の高いものが好まれる。
    • 再利用性も高まるし、UIの変更にも強くなる。
  • 状態はなるべくコンパクトに(無駄なUIの情報は持たせない)
    • 公開範囲も最小限にしておいた方がいい。選択状態はUIが持つべき。無駄に親に持たせないようにする。子だけで完結する状態は子に持たせるべき。
    • storeで持つ情報は本当にそこじゃないとダメなのか考える。