Atomic Design を読んでの備忘録

「[Atomic Design ~堅牢で使いやすいUIを効率良く設計する](https://amzn.to/2KrOZ6n)」を読んだので、自分なりの備忘録。

# コンポーネント指向設計

本書では「コンポーネント・ベースの UI 開発」「UI コンポーネントの設計」とある。英語では "Component Based Design" が一般的表現の模様。ここでは「コンポーネント指向設計」と表現する。

## メリット

### 開発者メリット

#### 堅牢性

- コンポーネント単位でデストできる
- 不都合のリスクポイントを減らすことができる
- メンテナンスしやすくなる
- 解決する問題を小さくできる

#### 効率化

- 再利用で実装量を減らす
- 平行開発で待ち時間を減らす
- 仕様変更による手戻り作業を最小化する
- 新規参入開発メンバーを最短で戦力化する
- 複数のテストアプローチでテスト工数を下げる
- 複数アプリケーションの開発を容易にする

### ユーザーメリット

- 多機能アプリケーションのユーザビリティを向上させる
    - ボトムアップ設計による UI の一貫性が複雑さの排除とシンプルさを実現する。
- UI とは会話である
    - 単語の組み合わせを文章として理解するように人間はパタンを認識して適応する。UI コンポーネントを単語と考えた時、その組み合わせがシンプルである程パタン認識が容易になり、シンプルな UI が実現できる。

## コンポーネントの特徴

- カプセル化されている
- 置換可能である
- 再利用可能である
- コンポーネントを別のコンポーネントと組み合わせて作成可能である

### コンポーネント設計の 2 つのポイント

- 単一責任の原則 "SRP: Single responsibility principle"
- 関心の分離 "SoC: Separation of concerns"

# Atomic Design

- Atomic Design の「デザイン」とは「設計」である
- 世界が 100 種類の原子から構成されるように、web ページも原子のような小さな物質の組み合わせで考えるのが Atomic Design

## レイヤード・アーキテクチャとしての Atomic Design

![atomic-design-diagram](https://qiita-image-store.s3.amazonaws.com/0/5051/d8d5af68-9d06-8696-bc5b-1a72dad3560c.png)

- アプリケーションを責務に応じたいくつかの層に分割して設計
- 上図は [ITCSS](https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/) と照らし合わせた図 (私見)
    - **Reach** 影響力。適用範囲の広さ。タテ軸が下に行く程、影響範囲が狭くなる。
    - **Specificity** 詳細度。実装の抽象度。下に行く程、抽象度が低くなり、具体性が増す。
    - **Explicitness** 明瞭性。コンポーネント利用シーン、ユースケースの明確さ。
    - Atomic Design も ITCSS も高レベルなレイヤード・アーキテクチャであるので、考え方は共通している。

## UI デザインの関心事を Atomic Design で階層化

デザイン視点で関心の分離を設計する。

| 順番 | 行動プロセス | デザイン対象 (関心) | 層 |
|------|--------------------------------------|--------------------------------|-----------|
| 1 | 画面全体から情報を探す | 画面全体のレイアウト | Templates |
| 2 | 興味を引くコンテンツを見つける | ユーザーの行動を促すコンテンツ | Organisms |
| 3 | コンテンツに促されて行動する | 行動を阻害しない操作性 | Molecules |
| 4 | 全体を通してサービスに良い印象を抱く | デザインの統一性 | Atoms |

### 階層化のメリット

- 全体を考慮する必要がなく 1 つの層の責務に関わる課題だけに集中できる
- 同一層に属するコンポーネントであれば差し替えることができる
- 上位層の UI コンポーネントの変更が下位層に影響することがない

# Atoms (原子) の設計

デザインの統一感を支えるのが atoms であり、4 つのカテゴリー (横の広がり) がある:

- プラットフォームのデフォルト UI
    - HTML 要素 + 独自 CSS
- プラットフォームのデファクト・スタンダードな UI
    - バルーン、バッジ、カード...
- レイアウト・パターン
    - グリッド、聖杯レイアウト、メディア・オブジェクト...
- セマンティックなデザイン要素
    - 見出し、本文、コンテンツ画像、アイコン、デコレーション枠や区切り線、アニメーション

# Molecules (分子) の設計

ユーザーの動機に対する機能を提供する。

**例) 検索フォーム**

| コンポーネント | Atom の機能 | 役割 |
|----------------------|------------------------------|----------------------------|
| テキスト・インプット | 任意のテキストを入力 | 検索したいキーワードを入力 |
| ボタン | クリック時に任意の処理を開始 | 検索を開始 |
| テキスト | 任意のテキスト情報を表示 | 何が検索できるかの説明 |

```html:検索フォーム
<molecule-search-form>
  <atom-text>サイト内検索</atom-text>
  <atom-text-input placeholder="キーワードを入力"/>
  <atom-button>検索</atom-button>
</molecule-search-form>
```

## Molecules のデザインの統一

- 以前使ったことがある、または、直感的に使い方がわかる形をしている
- 似た形をしたものは常に同じ挙動をする

# Organisms (有機体) の設計

独立して成立するコンテンツを提供する。

> この層のコンポーネントがエンジニア、デザイナー、ディレクター間で共通認識として存在していると、コミュニケーションが迅速に進みます。

## Molecules と Organisms の分け方

- **Molecules**: 独立して存在できるコンポーネントではなく、ほかのコンポーネントの機能を助けるヘルパーとしての存在意義が強いコンポーネント
- **Organisms**: 独立して存在できるスタンドアローンなコンポーネント

# Templates (テンプレート) と Pages (ページ) の設計

- **Templates**: ページ・レイアウトに対する責務を担う
    - Atoms, Molecules, Organisms 層を配置するコンポーネント
    - Pages コンポーネントのコンストラクタ
- **Pages**: コンテンツとコンポーネントをつなぐ
    - Templates コンポーネントのインスタンス
    - 本書では Flux などのグローバルメディエーターとの接続をこの層で行っている
    - Templates と Pages が分かれている事でレイアウトレベルの A/B テストなども実現しやすそう

# コンテナーとプレゼンテーショナル・コンポーネント

コンポーネントのロジックと見た目の関心を分離する。

```html:見出し
<atom-heading>
  <atom-heading-container>
    <atom-heading-presenter>
      <slot/>
    </atom-heading-presenter>
  </atom-heading-container>
</atom-heading>
```

- **コンテナー・コンポーネント**: コンポーネントのロジックを責務とする。
- **プレゼンテーショナル・コンポーネント**: コンポーネントの見た目を責務とする。

# レイアウトしやすいコンポーネント

> レイアウトしやすいコンポーネントは、「コンポーネント自身がどのようにレイアウトされるか」という情報に関心を持ちません。

- [スタイルクローズドの原則]( https://qiita.com/seya/items/8814e905693f00cdade2#%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%BA%E3%83%89%E3%81%AE%E5%8E%9F%E5%89%87)

# 統一デザイン

## デザインの要素と原則

- [Visual design elements and principles - Wikipedia](https://en.wikipedia.org/wiki/Visual_design_elements_and_principles)

### 要素

1. 色
2. 線
3. 図形
4. 質感・テクスチャ
5. 空間
6. フォーム (三次元的視覚情報のある要素)

### 印象

1. 統一
2. バランス
3. 階層
4. 尺度・比率
5. 占有・強調
6. 類似と対比

## デザイン要素の階層化

![design-layers-diagram.png](https://qiita-image-store.s3.amazonaws.com/0/5051/6eee6de9-23d1-f592-f106-a84d61d0889a.png)

※ 本書だと依存関係の矢印が逆だけど、↑ じゃないかな。

# デザイナーとの協業

- デザイナーは全体を俯瞰してトップダウンのアプローチ
- エンジニアは最小単位の処理を組み合わせるボトムアップのアプローチ
- インターフェース・インベントリをつくる