Atomic Designを開発に取り入れてみて

こんにちは、@k_akoarumです。

この記事はイノベーター・ジャパン Advent Calendar 2019の9日目の記事です。

ここ数年、Webデザインやフロントエンド界隈では耳にすることも多いAtomic Designですが、いまいちピンと来ない、実際のところどうなの?という声をよく聞きます。

当社では、Vue.jsを使用したプロダクトでAtomic Design(正確にはAtomic Designをベースとしたもの)を取り入れているので、これまでの経験を踏まえて、あらためてAtomic Designはどうなのかについてまとめてみようと思います。 ​

Atomic Designとは

f:id:akoarum:20191206114512p:plain
出典元:https://bradfrost.com/blog/post/atomic-web-design/

まずはAtomic Designについて、知らないという方もいるかと思いますので、軽くおさらいです。

Atomic Designとは、Brad Frostさんが2013年に考案したアーキテクチャ(デザイン手法)です。
ページを以下の5つのレベルに分け、それぞれに明確な役割を付与しつつ、再利用可能なコンポーネントを作っていく手法です。

  • Atoms(原子):最小単位。これ以上細かく分割できない最も抽象的な単位
  • Molecules(分子):Atomsを組み合わせて作る。何かしらの1機能、意味を持つ
  • Organisms(有機体):Atoms、Molecules、Organismsを組み合わせて作る。より具体的で再利用性はあまりない
  • Templates(テンプレート):ワイヤーフレームと同等で、ページを構成しつつも実際のデータなどが入っていないもの
  • Pages(ページ):Templatesに実際のデータを反映させたもの

詳細についてはすでに数多くの解説がWeb上にありますので、ここでは省略します。 ​

Atomic Designを使用するメリット

Atomic Designを使用すると、以下のようなメリットがあるとされています。​

  • UIが統一されることでUXの向上につながる
  • デザインレベル、コンポーネントレベルで責務の分離ができる
  • 共通概念が生まれることで、チーム開発がしやすくなる

Atomic Designでは解決できないこと

Atomic Designは、上記でも触れている通りアーキテクチャ(デザイン手法)です。当然ですが、開発方法やコンポーネント開発の問題を解決するようなことは何も書かれていないため、これらについては自らで用意する必要があります。

実際に開発してみてわかったこと

ここからは当社のプロダクトで見えてきたことを軽く触れていきます。

問題発生時の原因特定がスムーズになった

実はAtomic Designを導入しているプロダクトはもともとAtomic Designではない形で実装されていて、一つ一つのコンポーネントの粒度がかなり大きい状態でした。
その時の一つのコンポーネントは責務をいくつも持っていて、複数の状態を入り乱れるように定義されていたため、原因特定のためにコードを紐解く時間なども必要でした。

それに対して、Atomic Designを導入した後のコンポーネントでは、原則として一つのコンポーネントにつき責務が一つになっているので、原因を探し出すのがとてもわかりやすくなりました。

UIが統一されてきた

ページによってまちまちだったUIが統一されるようになってきました。
粒度の大きいコンポーネントで開発していると、機能は同じなのに見た目が異なるということがしばしば発生します。

Atomic Designの場合は基本的に小さな単位でも全て再利用可能なコンポーネントから作られるので、UIは統一されていきます。
見た目の変更が入った場合でも、対象のコンポーネントだけを修正すれば全てに反映できるので、修正のコストも抑えられます。

ただし、どのようなコンポーネントがプロダクトに存在しているのかをメンバーが把握していなければ、新たに似たコンポーネントを作ってしまう可能性もあるため、Storybookなどを使用してリスト化して管理することが重要になります。

コンポーネントの数がかなり増える

Atomic Designでよく言われるものの一つです。細かく分けていくことになるので、やはりコンポーネント数は肥大化します。
小規模なプロダクトでも、合計50個を超えているということはよくあります。
デザインである程度個数を抑えることは可能ですが、こればかりは避けられないかと思います。

このコンポーネントはどちらに属させるか問題

コンポーネントを開発していくと度々発生するのが、「このコンポーネントはどのレベルに属するのか」で悩むということです。

