こんにちわ。ユニバの MJ です。
2017 年も終盤に差し掛かり、今年のフロントエンドの印象としては、特にフレームワーク的な革新はなく中身が成熟していった印象があります。
そんな中で一つまとめておきたい話が一つ。
それが Atomic Design (アトミックデザイン)
です。
はじめに
Atomic Design という言葉を最初に耳にしたのは とある勉強会で Abema の方の発表でした。
確か 2015年 の冬あたり
グラディオ「実際やってみて改めて実感したぜ、Abemaはすげぇ゛よ゛!!!」
イグニス「ああ...もうすでに完成されてたな」
グラディオ「コーディング・デザイン・自由度、3つが調和しねぇと、どれかが飛びでたってだめだ」
プロンプト「おれ、次からもっとフロントエンドを楽しめそうな気がする」
ノクティス「ああ、俺も」
と今更ながら思うわけですな。
よく語られがちなのは デザインとコーディングの親和性などですが、今回はフロントエンドのコーディング、特に React を用いたプロダクトにおいて Atomic Design がどのようにして効果を発揮していたか?をまとめたいと思います。
Atomic Design とは
ここら辺はネットの情報を見てもらうと良い。
要は atoms
, molecules
, organisms
, templates
に粒度を分けて実装しろや〜ということ。
もちろんそれぞれに区分けはあるらしんだけど、その説明は今回の話だと本筋ではないので割愛。
React と Atomic Design
ここからが重要なこと。
次の私の素晴らしいデザイン案を React で実装するときに皆さんはどう実装されるでしょうか?
普通に組むとき
普通の発想ならこう組むのではないでしょうか?
<div>
<div>
<div className={componentA}>
...
</div>
<div className={componentB}>
...
</div>
</div>
<div>
<div className={componentC}>
...
</div>
</div>
</div>
となるのが普通でしょう。コンポーネントが複雑ならばその後でこうなるでしょう。
<div>
<div>
<div>
<ComponentA />
</div>
<div>
<ComponentB />
</div>
</div>
<div>
<div>
<ComponentC />
</div>
</div>
</div>
まぁ起こりうる最終ケースがここら辺で打ち止めになるはずです。
アトミックデザインに従うと
<div className={ComponentA}>
...
</div>
<div className={ComponentB}>
...
</div>
<div className={ComponentC}>
...
</div>
を作った後で (いわゆるこれらは molecules, または atoms に属します)
<div className={OrgansAB}>
<div>
<ComponentA />
</div>
<div>
<ComponentB />
</div>
</div>
と、横並びの要素を作って
<div className={TemplateABC}>
<div>
<OrgansAB />
</div>
<div>
<ComponentC />
</div>
</div>
として最終的に
<div className={TemplateABC}>
<TemplateABC />
</div>
となるわけです。
さて、普通に組んだときに 上のような結果で作ろうという発想が最初から至れるでしょうか?
できるという人はとても素晴らしいコーダーです。ユニバに入社してください。
私のような一般ピーポーには驚きでした。
なぜだか アトミックデザインに従って書いていくと、最終的な仕上がりがとても綺麗になって、あたかも自分が頭が良いではないかと錯覚することができます(キャホー)!
トップダウンな思考とボトムアップな思考がもたらすチーム開発における着地点
ここで一つ、Redux で書かれたアプリケーションを考えてみると、サーバサイドと通信したりする部分を書く人、主にコンポーネントを書く人、という2つの立ち回りが出てくることが往々にしてあります。
お互いのコードがどこで役割やデータをパスし合うか?
それは先の例でいうと Page.jsx
で行われることが多いでしょう。
先ほど示した例で普通にコーディングした場合は トップダウン
, Atomic Design の考えに基づいたコーディングを ボトムアップ
としたときに、通信周りを書く人は当然のことながらトップダウン的な思考で書いています。
このときにコンポーネントを書く人が同じようにトップダウンの思考で考えていくとお互いの境界線が曖昧になることが多いです。
なぜなら通信周りの人がどこまで書いて、コンポーネントを書く人がどこから書いて良いかわからないからです。
このときにコンポーネントを書く人がボトムアップな思考で考えているとどうなるか。
お互いの合流点が明確になるわけです。
通信周りを書く人は単純です。
class Page extends Component {
buisinessLogic() {
}
render() {
return (
<Template ...props />
)
}
}
レンダーの中に書くべきは最小単位のテンプレートを書いてあとは渡す予定の props
を丁寧に渡してあげるだけで済みます。
Page.jsx
の中にはそのページで行うべき重要なロジックだけを書くだけで済むようにすることができます。
こんなことは普通にできるやろ
そうです。この話はチーム内で円滑かつ綿密に設計がされていれば問題のない話だと思います。
しかしですよ?そんなにうまいこと仕事の分担ができるでしょうか?いやできない(倒置法)。
アトミックデザインを導入することで、自然とお互いがどこまで責任を持たせて、どうやってやりとりを行うのか?という点が非常に明確になりました(体験談)
よくあるデメリット(課題感)
さて、とはいうもののアトミックデザインをやるには幾つか弊害があります。
- 記述量が増える
- 上の例でもそうですが、やたら Div で囲みます。
- とはいえ、CSS のスタイリングの概念から見ると、間違っていない括り方ではあるので、そこは我慢
- コンポーネントをテスト描画をできる環境がないと無理
- フロントエンドがそのコンポーネントに入るべき値やケースなどを、網羅しないといけません。
- データが
Page.jsx
に行き着く前に、単体でテストできるような仕組みを頭を捻って用意しましょう - 私はコンポーネント自身が example を持つようにして、半自動でテストをレンダリングするような仕組みを用意しました。ここら辺のノウハウは是非共有していきたいですね〜。
- ファイル増えすぎ
- 馬鹿みたいに Atom を分別したりするとすぐにファイルの山でできて整理ができなくなります。
- カテゴリごとにフォルダを分けたり、モジュールを意識してコーディングしましょう。
- 名前決めしてないと出会った瞬間「君の名は?」と発狂する
- props の名前などは事前ある程度合意をしておきましょう。映画のようなことやってると死にます。
最後に
初めはコンポーネントの整理のためにアトミックデザインを導入しました。
しかしやっていく内に、自然とチーム内で受け渡しの秩序が生まれましたとさ。
バイバイ汚いコードよ。皆さんもアトミックデザイン的な思考を試してはいかが〜。