設計パターンを図にしてみる
よく誤解されるのですが、自分は別に Atomic Desgin じゃないとイヤ!みたいな人では決してないです。
Presentational / Container Components も同様に、この考え方にものすごく強いこだわりがあるわけでもありません。
事実、小規模なケースにおいては Atomic Desgin を導入しないことも多いですし、Presentational / Container Components の区別をつけない開発を行うこともあります。
ただそれは趣味における開発の話であって、フロントエンド側の開発に複数人が携わるケースでかつ自身がテックリードを任された場合、両方とも取り入れることが多いです。
過去の記事でもちょくちょく書いていますが、フロントエンド開発において自分が一番重要視しているものは、プロジェクトの保守性です。
つまり、保守が容易なプロジェクトは良いプロジェクトだと思っていますし、保守が容易でないプロジェクトは悪いプロジェクトだと思っています。
この考え方に賛同してくれる方は相変わらず少ないみたいですが…。
机上の空論とまでは言いませんが、今一度自分の考え方を図に書いてみたら?と思うことは多いです。
例えば Atomic Design の超ざっくりとした図は以下のような感じですよね。
Pages
↓
Templates
↓
Organisms
↓
Molecules
↓
Atoms
実際には、例えば Organisms が Atoms を呼ぶケースなども存在するため、もう少し複雑ですが。
ここに Presentational / Container Components の考え方を導入すると以下のように判別できるようになります。
Pages(containers)
↓
Templates(components)
↓
Organisms(components)
↓
Molecules(components)
↓
Atoms(components)
つまり、Atomic Design 的には Pages が Container Components で、Templates 以下は Presentational Components に該当します。
で、Atomic Design 的にも Presentational / Container Components 的にも動的なデータ、つまり Api などにまつわる処理は Pages(つまり Container Components)で行うはずなので、さらに以下のように書けます。
Api など
↕
Pages(containers)
↓
Templates(components)
↓
Organisms(components)
↓
Molecules(components)
↓
Atoms(components)
これが Atomic Design と Presentational / Container Components の組み合わせとなります。
このコンポーネントパターンでは、以下のような強みが挙げられます。
- 保守が容易
- プロジェクトが堅牢になる、大規模なプロジェクトであっても構築できる
- UI / UX デザイナーとコンポーネントパターンの認識がズレにくい
- Storybook が組みやすく、コンポーネント単位でプロトタイプと 1 対 1 の確認が行える
逆にデメリットとしては以下のような感じです。
Pagesつまり Container Components が肥大化する- Presentational Components 間でデータのバケツリレーが発生する
- プロトタイプによるが、SPA の場合
Templatesが浮きやすい - 小規模なプロジェクトでは恩恵が得られにくい
- UI / UX デザイナーに知識力、技術力が求められる
過去コンポーネントパターンに関する様々な記事を読んできましたが、「Container Components の肥大化」と「データのバケツリレーの発生」がどうしてもイヤなエンジニアの方は少なくないように見受けられました。
で、その場合 Organisms も動的なデータを扱うようにしてなんとかしたーみたいなケースが多いみたいです。
毎度思うんですが、なんでどの記事も Organisms なんですかね?
Templates が浮きがちなので、なんとなくしっくりくるというのはわからなくもないのですが…
Api など
↕
Pages(containers)
↓
Templates(components)
↓
Organisms(containers?components?) ↔ Api など
↓
Molecules(components)
↓
Atoms(components)
ぱっと見、Api にアクセスする層が 2 つに増えただけに見えますが。
見落としがちな点として、1 Page に対して複数個の Organisms が呼ばれるケースが大半なことが挙げられます。
なので、もう少し正確に書くと以下のような感じになります。
Api など
↕
Pages(containers)
↓
Templates(components)
↓↓↓
Organisms(containers?components?) ↔ Api など
↓↓↓
Molecules(components)
↓↓↓
Atoms(components)
従って 1 Page に対して、複数のコンポーネントが Api にアクセス可能な状態が出来上がってしまいます。
で、自分としてはこの時点で『これって保守できなくない?できたとしても設計が複雑すぎない?』と思うんですが、どーなんでしょうか。
フロントエンドエンジニア側の Atomic Design の一番の恩恵は一番上の層が動的なデータを扱ってくれることだと思っていて。
どこのプロジェクトもコンポーネント設計が甘すぎます。
その甘さがプロジェクトからチームから、ひいては会社の足を引っ張っていることに繋がっていることになーんで気づけないのかなーと思うことがしばしばあります。
例えば Redux であれば、ありとあらゆるコンポーネントが connect しまくっているプロジェクトも少なくないです。
ネットワーク情報を見るとバレバレなんですが、同じ Api を何本同時に叩いてんねん、って思います。
で、それだけは避けようと Atomic Design っぽい独自の手法を取り入れているプロジェクトもこれまた少なくないですが、これまたうまくいっているとは言いづらいです。
上記の例でいうと、 Pages と Organisms で扱う Api をどう分けるのか、その分け方は容易に判断できるものなのか、それはプロトタイピングに影響しないのか、そもそもコンポーネントパターンとして破綻していないか、例外は発生しないか。
考慮しなくてはいけないことは山ほどあるわけで、それらをちゃんと考慮した上で、果たしてそれは本当に良いコンポーネント設計になっているのか。
面倒くささとシンプルさって、結構相反すると思っていて。
面倒くささを取るのか、シンプルさを取るのか、Redux とか結構究極ですよね。
で、あくまで自分の持論ですが、面倒くさくてもシンプルになるのであればシンプルさを優先したほうが、結果的に良い方向を向きやすいと思っています。
面倒くさいから自動化したりシンプルにしたりすることはめちゃめちゃ大事だと思います。
でも面倒くさいから複雑にするというのは、ちょっと本末転倒感があるケースも少なくないよなーと。
もともと日本人って足すのは得意(?)でも引くのは苦手な人種だと思っているので、そもそも足すことをもっと慎重にすべきじゃないの?とは思います。
自分の本音としては、多分どこのプロジェクトもコンポーネント設計がうまくいってないからいくら調べても情報が出ないんだろうなーと思っています。
新しい設計を試したいなら趣味でやってもらって、仕事では無難でシンプルな手法を取り入れてほしいなーと思う、今日このごろです。