例えば、「かなり具体的な意味を持つコンポーネントだけどAtomsやMoleculesなど子コンポーネントを持たない」というケース。
この場合、具体的な意味を持つのでAtomsには属せそうにありません。しかし一方で子コンポーネントを持たないためにMoleculesなどの上の階層には属せないことになるため、どうするべきか非常に迷うことになってしまいます。

  • 具体的な意味を持っていても子コンポーネントを持っていなければAtomsにする
  • 子コンポーネントを持っていなくてもMolecules / Organismsに属することができるようにする
  • 特殊コンポーネントのカテゴリを作る

のような割り切りがどうしても必要になります。

このように実際の開発では、ある程度拡張させたルールを作って運用することが必要です。

Organisms / Pages の肥大化

Atomic Designではデータ(APIやストアなど)へのアクセスはOrganismsかPagesが担うことになります。そうなると、その配下で持つデータ量が多いほど必然的にそのコンポーネントに定義する内容も肥大化します。

これはAtomic Designがあくまでデザイン手法であるからで、この課題の解決策はAtomic Designでは持ち合わせていません。
この課題を解決しようと思ったら、Atomic Componentsのような拡張されたアーキテクチャに寄せていくなどの工夫が必要になります。

デザインの段階から取り入れるには高度なテクニックが必要

デザインにおける視点の流れは、全体を俯瞰しながら細部をみる、ということが多いかと思います。その一方でAtomic Designは、細部から全体へという視点の流れがあります。
この視点の違いが、後にコンポーネントを組み合わせた結果何かバランスの悪いデザインになってしまった、ということに繋がりやすくなります。

また、そもそも「コンポーネント」という考え方自体がWebデザインの分野ではあまり普及していなかったことから、まず導入時点でつまづいてしまうデザイナーさんも多くいるようです。
なので、導入時点ではデザイナーさんには軽く意識する程度でデザインを進めてもらい、エンジニア側でうまく分割するなどするのがいいかもしれません。

現在の設計ルール

これらのことを踏まえ、現在は以下のようなルールで開発を行っています。

カテゴリ 依存カテゴリ ストア・APIアクセス 状態管理
Atoms なし NG 自己完結のみ
Molecules Atoms NG 自己完結のみ
Organisms Atoms, Molecules, Organisms NG OK
Projects Atoms, Projects NG OK
Pages Atoms, Molecules, Organisms, Projects OK OK

Atomic Designから変更した点としては、まずTemplatesはコンポーネントとして表す必要性がないと判断したため廃止しました。
また新たにProjectsという、上記で記していた特殊コンポーネントのカテゴリを追加しています。ただしこのカテゴリは曖昧な位置付けになっているため、いずれはOrganismsに統合されるかもしれません。

ストア・APIへのアクセスについては、基本的にPagesのみで行うようにしています。これは、その一切の責務をPagesが担い、OrganismsはPagesから受け取ったデータを仕分ける責務に分けたかったからです。

状態については、Atoms、Moleculesに関しては自己完結するもののみ持つことを許可しています。ここで言う「自己完結するもの」とは、例えばそのコンポーネント自体のスタイルに関する状態などです。

今のところはこのルールでうまく回っていますが、Projectsのようにまだ曖昧な部分も残っているため、もう少しブラッシュアップして明文化させていけたらなと考えています。

まとめ

  • 問題発生時の原因特定や修正のコストが抑えられるようになった
  • UIの統一が進められた
  • コンポーネントの数はどうしても増えるので、メンバーが把握できるようにリスト化するなどして管理する必要がある
  • Atomic Designだけでは解決できない課題もあるので、設計の指標として活用しつつ、うまく拡張した設計ルールを作る必要がある

最近は先述したAtomic Components以外にもAtomic Designから拡張した新しい設計ルールが登場してきているので、行き詰まったり悩んだりしたらそういったルールを見てみるのもいいかもしれません。

最後に

私個人の話をすると、2019年はひたすらVue.jsやNuxt.jsで開発していた1年でした。
7月にイノベーター・ジャパンにジョインして以来、フロントエンドエンジニアとしてもっと色々なことをしていきたいと思っていましたが、ちょっと間に合いませんでした。

2020年はいくつかのチャレンジをして、フロントエンドエンジニアとしてだけでなく様々な分野で大きく変化・成長できる年にしていけたらと考えています。チャレンジする内容は一部決めていますが、それはまたいずれ。