atomic designでコンポーネント指向な開発を進めよう

# atomic designとは？

アトミックデザインは、ビューコンポーネントライブラリの粒度の定義で、アメリカのWebデザイナーBrad Frost氏が考案・提唱しました。
http://atomicdesign.bradfrost.com/
VueやReactでコンポーネント設計でよく使われる手法です。<img width="1026" alt="スクリーンショット 2020-07-09 0.28.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491279/a98049a6-f3c8-1dd0-7e02-7f16350da148.png">
この図はコンポーネントの粒度を表しています。
上記のように5分割してコンポーネントを構成していきます。

# Atoms

![atoms-form-elements.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491279/3bc26bb5-b63e-7b2b-b5b3-e93950af951d.png)

ラベル、インプット、ボタンなどこれ以上分解できない最小の単位のものがAtomsになります。

# Molecules
![molecule-search-form.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491279/bb528ebf-cc91-8a30-615d-09e92cf3167f.png)

Atomsを組み合わせたものがMoleculesです。
上の図だとひとつ前のAtomsの図で３つのAtomsを全て組み合わせて検索フォームのMoleculesを作成しています。

# Organisms
![organism-header.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491279/51268432-d8b5-167d-4566-177da1459ad7.png)

Moleculesを組み合わせたものがOrganismsです。図はロゴとメニューと先ほどの検索フォームを合わせたヘッダーになっています。

# Templates
![template.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491279/a492545d-f968-e878-fa1a-6a064369381c.png)

Moleculesを組み合わせて、ページの構造を作成したものがTemplatesです。ワイヤーフレームの役割で、ページ内容についてはまだこの階層では仮のものとなります。

# Pages
![page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491279/28ac2ccc-1c53-d67c-722c-4ac6b491ac6f.png)

配置されたUIの外観を決めるテンプレートの文章や画像などといった内容を持つのがPagesとなります。



一連のコンポーネントの粒度を理解した上で、instagramで表したこの図を見るのが一番理解が深まりそうです。（わかりやすい!!）
![instagram-atomic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491279/d000720f-e9e2-0781-22be-bfaa6297f100.png)

出典: https://atomicdesign.bradfrost.com/chapter-2/


# ディレクトリ構造の一例（Vue.js）
```

 components/
 ├── atoms
 │   ├── Link
 │   │   ├── NormalLink.vue
 │   │   └── BoldLink.vue
 │   ├── Button
 │   │   ├── NormalButton.vue
 │   │   └── BoldButton.js
 │   └── Table
 │       ├── HeaderCell.vue
 │       └── ContentCell.vue
 ├── molecules
 │   ├── Article
 │   │   ├── MainArticle.vue
 │   │   └── SubArticle.vue
 │   └── Table
 │       ├── TableHeader.vue
 │       └── TableContent.vue
 ├── organisms
 │   ├── Header
 │   │   ├── MainHeader.vue
 │   │   └── SubHeader.vue
 │   └── Table
 │       ├── MainTable.vue
 │       └── SubTable.vue
 └── templates
     └── Main
         ├── DashboadTemplate.vue
         └── MainTemplate.vue

```

こんな感じでatomic designの名称のファイルの配下にさらにLinkやButtonなどのディレクトリを作ってあげれば整理できて見易いかな思います。
atomsなどの直下にどんどん突っ込んでいくパターンでもありかとは思います。

# 悩むポイント
### どの粒度で分類する?
これがmoleculesなのか、organismsなのかと迷う場面は出てくるかもしれませんが基本的には上記にも書いた通り、atomsの組み合わせはmolecules、moleculesの組み合わせはorganismっていうシンプルな思考でざっくりやってくのが良いかと思います。

### organismsとorganismsを合わせたコンポーネントはどうなる？
パーツとしてのコンポーネントが３階層なので、このようなことが起きるのはどうしてもしょうがないです。
organisms内ではネストしてしまって良いルールで運用するのが１番簡単そうかなと思います。

### データの変更はどこで行うの？
基本的にデータ、ファンクションはPagesに全て持たせて、そこで変更すべきです。
理由としてはdataを持つ場所を決めず、複数箇所に持たせてしまうといちいちどこで階層でデータを操作しているのか探さなければいけなくなるのでデータの流れが複雑化しスパゲティ化します...
書くのは楽でも後のことを考えて、親から子にprops（Function含め）、もしくはemitすると良いです。

### どんなコンポーネントがあったかわからなくならない？
StoryBookの導入してカタログ化すると良さそうです。
デザイナーとの認識合わせもこれでスムーズに行えそうです。
参考: https://qiita.com/masaakikunsan/items/dad8d84807918f3a43cb

実は、SmartHRさんはStoryBookとコンポーネントのソースコード公開してたりします。（Reactですが）
https://smarthr.invisionapp.com/share/ADUDJ8BW74C#/screens/403704083

## 導入メリット

### デザインが崩れにくくなる
コンポーネントを使いまわしながらデザインをしていくようになるため、デザインが分からない人でもコンポーネントを当て込むだけで画面を構成することができるので、デザインに一貫性が生まれ、崩れにくくなります。
当たり前ですが、パーツごとのCSSの変更箇所も１箇所に集約されるため修正忘れのリスクが大きく減ります。

### コンポーネントの作成方法を共有認識化できる
指針としてアトミックデザインを導入すれば、コンポーネント作成の粒度を上記に合わせるだけなので、認識を合わせやすくなります。個人開発であればある程度好きにやればよさそうですが、大勢が好き勝手にコンポーネントを作成するとどこに保存するコンポーネントなのか不明瞭になりがちです。

### 実装量の削減
コンポーネントの再利用が簡単にできるため開発効率が上がります。最初は大量のファイルを作るので少し大変かもしれませんが、その後のコストは大きく削減できるはずです。

# 参考文献
https://qiita.com/japboy/items/9576301456b2bffb1fac
https://qiita.com/kei-tamiya/items/cd34c120a860f20622dd
https://tech.connehito.com/entry/learn-and-failure-atomic-design

**時間がある方は、この動画が死ぬ程わかりやすいのでおすすめです！！**
【プログラミング】チームリーディング　フロントエンドコンポーネントの指針 音ズレ修正Ver.
https://www.youtube.com/watch?v=oYdSLEixVFo&t=385s