Next.jsの設計をどうやるかドラフト版1

日々仕事の中でどうするのがあるべき姿か唸っているので一旦吐き出してみる。考えてばかりだと永遠にアウトプットしない気がするし
まだまだ試行錯誤途中なので、とりあえずドラフト版としてその1とする。色々と推敲不足なところがあると思います

現状で考えている設計案

ポイントととしてはSOLID、KISS、YAGNI、そしてDRYを適切に守り、Testableなものを作ることができれば理想ではないかと考えています

状態を一箇所で持つ

  • 状態が複数のコンポーネントにまたがっていると扱いづらいため、画面コンポーネントの根っこで持つのが望ましいと考える
  • fowardRefだったりContext APIのような仕組みでアクセスすると状態の関係性が複雑化するので避けられるなら避ける
  • ただ状態がファットになってしまうという欠点もあり、ここをどう解決するかは課題

部品を細かくする

  • 単一責務の部品であればUTは容易であるため
  • 基本的にSOLID原則を守って作っていればDIによるモックもでき、テストは容易になる
  • 但し部品が多い場合、認知負荷が上がる問題があり、ここをどう解決するかは課題

fowardRefは極力使わない

  • どこまでがコンポーネントの責務なのかわからなくなるため
    • 基本的にフローは親から子へ向かうべきで、子から親に向かうべきではない
  • .focus()を使いたいといった、どうしようもないときだけはあり
    • ただこれを使う時点でUX的に微妙になっていないかを確認した方がいいと思う

型安全にする

  • anyは使わず、unknownとしてTypeGuardを使い、型をアサーションすることで、論理的にも物理的にも型安全を確保する
  • これによってコーディングミスや予期せぬ結合不具合が減らせると考えている

型で縛れるところは型で縛る

  • 例えば次のコードは型で縛れない
    • キーに何が来るかわからないため
const foo: { [key: string]: string } = {
  foo: 'bar',
};
  • throwもよくわからないので利用を避け、returnで管理するなどの検討も良いと思う(golangのように

変数はImmutableに

  • letuseRefは極力避け、constuseStateといったImmutableなものを使う
    • 再代入を阻止することで予期せぬ値の変更によるバグを防ぐ目的
    • スコープが短ければ気にしなくていいと思うが…
    • オブジェクトの変更もプロパティ書き換えより作り直しのほうが理想的
      • 現実味は薄いが、参照引き回しによるバグは防げる

共通化しすぎない

DRYよりKISSであれ

  • DRY 原則は少なくないプログラマーにとって絶対的だと考えています
    • 同じコードを書くことはナンセンスだと言う考えを持つ人は少なくないでしょう
  • 但しその時は偶々同じ処理でも、将来的に変わるかもしれません。次の考えが良い参考になると思います
  • 基本的には将来不変なものは共通化していいと思いますが、それ以外はしなくて良い気がしてます

余計なものは実装しない

YAGNIはKISSである

  • 今は使わないけど今後使うだろうというものは実装しない
    • 実装が不要に複雑になってしまう
    • 盲腸のような実装は結局使われないまま、削除のタイミングもなく放置されがち

作ってみた叩き台と課題感

Next.js-Architecture-Example

課題感としては次のような感じ

  • pages配下の作りをどうするか
    • pageにはgetStaticPropsやgetServerSidePropsしか書かないのが正解な気がする
    • 問題はtemplates配下
    • PageStateとPageUseCase, PageViewで分割しているがインターフェースと実装の依存が強すぎて微妙な気はする
    • 項目が増えれば増えるほど複雑化しファットになっていく