Micro Atomic Design
こんにちは、株式会社POLでエンジニアをしているミズノです。前回はフロントエンド の取り組みについてお伝えしました。今回はその続きで、レイヤードアーキテクチャと合わせて取り組んでいるのがAtomic Designの考え方です。その部分を紹介したいと思います。
課題
我々のフロントエンド開発において、2つの大きな課題がありました。
1.影響範囲の調査コストが高い
当時コンポーネントを利用し各機能を表現していましたが、コンポーネントの利用範囲はアプリケーション全体であるため、改修が他のページで思わぬ影響をあたえることがありました。開発時に入念な影響範囲調査が行われていましたが、この工程は正直楽しいものではく、スタートアップで求められるスピード感が欠如していると感じていました。
2.コンポーネントの複雑化
コンポーネントの再利用は良い考えですが、扱いを誤るとコンポーネントの複雑化が起きます。例えば、Propsに大量のデータを渡す、その多くがオプショナルで、if文などの制御が多数入っている。こういったコンポーネントを皆さんも見たことがあるのではないでしょうか?
このような課題を解決したいと思い、POLではMicro Atomic Designという考えを導入しています。
Micro Atomic Design
「Atomic Designとは何か違うのか?」というと大きな違いはありません。違いは、適用範囲がページ単位ということです。
一般的なAtomic Designはアプリ全体で以下のようにディレクトリ構造が多いと思います。
src/
├ atoms
├ molecules
├ organisms
├ pages
└ template
Micro Atomic Designではページ毎にAtomic Designの構造を持たせます。以下の例ではMainページの内部にAtomic Designのディレクトリ構造があります。
src/
└ presentation
├ components
└ containers
├ Detail
└ Main
├ atoms
├ molecules
├ organisms
├ pages
├ hooks
└ context
各ページで利用するコンポーネントは、同一ディレクトリ内で完結します。Mainページの修正はMainディレクトリ内で常に完結しています。これに影響範囲は明確になります。ManページでDetailページのコンポーネントを利用することはNGです。
ここで疑問となるのが
「MainページとDetailページ、両方で利用するコンポーネントはどう扱うの?」
かと思います。
実は両ページに同じコンポーネントを作成しています。Micro Atomic Designに取り組む前に、どれぐらい共通のコンポーネントを使うのか調査しました。結論としては、各ページのコンポーネントは似てはいるが、実は別物であることがほとんどでした。そこでコンポーネントの重複は受け入れ、コンポーネントのシンプル性と影響範囲の最小化を優先することにしました。
過剰な共通化は複雑なコンポーネントを作り、開発速度を落とすことがあります。Micro Atomic Designでは、ページ毎のコンポーネントに要求される責務は最小になるり、見通しの良いコードが増えます。
もちろん日々改善もし、共通コンポーネントの考えも取り入れています。最新版のディレクトリは以下のようなものです。Atomsのような変更の入らない最小単位になりうるものは共通コンポーネントとして利用しています。
src/
└ presentation
├ components
│ ├ atoms
│ └ molecules
│
└ containers
├ Detail
└ Main
├ atoms
├ molecules
├ organisms
├ pages
├ hooks
└ context
実はMicro Atomic DesignのアイディアはメルカリさんのMicro ViewControllerをヒントにしています。複数人で開発する場合は、それを考慮した設計にするとスムーズに開発を進めることができます。
注意点として、これは銀の弾丸ではありません。ある種のトレードオフが発生しす。我々の課題解決としてはフィットしましたが、そうでない場合もあると思います。同じような課題に悩まれているチームの参考になれば幸いです。
皆さんの現場ではどのように取り組まれていますか? 良いアイディアをお持ちであればぜひ教えてください。POLではエンジニア採用の一環としてMeetyを利用して積極的にカジュアル面談を行っています。
私も募集を出しているので、よければ是非お話ししましょう。どんな話でも大丈夫です。お待ちしてます。
https://meety.net/matches/cRWkjvfyJxnA