前書き
2023年アドベントカレンダー、3回目の投稿になります。
明日の投稿の枠、まだ決まっていませんでしたので「私が書きます」と立候補してみたのですが、、、
本当にネタがない状態だったので、過去の失敗を掘り返してみました。
ですので、本当に読まないでほしいです。
もし読むなら、必ず「いいね」をしてくださいね〜
概要
最近、Atomic Designは「古い」や「使えない」という評判を目にしますが、数年前まではスタンダードなUI設計手法だったと思います。最近のスタンダードは何でしょう、コメントで教えてください。
タイトルに失敗と書いてあるので、「Atomic Designの思想と運用が合わなくなった」や「Atomic Designの原則に沿ったコンポーネントの切り出し方とシステムの構造が合わなくなった」という崇高な失敗ではなく、Atomic Designの原則を見よう見まねで、とりあえずUI設計した結果、大変な目にあった個人的な愚かな失敗の話です。
ベテランはもちろん、新人のエンジニアもこの失敗はしないと思います。
Atomic Designとは
Atomic DesignとはUIの設計手法で、原子に相当する小さなコンポーネントを組み合わせて、1つのページを作り上げる考え方です。
下記リンク先の公式ページによると、コンポーネントは5つの階層に分けられると書いてあります。
https://atomicdesign.bradfrost.com/chapter-2/
- Atoms
- Molecules
- Organisms
- Templates
- Pages
詳細な説明は、他のエンジニアが書いた記事を読んでほしいので省きます。
ただ基本的に下記のようなコンポーネントの構成かと思います。
- Atoms
- 最小単位のラベルやボタン、インプットフィールド、テキストなど
- Molecules
- Atomsの組み合わせ、インプットとボタンとラベルでインプットフォームを作成
- Organisms
- Moleculesを組み合わせ、ヘッダーやサイドバー、コンテンツを作成
Templatesで枠組み構成して、Pagesでページを構成しますが、プロジェクトによってはTemplatesがなく、直接Pagesでページを構成したりと色んな方法があるかと思います。
ただ、Atomic Designの原則は大事です。
ここから本題
それでは、失敗です。
下のようなボタン付きテーブル、Atomic Designの設計に照らし合わせるとどんな感じで構築しますか?
See the Pen Untitled by takahiro fukushima (@takahiro-fukushima) on CodePen.
多分、いろんな考え方があるので、開発のしやすや拡張性、保守性を確保できていたら、全部正解です。
それでは失敗したパターンですが、AtomsにButtonとTableコンポーネント作成して、Moleculesで組み合わせてボタン付きテーブルを構成してしまったことです。
ディレクトリ構成でいうと下記の通りです。
components/
├── atoms
│ ├── Button
│ │ └── Button.jsx
│ └── Table
│ └── Table.jsx
├── molecules
│ └── Table
│ └── Table.jsx
次に「テーブルにもう一つ、この機能のボタンをつけてほしい」と依頼があった際、下記のようなディレクトリ構造で作ってしまったわけです。
components/
├── atoms
│ ├── Button
│ │ └── Button.jsx
│ └── Table
│ └── Table.jsx
├── molecules
│ └── Table
│ ├── Table.jsx
│ └── ⚪︎⚪︎Table.jsx
本来ですと、この時点で嫌な雰囲気を感じとってリファクタリングするべきでしたが、それを怠ってしまい、「また別の機能のボタンをテーブルに追加するページができたんだけど、よろしく」との依頼を受けますと。
そうすると、
components/
├── atoms
│ ├── Button
│ │ └── Button.jsx
│ └── Table
│ └── Table.jsx
├── molecules
│ └── Table
│ ├── Table.jsx
│ ├── ⚪︎⚪︎Table.jsx
│ └── ⚪︎⚪︎⚪︎⚪︎Table.jsx
という感じで、テーブルに関係する依頼がある度にTableが増えていくわけです。
まだリファクタリングするタイミングがあるかと思いきや、いつの間にか下のディレクトリ構造のように、色々なTableが色々なOrganismsに散らばって、開発を進めながらリファクタリングできないように、、、
components/
├── atoms
│ ├── Button
│ │ └── Button.jsx
│ └── Table
│ └── Table.jsx
├── molecules
│ └── Table
│ ├── Table.jsx
│ ├── ⚪︎⚪︎Table.jsx
│ ├── ⚪︎⚪︎⚪︎⚪︎Table.jsx
│ ├── ⚪︎⚪︎⚪︎⚪︎⚪︎⚪︎Table.jsx
│
├── Organisms
│ └── ContentTable
│ ├── ContentTable1.jsx <- Table.jsxを使って
│ ├── ContentTable2.jsx <- ⚪︎⚪︎⚪︎⚪︎⚪︎⚪︎Table.jsxを使って
│ ├── ContentTable3.jsx <- Table.jsxを使って
│ ├── ContentTable4.jsx <- ⚪︎⚪︎⚪︎⚪︎Table.jsxを使って
│ ├── ContentTable5.jsx <- ⚪︎⚪︎⚪︎⚪︎⚪︎⚪︎Table.jsxを使って
│ ├── ContentTable6.jsx <- ⚪︎⚪︎Table.jsxを使って
要望が増えるとコンポーネントが無駄に増え、Atomic Designの恩恵を全然受けていない状態になり、暗い気持ちでコーディングしていました。
Atomic Designの恩恵を受けない設計をした時点で失敗です。
どうしたら良かったか
moleculesでTableとButtonを組み合わせず、OrganismsでTableとButtonを組み合わせていけば、moleculesでTableコンポーネントが増えず、まだスッキリとした構造で開発できたのではないかと考えています。
ただ他にもプロジェクトの内容に合わせた良いコンポーネントの組み合わせがあると思いますので、メンバーと話し合ってベストな構成を決めていくのが良いのかなと思います。
とりあえず、この後のプロジェクトでは本記事のような失敗はしなくなったので、ちょっとは成長しました。
最後に
「こんな失敗はしないだろう」という失敗ですですし、「こんな失敗するなんてバカだなぁ」と思って反面教師にして下さい。
思い出しながらこの記事を書いたので詳細は忘れ気味でしたが、ツールや開発手法はとにかく思想を理解して、それに沿って恩恵を受け、良い開発者体験を得られるようにしていきましょう。
ご指摘がありましたらコメントにてお願いします〜
批判は泣いてしまうので、お控えを。
あと「いいね」もお願いします