隠れドメインのsiteを使って収まりの悪いコンポーネントを整理する

## はじめに

ドワンゴでニコニコ生放送のWebフロントエンジニアをやっています @misuken です。

今回はWebフロントのコンポーネント設計において、隠れドメインの **site** を使うことで、一般的に収まり悪いコンポーネントを簡単にスッキリ収める方法を紹介します。

この手法は対処療法ではなく、ドメインの本質にしっかりと基づいた設計に繋がるため、チームからの納得を得られやすく、長期的にも様々な安定をもたらすことを期待できます。

## 収まりの悪いコンポーネント達

あなたが運営しているサイトでこんな名前のコンポーネント名はありませんか？

- Header
- Footer
- NavigationBar
- SideMenu

これらのコンポーネントは、Atomic Designで作ってい場合 organisms にいると思われますが、きっとディレクトリツリーでは他のコンポーネントの中に埋もれてモヤモヤしたことがあるのではないでしょうか。

```
- footer
- g*****
- header 
- i*****
- ~
- m*****
- navigation-bar
- o*****
- ~
- r*****
- side-menu
```

そんな収まりの悪いコンポーネント達をどのよう捉えるとスッキリ収められるのかを説明していきます。

## 収まりの悪いコンポーネント達の特徴

収まりの悪いコンポーネント達が持つ特徴は以下のようなものが多いはずです。

- 様々なドメインの内容を包括している
- 時間とともに包括するドメインが変化することもある
- 何もドメインを含んでいないように見える場合もある
- 既存の単一のドメインに絞りきれない

各ドメインを束ねるような存在だったり、サービス内のドメインと全く無関係のような存在だったり、といったところでしょうか。

## サイトを構成する上で生まれた存在

それらに共通するのは、サイトを構成する上で必要、または利便性を向上させるために存在しているということです。

- サイトだからこそ必要になる
- それがあることでサイトの利便性が向上する
- サイト特有の関心事である
- どのサイトでも同様の存在が現れる
- ある意味サイトのドメインの型と言える(サイトという概念における型というイメージ)

それらが無かったら、サイト上に情報は公開されていてもアクセスできないかもしれませんし、著しく使い勝手の悪いサイトになっていることでしょう。

この隠れドメインである site に気付けるかどうかが収まりの悪いコンポーネント達を無くせるかどうかの鍵になっています。

## サイトマップも利便性を向上させる存在

説明するまでもないですが、サイトマップ(サイトの地図)とは、まさにサイトの利便性を向上する存在です。

site-map-page(サイトの地図のページ) や site-map-section(サイトの地図のセクション) というコンポーネントがサイトのドメインの型にあると捉えれば、 site-header や site-footer も同様にそこに存在することは明白でしょう。

また、サイトをいくつも作る場合、サイトの内容を検索するフォームを汎用的な名前にしたいならば site-content-search-form としてサイトのドメイン型に加えることもできます。これもサイトの利便性を向上させる存在です。

## siteドメインを使った分類

siteドメインを使って分類したディレクトリ構造は以下のようになります。

```
- a***
- ~
- r***
- site-content-search-form
- site-footer
- site-header
- site-map-section
- site-navigation-bar
- site-side-menu
```

明らかにスッキリしていますね。

## 本でも同じような捉え方ができます

例えば、本をコンポーネントで作るとした場合、ドメインの内容以外に本自体を構成する共通部品があるはずです。これらに book というドメインが付いていないと関心が散らばる上に index のような短い名前では非常に取り扱いの難しい状態に陥ってしまいます。

```
- back-cover 裏表紙
- cover 表紙
- d****
- ~
- h****
- index  索引
- information (書籍)情報
- j****
- ~
- v****
- wraparound-band 帯
```

bookドメインを明示して以下のように分類されれば、曖昧さがなくなり、秩序がもたらされます。

```
- book-back-cover 裏表紙
- book-cover 表紙
- book-index  索引
- book-information (書籍)情報
- book-wraparound-band 帯
- c****
- ~
- v****
```

## site以外のもの

site以外にも似たような隠れドメインは存在します。

ヘルプや利用規約のように提供するサービスに依存するもの達です。これらは service-help-* や service-tos-* などとすると、よりキレイに分類できます。

お問い合わせ(contact)のようなものは、サイトに対するお問い合わせなのか、サービスに対するお問い合わせなのかなど、少し考慮したほうが良いかもしれません。

## URLとの関係

URLでは `*.com/service-help` ではなく `*.com/help` としたいと思うので、そこはドメインを抜いた形で問題ないでしょう。

あくまでURLでの参照先はシンボリックリンクのような存在で、ルーティングで表示する対象を決めれば良いものです。

権限のある人にはHTTPのステータスコード200、権限のない人には403のページが表示されるなど、そもそもURLには実態がそのまま置かれているわけではないのですから、URLはURL、コンポーネント名はコンポーネント名と切り分けて考えたほうが管理しやすくなります。(適切な名前で管理されていれば一定の関係性はわかる範囲に落ち着きます)

## BCD Designとの関係

今回の site に気付く上では、[BCD Design](https://qiita.com/misuken/items/19f9f603ab165e228fe1)の知見があると助けになります。

BCD Designでは header や footer といった単語は Base に該当する単語であり、それらがCase Common Domainのコンポーネントを内部に持つ(依存する)ことは何かがおかしいことを意味しています。

つまり、 header が例えば user-login-anchor のようなコンポーネントを内部に持つのであれば、 userドメインを知っていて使う側の立場でなければならないことを意味するため、header側にDomainに該当する単語が足りていないことが明らかになるのです。

header というコンポーネントはどのサイトでも役割としては決まっているものの、内容に関してはそのサイトごとに決定されます。ロゴや検索フォームが配置されることは多いかもしれませんが、何を表示するのかどういった機能を提供するのか、それらは全てサイトのブランディングや目的によって決定されます。

anchor や button は具体的な Base であるのに対し、 header や footer は抽象的な Base といった立ち位置になります。

navigation や side といった単語(分類するなら Case になるが)もあまりに漠然としていて、 navigation-menu や side-menu だけでは役割はわかるものの、コンポーネントの内部構成で何も確定できるものがありません。(組み合わさるドメインによって内部構成が全然違うため)

site-* (厳格にはそのアプリケーションのサイト)と組み合わさったときに初めて内部構成が確定できるわけですから、こちらも組み合わせる前の段階ではDomainに該当する単語が足りていないことを把握できます。

このように、BCD Designの助けがあるとコンポーネントの分類はもちろん、ドメインの関係性の理解が促進されます。Atomic Designで運用していたとしても、BCD Designの考え方から受けられる恩恵は少なくないので、不足している単語を補って、気持ちの良いディレクトリツリーを手に入れてみてはいかがでしょうか。